• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Strange problem

Status
Not open for further replies.
Level 19
Joined
Feb 25, 2009
Messages
2,004
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.
Thanks in advance.

Test map can be found here.
 
Last edited:
Level 7
Joined
Apr 1, 2010
Messages
289
  • 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.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
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])
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
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 :D)
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)

You'll have to add
  • 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 :/
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
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.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
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).
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
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]
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
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.
 
Level 19
Joined
Feb 25, 2009
Messages
2,004
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


New map link
 
Status
Not open for further replies.
Top