# Strange problem

Status
Not open for further replies.

#### MortAr

Level 19
I got a pretty weird problem with a spell I was making few days ago.
Here the trigger(s) I use for it:

• Bouncer Main
• Events
• Unit - A unit Starts the effect of an ability
• Conditions
• (Ability being cast) Equal to Bouncer
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• MUI2 Equal to 0
• Then - Actions
• Trigger - Turn on Bouncer Loop <gen>
• Else - Actions
• Set MUI1 = (MUI1 + 1)
• Set MUI2 = (MUI2 + 1)
• Set B_Caster[MUI2] = (Triggering unit)
• Set B_Target[MUI2] = (Target unit of ability being cast)
• Set B_cPoint = (Position of (Triggering unit))
• Set B_tPoint[MUI2] = (Position of B_Target[MUI2])
• Set B_Level[MUI2] = (Level of Bouncer for (Triggering unit))
• Unit - Create 1 Projectile Dummy for (Owner of (Triggering unit)) at B_cPoint facing B_tPoint[MUI2]
• Set B_Dummy[MUI2] = (Last created unit)
• Animation - Change B_Dummy[MUI2] flying height to 75.00 at 0.00
• Special Effect - Create a special effect attached to the origin of B_Dummy[MUI2] using Abilities\Weapons\IllidanMissile\IllidanMissile.mdl
• Set B_MissleModel[MUI2] = (Last created special effect)
• Set B_MaxBounces[MUI2] = (2 + (3 x B_Level[MUI2]))
• Set B_Damage[MUI2] = (10.00 x (Real(B_Level[MUI2])))
• Set B_Increment = (2.00 x (Real(B_Level[MUI2])))
• Set B_Angle[MUI2] = (Angle from B_cPoint to B_tPoint[MUI2])
• Custom script: call RemoveLocation (udg_B_cPoint)
• Bouncer Loop
• Events
• Time - Every 0.03 seconds of game time
• Conditions
• Actions
• For each (Integer MUI3) from 1 to MUI2, do (Actions)
• Loop - Actions
• Set B_dPoint[MUI3] = (Position of B_Dummy[MUI3])
• Set B_tPoint[MUI3] = (Position of B_Target[MUI3])
• Set B_Angle[MUI3] = (Angle from B_dPoint[MUI3] to B_tPoint[MUI3])
• Set B_mPoint[MUI3] = (B_dPoint[MUI3] offset by 25.00 towards B_Angle[MUI3] degrees)
• Unit - Move B_Dummy[MUI3] instantly to B_mPoint[MUI3]
• Set B_Distance[MUI3] = (Distance between B_dPoint[MUI3] and B_tPoint[MUI3])
• Custom script: call RemoveLocation (udg_B_mPoint[udg_MUI3])
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• B_Distance[MUI3] Less than or equal to 100.00
• Then - Actions
• Set B_NumBounces[MUI3] = (B_NumBounces[MUI3] + 1)
• Unit - Cause B_Caster[MUI3] to damage B_Target[MUI3], dealing (B_Damage[MUI3] + (B_Increment x (Real(B_NumBounces[MUI3])))) damage of attack type Spells and damage type Unknown
• Special Effect - Create a special effect at B_tPoint[MUI3] using Abilities\Spells\Undead\Possession\PossessionMissile.mdl
• Special Effect - Destroy (Last created special effect)
• Set B_LastTarget[MUI3] = B_Target[MUI3]
• Set B_HitGroup[MUI3] = (Units within 325.00 of B_dPoint[MUI3] matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of B_Dummy[MUI3])) Equal to True) and ((Matching unit) Not
• Custom script: set udg_B_Target[udg_MUI3] = FirstOfGroup(udg_B_HitGroup[udg_MUI3])
• Unit Group - Remove all units from B_HitGroup[MUI3]
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Or - Any (Conditions) are true
• Conditions
• (B_Target[MUI3] is dead) Equal to True
• B_Target[MUI3] Equal to No unit
• B_NumBounces[MUI3] Greater than or equal to B_MaxBounces[MUI3]
• Then - Actions
• Set B_Caster[MUI3] = No unit
• Unit - Remove B_Dummy[MUI3] from the game
• Set B_Dummy[MUI3] = No unit
• Set B_LastTarget[MUI3] = No unit
• Set B_NumBounces[MUI3] = 0
• Custom script: call RemoveLocation (udg_B_tPoint[udg_MUI3])
• Custom script: call RemoveLocation (udg_B_dPoint[udg_MUI3])
• Custom script: call DestroyGroup (udg_B_HitGroup[udg_MUI3])
• Set MUI1 = (MUI1 - 1)
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• MUI1 Equal to 0
• Then - Actions
• Set MUI2 = 0
• Trigger - Turn off (This trigger)
• Else - Actions
As you may have noticed, the spell shoots a missle which bounces through enemies within the main target. The problem in the spell is that when I spam it and the MAIN target dies the missles get struck into the air and never destroyed.
This sometimes also happens when it is cast several the times BEFORE the first cast missle reaches its target.

Any suggestions to fix the problem are accepted.

Test map can be found here.

Last edited:

#### Narogog

Level 7
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Or - Any (Conditions) are true
• Conditions
• B_Target[MUI3] Equal to No unit
I think the problem might be that you don't have a check to see if the target unit is alive, you have one for if it is no unit but when a unit is dead it still is a unit.
gonna test map and see.

#### MortAr

Level 19
EDIT: The bug still remains, so it's not this, apparently.

#### PurplePoot

Level 40
I can't reproduce it, so I can't test for sure, but I'm pretty sure the cause is the empty indices that you leave when you clean up without reducing the overall size of the array (don't do this, it's a waste of performance even if it doesn't cause problems).

You also leak a point when you use Point with Polar Offset, and I'm pretty sure this (in the first trigger) is a typo:

Set B_Angle[MUI3] = (Angle from B_cPoint to B_tPoint[MUI2])

#### ap0calypse

Level 28
You forgot to decrease MUI2 in the loop (after the loop, actually).

I tested it with a test-value (time of day, always a useful value when testing )
Here's a small snippet of what your code is thinking:

2 instances are running, both have the same main target:
This means that MUI2 is 2 (and the code loops from 1 to MUI2)

LOOPING (from 1 to 2)
Missile 1 kills main, aqcuires new target

Missile 2's target is dead -> remove (MUI1 = 1)

LOOPING (from 1 to 2)
Missile 1 moves towards the next target

Missile 2's target is dead -> remove (MUI1 = 0 --> spell will stop)

• Set MUI2 = MUI1
right behind the loop.

• Actions
• For each (Integer MUI3) from 1 to MUI2, do (Actions)
• Loop - Actions
• Set B_dPoint[MUI3] = (Position of B_Dummy[MUI3])
• Set B_tPoint[MUI3] = (Position of B_Target[MUI3])
• Set B_Angle[MUI3] = (Angle from B_dPoint[MUI3] to B_tPoint[MUI3])
• Unit - Move B_Dummy[MUI3] instantly to (B_dPoint[MUI3] offset by 15.00 towards B_Angle[MUI3] degrees)
• Set B_Distance[MUI3] = (Distance between B_dPoint[MUI3] and B_tPoint[MUI3])
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• B_Distance[MUI3] Less than or equal to 64.00
• Then - Actions
• Set B_NumBounces[MUI3] = (B_NumBounces[MUI3] + 1)
• Unit - Cause B_Caster[MUI3] to damage B_Target[MUI3], dealing (B_Damage[MUI3] + (B_Increment x (Real(B_NumBounces[MUI3])))) damage of attack type Spells and damage type Unknown
• Special Effect - Create a special effect at B_tPoint[MUI3] using Abilities\Spells\Undead\Possession\PossessionMissile.mdl
• Special Effect - Destroy (Last created special effect)
• Set B_LastTarget[MUI3] = B_Target[MUI3]
• Set B_HitGroup[MUI3] = (Units within 325.00 of B_dPoint[MUI3] matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of B_Dummy[MUI3])) Equal to True) and ((Matching unit) Not
• Custom script: set udg_B_Target[udg_MUI3] = FirstOfGroup(udg_B_HitGroup[udg_MUI3])
• Unit Group - Remove all units from B_HitGroup[MUI3]
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Or - Any (Conditions) are true
• Conditions
• (B_Target[MUI3] is dead) Equal to True
• B_Target[MUI3] Equal to No unit
• B_NumBounces[MUI3] Greater than or equal to B_MaxBounces[MUI3]
• Then - Actions
• Set B_Caster[MUI3] = No unit
• Unit - Remove B_Dummy[MUI3] from the game
• Set B_Dummy[MUI3] = No unit
• Set B_LastTarget[MUI3] = No unit
• Set B_NumBounces[MUI3] = 0
• Custom script: call RemoveLocation (udg_B_tPoint[udg_MUI3])
• Custom script: call RemoveLocation (udg_B_dPoint[udg_MUI3])
• Custom script: call DestroyGroup (udg_B_HitGroup[udg_MUI3])
• Set MUI1 = (MUI1 - 1)
• Else - Actions
• Set MUI2 = MUI1
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• MUI1 Equal to 0
• Then - Actions
• Trigger - Turn off (This trigger)
• Else - Actions
I couldn't replicate the bug after adding that little line.
(NOTE: decreasing MUI2 inside the loop is not a good idea, as it is the "exitwhen" check).

I had also found Poot's typo (MUI3 should be MUI2), but he beat me to it :/

#### PurplePoot

Level 40
ap0calypse, he can't decrease MUI2--he doesn't resort the array when a missile dies (bad idea and should be fixed, but still) so if he decreased it he'd sometimes lose active indices.

#### MortAr

Level 19
Strange thing is the problem still remains even with that line.
Also, I decrease the MUI2 variable OUTSIDE all loops.

PS: Those who are not familiar with the bug, you can see it here.

#### PurplePoot

Level 40
Okay I found it, and sorting the array when a missile is destroyed will fix it. Basically, since you don't remove unused indices until they're all gone, the last condition (to clean up the unused index) fires every iteration, and thus quickly brings MUI1 down to 0. You can fix this either with some sort of boolean in the array or (more sanely) by sorting the array during cleanup.

#### ap0calypse

Level 28
ap0calypse, he can't decrease MUI2--he doesn't resort the array when a missile dies (bad idea and should be fixed, but still) so if he decreased it he'd sometimes lose active indices.
Yes, but then he'd have to redo the entire indexing system so it is dynamic.
He could either do that, or loop through some indices to sort them.
Although the looping is the easier option, redoing the indexing system is probably the best one...

Mortar said:
Also, I decrease the MUI2 variable OUTSIDE all loops.
Decreased as in MUI2 = MUI2 - 1?
Or MUI2 - MUI1? (I tried the latter one, as just decreasing it by 1 can still bug).

#### PurplePoot

Level 40
You can deflate it by moving the last index to the slot of the one that just emptied and then reducing the count by one whenever a missile needs to be cleaned up, which is easy and efficient.

#### mckill2009

Level 29
When I use indexing, I first create a boolean=false at the initilization then after the spell finishes it's goal, add an if/then/else then check if the boolean is false, then set it to true, then do 'Set MUI1 = (MUI1 - 1)', this way you can avoid using 'Set B_Caster[MUI3] = No unit' and many OR's...

One more thing, I think you really dont need to use arrays in this...
Set B_dPoint[MUI3]
Set B_tPoint[MUI3]

#### ap0calypse

Level 28
You can deflate it by moving the last index to the slot of the one that just emptied and then reducing the count by one whenever a missile needs to be cleaned up, which is easy and efficient.
Oh, right, stupid me... you don't need to maintain the correct order (1, 2, 3, 4, 5 -- 3 ends: 1, 2, 4, 5).
I wasn't thinking enough I guess.

#### Dr Super Good

Spell Reviewer
Level 63
Well I do not normally do GUI spells but since you asked nicely in chat...

Heres the fixed version (I hope). It also should not leak as much (can not garuntee it due to the GUI obscuring the behaviour of the code).

#### Attachments

• Bouncer v1.1.w3x
20.6 KB · Views: 86

#### MortAr

Level 19
Hmm, very nicely done.
But, ever since I don't want to just CnP your trigger(s) and add it to the spell
I tried to re-create them in my own version, the problem here now is the spell totally
malfunction after the first hit, and I dunno why.

• Bouncer Main
• Events
• Unit - A unit Starts the effect of an ability
• Conditions
• (Ability being cast) Equal to Bouncer
• Actions
• Set B_Caster[MUI2] = (Triggering unit)
• Set B_Target[MUI2] = (Target unit of ability being cast)
• Set B_cPoint = (Position of (Triggering unit))
• Set B_tPoint[MUI2] = (Position of B_Target[MUI2])
• Set B_Level[MUI2] = (Level of Bouncer for (Triggering unit))
• Unit - Create 1 Projectile Dummy for (Owner of (Triggering unit)) at B_cPoint facing B_tPoint[MUI2]
• Set B_Dummy[MUI2] = (Last created unit)
• Animation - Change B_Dummy[MUI2] flying height to 75.00 at 0.00
• Special Effect - Create a special effect attached to the origin of B_Dummy[MUI2] using Abilities\Weapons\IllidanMissile\IllidanMissile.mdl
• Set B_MissleModel[MUI2] = (Last created special effect)
• Set B_MaxBounces[MUI2] = (2 + (3 x B_Level[MUI2]))
• Set B_Damage[MUI2] = (10.00 x (Real(B_Level[MUI2])))
• Set B_Increment[MUI2] = (2.00 x (Real(B_Level[MUI2])))
• Set B_Angle[MUI2] = (Angle from B_cPoint to B_tPoint[MUI2])
• Custom script: call RemoveLocation (udg_B_cPoint)
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• MUI2 Equal to 0
• Then - Actions
• Trigger - Turn on Bouncer Loop <gen>
• Else - Actions
• Set MUI2 = (MUI2 + 1)
• Bouncer Loop
• Events
• Time - Every 0.03 seconds of game time
• Conditions
• Actions
• For each (Integer MUI3) from 0 to (MUI2 - 1), do (Actions)
• Loop - Actions
• Set B_dPoint[MUI3] = (Position of B_Dummy[MUI3])
• Set B_tPoint[MUI3] = (Position of B_Target[MUI3])
• Set B_Angle[MUI3] = (Angle from B_dPoint[MUI3] to B_tPoint[MUI3])
• Set B_mPoint[MUI3] = (B_dPoint[MUI3] offset by 25.00 towards B_Angle[MUI3] degrees)
• Unit - Move B_Dummy[MUI3] instantly to B_mPoint[MUI3]
• Set B_Distance[MUI3] = (Distance between B_dPoint[MUI3] and B_tPoint[MUI3])
• Custom script: call RemoveLocation (udg_B_tPoint[udg_MUI3])
• Custom script: call RemoveLocation (udg_B_dPoint[udg_MUI3])
• Custom script: call RemoveLocation (udg_B_mPoint[udg_MUI3])
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• B_Distance[MUI3] Less than or equal to 100.00
• Then - Actions
• Set B_NumBounces[MUI3] = (B_NumBounces[MUI3] + 1)
• Unit - Cause B_Caster[MUI3] to damage B_Target[MUI3], dealing (B_Damage[MUI3] + (B_Increment[MUI3] x (Real(B_NumBounces[MUI3])))) damage of attack type Spells and damage type Unknown
• Special Effect - Create a special effect at B_tPoint[MUI3] using Abilities\Spells\Undead\Possession\PossessionMissile.mdl
• Special Effect - Destroy (Last created special effect)
• Set B_LastTarget[MUI3] = B_Target[MUI3]
• Custom script: call DestroyGroup (udg_B_HitGroup[udg_MUI3])
• Set B_HitGroup[MUI3] = (Units within 325.00 of B_dPoint[MUI3] matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of B_Dummy[MUI3])) Equal to True) and ((Matching unit) Not
• Custom script: set udg_B_Target[udg_MUI3] = FirstOfGroup(udg_B_HitGroup[udg_MUI3])
• Unit Group - Remove all units from B_HitGroup[MUI3]
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Or - Any (Conditions) are true
• Conditions
• B_Target[MUI3] Equal to No unit
• B_NumBounces[MUI3] Greater than or equal to B_MaxBounces[MUI3]
• Then - Actions
• Set MUI2 = (MUI2 - 1)
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• MUI2 Equal to 0
• Then - Actions
• Trigger - Turn off (This trigger)
• Else - Actions
• Set B_Caster[MUI3] = B_Caster[MUI2]
• Set B_Dummy[MUI3] = B_Dummy[MUI2]
• Unit - Remove B_Dummy[MUI3] from the game
• Special Effect - Destroy B_MissleModel[MUI3]
• Set B_MissleModel[MUI3] = B_MissleModel[MUI2]
• Set B_NumBounces[MUI3] = B_NumBounces[MUI2]
• Set B_Damage[MUI3] = B_Damage[MUI2]
• Set B_Increment[MUI3] = B_Increment[MUI2]
• Set MUI3 = (MUI3 - 1)
• Else - Actions

#### Dr Super Good

Spell Reviewer
Level 63
Why not just use my version? I debuged all the problems and fixed most possible leaks (yours still does leak).

I suspect the problem has to do with you not flushing number of bounces. My version kept count of the number of bounces in 1 vartiable only while yours uses 2.

#### MortAr

Level 19
All bugs fixed, thanks to DSG and his endless efforts.

Status
Not open for further replies.

Replies
2
Views
493
[Trigger] Making this MUI
Replies
3
Views
715
Replies
12
Views
898
Replies
1
Views
489
Replies
4
Views
706