• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

[Solved] MUI Indexed Spell - Text not being deleted

Status
Not open for further replies.
Level 14
Joined
Aug 31, 2009
Messages
775
Hello all.

I made a spell for my map and it goes something like this:

Disintegrator Beam - (Target a unit)
Charges up over 5 seconds, and unleashes a giant beam of energy dealing 2500 damage split among all affected units over 2 seconds and applies Supperation ( a debuff which prevents healing ) for 10 seconds.

Now everything about the spell works perfectly fine except one detail...

I display a Floating Text above the caster (the caster is a building anyway, so it doesn't need to move) and it displays the countdown timer of the charge. Once it fires, it changes the text to "FIRE!" and then tries to fade out / delete the text.

The problem I have is that the very first time to spell is cast, the text is NOT deleted. Every cast after that works perfectly fine.

The code is below:
  • Disintegration Beam Cast
    • Events
      • (This is handled by an event trigger system, no problems here)
    • Conditions
      • (This is handled by an event trigger system, no problems here)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DB_Count Equal to 0
        • Then - Actions
          • Trigger - Turn on Disintegration Beam Loop <gen>
        • Else - Actions
      • Set DB_Count = (DB_Count + 1)
      • Set DB_Point[DB_Count] = (Position of (Target unit of ability being cast))
      • Set DB_Caster[DB_Count] = (Triggering unit)
      • Floating Text - Create floating text that reads <Empty String> above DB_Caster[DB_Count] with Z offset 0.00, using font size 12.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Set DB_Text[DB_Count] = (Last created floating text)
      • Set DB_Timer[DB_Count] = 140
  • Disintegration Beam Loop
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Index) from 1 to DB_Count, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (DB_Caster[Index] is alive) Equal to False
              • DB_Timer[Index] Greater than or equal to 100
            • Then - Actions
              • Floating Text - Change text of DB_Text[Index] to |cffffcc00Failed!|r using font size 12.00
              • Set DB_Timer[Index] = 0
            • Else - Actions
              • Set DB_Timer[Index] = (DB_Timer[Index] - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DB_Timer[Index] Greater than 40
                • Then - Actions
                  • Floating Text - Change text of DB_Text[Index] to (|cffffcc00 + (String(((DB_Timer[Index] - 40) / 20)))) using font size 12.00
                  • Special Effect - Create a special effect attached to the origin of DB_Caster[Index] using Abilities\Spells\Other\Doom\DoomDeath.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DB_Timer[Index] Equal to 40
                • Then - Actions
                  • Floating Text - Change text of DB_Text[Index] to |cffffcc00FIRE!|r using font size 12.00
                  • Set point = (Position of DB_Caster[Index])
                  • Set point2 = (point offset by 100.00 towards (Angle from point to DB_Point[Index]) degrees)
                  • Unit - Create 1 Sideways Dummy for Neutral Passive at point2 facing (Angle from point to DB_Point[Index]) degrees
                  • Custom script: call RemoveLocation(udg_point)
                  • Custom script: call RemoveLocation(udg_point2)
                  • Animation - Change (Last created unit)'s size to (200.00%, 200.00%, 300.00%) of its original size
                  • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 20.00%, 20.00%) with 0.00% transparency
                  • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
                  • Unit - Add Crow Form to (Last created unit)
                  • Unit - Remove Crow Form from (Last created unit)
                  • Animation - Change (Last created unit) flying height to 150.00 at 0.00
                  • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Human\ReviveHuman\ReviveHuman.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Human\ReviveHuman\ReviveHuman.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Human\ReviveHuman\ReviveHuman.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DB_Timer[Index] Less than or equal to 40
                  • DB_Timer[Index] Not equal to 0
                • Then - Actions
                  • Set point = (Position of DB_Caster[Index])
                  • Set group = (Units of type Footman)
                  • For each (Integer A) from 1 to 15, do (Actions)
                    • Loop - Actions
                      • Set point2 = (point offset by (150.00 + ((Real((Integer A))) x 75.00)) towards (Angle from point to DB_Point[Index]) degrees)
                      • Set group2 = (Units within 275.00 of point2)
                      • Unit Group - Pick every unit in group2 and do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ((Picked unit) belongs to an enemy of (Owner of DB_Caster[Index])) Equal to True
                              • ((Picked unit) is alive) Equal to True
                              • (Level of Invulnerable (Neutral) for (Picked unit)) Equal to 0
                              • ((Picked unit) is in group) Equal to False
                              • (Level of Spell Immunity for (Picked unit)) Equal to 0
                            • Then - Actions
                              • Unit Group - Add (Picked unit) to group
                            • Else - Actions
                      • Custom script: call DestroyGroup(udg_group2)
                      • Custom script: call RemoveLocation(udg_point2)
                  • Custom script: call RemoveLocation(udg_point)
                  • Unit Group - Pick every unit in group and do (Actions)
                    • Loop - Actions
                      • Unit - Cause DB_Caster[Index] to damage (Picked unit), dealing ((2500.00 / (Real((Number of units in group)))) / 40.00) damage of attack type Spells and damage type Fire
                      • Set bool = False
                      • For each (Integer A) from 1 to Supperation_Count, do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • Supperation_Target[Index] Equal to (Picked unit)
                            • Then - Actions
                              • Set bool = True
                            • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • bool Equal to False
                        • Then - Actions
                          • Set point2 = (Position of (Picked unit))
                          • Set DR_Loc = point2
                          • Set DR_Owner = Neutral Passive
                          • Trigger - Run Get Dummy <gen> (ignoring conditions)
                          • Unit - Add Supperation (Dummy, 10) to DR_Dummy
                          • Unit - Order DR_Dummy to Undead Necromancer - Cripple (Picked unit)
                          • Set DR_RecycleIn = 2
                          • Trigger - Run Recycle Dummy <gen> (ignoring conditions)
                          • Custom script: call RemoveLocation(udg_point2)
                        • Else - Actions
                  • Custom script: call DestroyGroup(udg_group)
                • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DB_Timer[Index] Less than or equal to 0
            • Then - Actions
              • Floating Text - Change DB_Text[Index]: Disable permanence
              • Floating Text - Set the velocity of DB_Text[Index] to 64.00 towards 90.00 degrees
              • Floating Text - Change the age of DB_Text[Index] to 0.00 seconds
              • Floating Text - Change the fading age of DB_Text[Index] to 2.00 seconds
              • Floating Text - Change the lifespan of DB_Text[Index] to 4.00 seconds
              • Custom script: call RemoveLocation(udg_DB_Point[udg_Index])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DB_Count Greater than 1
                • Then - Actions
                  • Set DB_Caster[Index] = DB_Caster[DB_Count]
                  • Set DB_Point[Index] = DB_Point[DB_Count]
                  • Set DB_Text[Index] = DB_Text[DB_Count]
                  • Set DB_Timer[Index] = DB_Timer[DB_Count]
                  • Set Index = (Index - 1)
                • Else - Actions
                  • Trigger - Turn off (This trigger)
              • Set DB_Count = (DB_Count - 1)
            • Else - Actions
So to restate - the spell works perfectly fine, except the FIRST cast of the spell will not delete the floating text. The floating text deletion is shown at the end of the trigger where the indexes are recycled.
This must be some kind of indexing issue, but I can't see what's wrong...
 
To find wrong logics one can remove as much logic as possible, but that the required logics still executes, so the floating text code.
One also can print message on screen to see which part of which instance runs, for example onDeindex, it could print "onDeindex[x]" where "x" is the current index.

When I tinker much around with finindes an error, I usually make a copy of the trigger I modify, or just a backup copy of the whole map during the process.

What should happen if time[x] is less than 100 but the unit is dead?
 
Level 14
Joined
Aug 31, 2009
Messages
775
So I finally found the cause of the bug.

Incredibly, it's caused by something I never thought could happen.

Notice the section that says this:

  • empty.gif
    empty.gif
    empty.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    join.gif
    unit.gif
    Unit - Add Supperation (Dummy, 10) to DR_Dummy
  • empty.gif
    empty.gif
    empty.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    join.gif
    unit.gif
    Unit - Order DR_Dummy to Undead Necromancer - Cripple (Picked unit)
  • empty.gif
    empty.gif
    empty.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    join.gif
    set.gif
    Set DR_RecycleIn = 2
  • empty.gif
    empty.gif
    empty.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    line.gif
    empty.gif
    empty.gif
    line.gif
    join.gif
    page.gif
    Trigger - Run Recycle Dummy <gen> (ignoring conditions)

The spell being cast here has its own trigger (event - a unit starts the effect of an ability...), and is also an indexed system using the "index" variable.

What's incredible is that the dummy casts the ability, runs the associated trigger (and causes the value of "Index" to change) BEFORE the trigger even gets to the next line of code.

This isn't so weird, because we're used to Nesting a trigger inside another trigger, but there should be a miniscule buffer between the events here, but somehow the unit is casting the spell so quickly it acts like the entire function is nested. This DOES NOT HAPPEN with any other spell (eg. Frost Nova, Firebolt to name a few). It seems Cripple somehow casts so fast it nests itself.

Crazy...
 
Status
Not open for further replies.
Top