[Trigger] Damaging section of my trigger only goes off once

Level 3
Joined
Jul 23, 2019
Messages
12
Hi, I need some help identifying the problem in my trigger. As the title says, it only runs the damage portion of my trigger on the first cast, but is broken on subsequent casts. Any help identifying the problem would be greatly appreciated!

  • Al Huma
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Al Huma+
    • Actions
      • Set VariableSet Al_Huma_Index = (Al_Huma_Index + 1)
      • Set VariableSet Al_Huma_Caster[Al_Huma_Index] = (Triggering unit)
      • Set VariableSet Al_Huma_Target[Al_Huma_Index] = (Target unit of ability being cast)
      • Set VariableSet Al_Huma_Count[Al_Huma_Index] = 0.00
      • Set VariableSet Al_Huma_Dummy_Angle = 180.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Al_Huma_Index Equal to 1
        • Then - Actions
          • Unit - Pause Al_Huma_Caster[Al_Huma_Index]
          • Trigger - Turn on AlHumaLoop <gen>
        • Else - Actions
  • AlHumaLoop
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Al_Huma_Loop_Integer) from 1 to Al_Huma_Index, do (Actions)
        • Loop - Actions
          • Animation - Play Al_Huma_Caster[Al_Huma_Loop_Integer]'s channel animation
          • Unit - Create 1 AlHumaDummy for (Owner of Al_Huma_Caster[Al_Huma_Loop_Integer]) at ((Position of Al_Huma_Caster[Al_Huma_Loop_Integer]) offset by 300.00 towards Al_Huma_Dummy_Angle degrees.) facing (Position of Al_Huma_Target[Al_Huma_Loop_Integer])
          • Set VariableSet Al_Huma_Dummy[Al_Huma_Loop_Integer] = (Last created unit)
          • Unit - Add a 2.50 second Generic expiration timer to Al_Huma_Dummy[Al_Huma_Loop_Integer]
          • Game - Display to (All players) for 1.00 seconds the text: grouped
          • Unit Group - Add Al_Huma_Dummy[Al_Huma_Loop_Integer] to Al_Huma_Dummy_Group
          • Unit - Add Al Huma Dummy Spell to Al_Huma_Dummy[Al_Huma_Loop_Integer]
          • Animation - Change Al_Huma_Dummy[Al_Huma_Loop_Integer] flying height to 250.00 at 999999.00
          • Set VariableSet Al_Huma_Dummy_Angle = (Al_Huma_Dummy_Angle + 45.00)
          • Set VariableSet Al_Huma_Count[Al_Huma_Loop_Integer] = (Al_Huma_Count[Al_Huma_Loop_Integer] + 0.25)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Al_Huma_Count[Al_Huma_Loop_Integer] Greater than or equal to 2.00
            • Then - Actions
              • Unit Group - Pick every unit in Al_Huma_Dummy_Group and do (Actions)
                • Loop - Actions
                  • Unit - Order (Picked unit) to Undead Dreadlord - Carrion Swarm (Position of Al_Huma_Target[Al_Huma_Loop_Integer])
                  • Game - Display to (All players) for 1.00 seconds the text: dmg
              • Unit - Unpause Al_Huma_Caster[Al_Huma_Loop_Integer]
              • Game - Display to (All players) for 5.00 seconds the text: Clean up
              • Set VariableSet Al_Huma_Caster[Al_Huma_Loop_Integer] = Al_Huma_Caster[Al_Huma_Index]
              • Set VariableSet Al_Huma_Count[Al_Huma_Loop_Integer] = Al_Huma_Count[Al_Huma_Index]
              • Set VariableSet Al_Huma_Target[Al_Huma_Loop_Integer] = Al_Huma_Target[Al_Huma_Index]
              • Set VariableSet Al_Huma_Index = (Al_Huma_Index - 1)
              • Set VariableSet Al_Huma_Loop_Integer = (Al_Huma_Loop_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Al_Huma_Index Equal to 0
                • Then - Actions
                  • Game - Display to (All players) for 5.00 seconds the text: Huma Off
                  • Custom script: call DestroyGroup(udg_Al_Huma_Dummy_Group)
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Small notes:
  • When changing flying height you can use 0 as the rate argument for an instant change, rather than using 999999.
  • You should always be pausing Al_Huma_Caster[Al_Huma_Index] on cast, not just when the loop trigger needs to be turned on. Whenever any unit casts this spell it should be paused until the spell completes, so this should not only occur in special cases.
  • Al_Huma_Dummy_Angle should be indexed to the cast instance along with all the other variables. As it stands, multiple simultaneous casts of Al Huma will all refer to the same dummy angle variable rather than having their own dummy angle variable that increases for them only. I think technically this works fine without it being indexed (all instances spawn a dummy at the same angle at the same time, rather than each cast spawning dummies always starting in a particular location), but IMO there's no reason to use a global angle because it could just confuse you or someone else later on down the line.
  • You are leaking a variety of locations used in both triggers, since you don't save them to variables and clean them up with a RemoveLocation. Here is a handy reference that links to a longer tutorial: Things That Leak
So what is actually the issue? At the end of the first successful cast, you destroy the group holding the dummies. The next time a cast instance finishes, it attempts to pick all units in that group and do something... but the group has been destroyed. It doesn't exist, so there are no units to be picked and ordered to cast their carrion swarms.

You could create a new group and assign the variable to it immediately after destroying the first one, but that's... kind of pointless. The immediate easy solution for something like this is to ask yourself if the group needs to be destroyed at all or if you could just clear it instead. The way you have the trigger right now, it would be fixed if instead of destroying the group you simply removed all units from the group. Then new units can be added on the next cast, those units can be picked, and they will cast their spells as desired.

But that is not the full correct solution. Why: simultaneous casts should not all share a unit group (I'm assuming you want a MUI spell here because most of what you've written sets that up correctly by indexing (most of) the relevant cast data). Consider what will happen in this scenario:
  • Unit A casts Al Duma in the middle of the map, adding its dummies to the group.
  • After 1.50 seconds unit B casts Al Duma in the bottom left corner of the map, adding its dummies the group also.
  • When Instance A ends 0.50s later, it will order all dummies in the group to cast carrion swarm at Unit A's position--this includes the dummies from Instance B that have been created, so in addition to all A dummies casting towards the center of the map, any dummies that yet exist for Instance B will also cast toward the middle of the map (not toward Unit B, mind you). They should not do that.
To solve this Al_Huma_Dummy_Group needs to be indexed to the cast just like everything else. Now, normally you don't have to do anything special with your variables when you set them up as arrays but groups are different than most because the group variable has to be initialized before units can be successfully added to it. By default, only the 1st (and 0th? honestly I dont know if GUI does that) index of each array is initialized with the value of <Empty Unit Group> by the variable editor. You should not really change this, because pre-allocating a bunch of indices is its own form of memory leak if those indices are never used.

Instead you will leave the array size in the variable editor at 1 and instead create and destroy the groups dynamically for each instance. You will also want to move the group destroy out of the if-block since it should happen each time not only if all cast instances have finished.
  • -------- in cast trigger --------
  • Set Al_Huma_Dummy_Angle = 180.00
  • Set Al_Huma_Dummy_Group[Al_Huma_Index] = (Empty unit group) //this will technically leak the very first group permanently (only once) but I'm not gonna worry about that; if you want to solve that yourself you are welcome to ask how
  • -------- in periodic trigger when ending the instance --------
  • Set Al_Huma_Loop_Integer = (Al_Huma_Loop_Integer - 1)
  • Custom script: call DestroyGroup(udg_Al_Huma_Dummy_Group[udg_Al_Huma_Index])
 
Level 3
Joined
Jul 23, 2019
Messages
12
Small notes:
  • When changing flying height you can use 0 as the rate argument for an instant change, rather than using 999999.
  • You should always be pausing Al_Huma_Caster[Al_Huma_Index] on cast, not just when the loop trigger needs to be turned on. Whenever any unit casts this spell it should be paused until the spell completes, so this should not only occur in special cases.
  • Al_Huma_Dummy_Angle should be indexed to the cast instance along with all the other variables. As it stands, multiple simultaneous casts of Al Huma will all refer to the same dummy angle variable rather than having their own dummy angle variable that increases for them only. I think technically this works fine without it being indexed (all instances spawn a dummy at the same angle at the same time, rather than each cast spawning dummies always starting in a particular location), but IMO there's no reason to use a global angle because it could just confuse you or someone else later on down the line.
  • You are leaking a variety of locations used in both triggers, since you don't save them to variables and clean them up with a RemoveLocation. Here is a handy reference that links to a longer tutorial: Things That Leak
So what is actually the issue? At the end of the first successful cast, you destroy the group holding the dummies. The next time a cast instance finishes, it attempts to pick all units in that group and do something... but the group has been destroyed. It doesn't exist, so there are no units to be picked and ordered to cast their carrion swarms.

You could create a new group and assign the variable to it immediately after destroying the first one, but that's... kind of pointless. The immediate easy solution for something like this is to ask yourself if the group needs to be destroyed at all or if you could just clear it instead. The way you have the trigger right now, it would be fixed if instead of destroying the group you simply removed all units from the group. Then new units can be added on the next cast, those units can be picked, and they will cast their spells as desired.

But that is not the full correct solution. Why: simultaneous casts should not all share a unit group (I'm assuming you want a MUI spell here because most of what you've written sets that up correctly by indexing (most of) the relevant cast data). Consider what will happen in this scenario:
  • Unit A casts Al Duma in the middle of the map, adding its dummies to the group.
  • After 1.50 seconds unit B casts Al Duma in the bottom left corner of the map, adding its dummies the group also.
  • When Instance A ends 0.50s later, it will order all dummies in the group to cast carrion swarm at Unit A's position--this includes the dummies from Instance B that have been created, so in addition to all A dummies casting towards the center of the map, any dummies that yet exist for Instance B will also cast toward the middle of the map (not toward Unit B, mind you). They should not do that.
To solve this Al_Huma_Dummy_Group needs to be indexed to the cast just like everything else. Now, normally you don't have to do anything special with your variables when you set them up as arrays but groups are different than most because the group variable has to be initialized before units can be successfully added to it. By default, only the 1st (and 0th? honestly I dont know if GUI does that) index of each array is initialized with the value of <Empty Unit Group> by the variable editor. You should not really change this, because pre-allocating a bunch of indices is its own form of memory leak if those indices are never used.

Instead you will leave the array size in the variable editor at 1 and instead create and destroy the groups dynamically for each instance. You will also want to move the group destroy out of the if-block since it should happen each time not only if all cast instances have finished.
  • -------- in cast trigger --------
  • Set Al_Huma_Dummy_Angle = 180.00
  • Set Al_Huma_Dummy_Group[Al_Huma_Index] = (Empty unit group) //this will technically leak the very first group permanently (only once) but I'm not gonna worry about that; if you want to solve that yourself you are welcome to ask how
  • -------- in periodic trigger when ending the instance --------
  • Set Al_Huma_Loop_Integer = (Al_Huma_Loop_Integer - 1)
  • Custom script: call DestroyGroup(udg_Al_Huma_Dummy_Group[udg_Al_Huma_Index])
Thanks for the quick and concise help as always Pyrogasm! I appreciate it.

I kind of figured it was because of the unit grouping since the trigger runs fine UP until that point, but I just couldn't for the life of me figure out why.

Initially, I had the unit group as an array, however the custom script call DestroyGroup kept getting errors when I tried to test the map in game and I wasn't sure why so I left it as is.

  • When changing flying height you can use 0 as the rate argument for an instant change, rather than using 999999.
  • You should always be pausing Al_Huma_Caster[Al_Huma_Index] on cast, not just when the loop trigger needs to be turned on. Whenever any unit casts this spell it should be paused until the spell completes, so this should not only occur in special cases.
  • You are leaking a variety of locations used in both triggers, since you don't save them to variables and clean them up with a RemoveLocation. Here is a handy reference that links to a longer tutorial: Things That Leak

Thank you for the tips!! As a beginner these mean a lot to me.

  • Al_Huma_Dummy_Angle should be indexed to the cast instance along with all the other variables. As it stands, multiple simultaneous casts of Al Huma will all refer to the same dummy angle variable rather than having their own dummy angle variable that increases for them only. I think technically this works fine without it being indexed (all instances spawn a dummy at the same angle at the same time, rather than each cast spawning dummies always starting in a particular location), but IMO there's no reason to use a global angle because it could just confuse you or someone else later on down the line.
Would you happen to know any resourceful guides on points with polar offsets? Initially I wanted it to spawn depending on the triggering units facing direction but I have no idea how so I just left it as a static spawn.

To solve this Al_Huma_Dummy_Group needs to be indexed to the cast just like everything else. Now, normally you don't have to do anything special with your variables when you set them up as arrays but groups are different than most because the group variable has to be initialized before units can be successfully added to it. By default, only the 1st (and 0th? honestly I dont know if GUI does that) index of each array is initialized with the value of <Empty Unit Group> by the variable editor. You should not really change this, because pre-allocating a bunch of indices is its own form of memory leak if those indices are never used.

Instead you will leave the array size in the variable editor at 1 and instead create and destroy the groups dynamically for each instance. You will also want to move the group destroy out of the if-block since it should happen each time not only if all cast instances have finished.
I'll try out the solution, and as for the leak I'll try to figure it out. I don't want to bother you more than I already have, thanks for taking the time type out these lengthy explanations and solutions, I appreciate it!
 
Level 3
Joined
Jul 23, 2019
Messages
12
Got it to work! Thanks again Pyrogasm.

I added 3 new Variables, Dummy_Group, Caster_Loc, and Target_Loc. I cleaned them up at the end of the trigger. (Hopefully those were the leaks you were talking about)

I looked up a custom script for creating unit groups because I wasn't sure how to

set.gif
Set Al_Huma_Dummy_Group[Al_Huma_Index] = (Empty unit group)

and instead opted for this:

  • Custom script: set udg_Al_Huma_Dummy_Group[udg_Al_Huma_Index] = CreateGroup()
Hopefully the group works as intended?

I also figured out why I couldn't destroy groups via custom script, it was because I didn't define the array which was such a stupid mistake.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
I kind of figured it was because of the unit grouping since the trigger runs fine UP until that point, but I just couldn't for the life of me figure out why.
Since it's only after the first cast I know it's going to be because of something that was destroyed or changed or removed or not returned to default or... after the first instance ended. But for the sake of example, if I didn't shortcut that way my process for figuring this out would have been something like:
  • What's not happening? The carrion swarms aren't casting.

  • Is that because the dummies don't have the ability, aren't being given the order, don't exist, are too far away to cast where they're being ordered to, or something else? I would then check the code to see if it looks to me like these things are all done correctly (I might not check in-depth).

  • Since everything appears to be set up and ordered correctly, there must be a reason the order isn't going through. The points can't be too far away because polar offset explicitly defines the distance and it works once, so that's out (I explained PP more below). Nothing would move the dummies prematurely, but I might test that in another map if I did have moving systems that I suspected could interact with dummies.

  • The simplest answer to all of this is that the order just isn't given to the dummy... but why? I could try to count the number of units in the group or something, but instead of that I'd just put a debug message right before and right after the order line. This tells me if the order line actually 'happens' (and if the first printed but second did not then I'd know it caused a thread crash or some other trigger interruption). Game - Display text to Player (auto-timed) is the GUI function.

  • Because the messages show on the first cast but never on any subsequent casts, the units must not be in the group the second time around (since otherwise I'd see at least the first message). But the actions to put them in the group are the same... so the group must be different! Then you could try printing the number of units in the group or checking that the dummy is in the group right after it's added or any number of other things to investigate. Then it's about sniffing out where and why the group was destroyed prematurely.
I looked up a custom script for creating unit groups because I wasn't sure how to
Huh, I thought that you could do what I wrote in GUI but apparently no. Maybe the modern editor removed it. You can use this workaround if you don't want to have to type it out like you did (helps in case you change variable names or with long complicated array index math):
  • Set Gr = (Units of type No unit-type) //No unit-type is a preset at the top of the unit type window
Would you happen to know any resourceful guides on points with polar offsets?
There's not much to know other than to understand what it is doing. Given point (Ax,Ay) it creates a new point (Bx,By) such that B is some defined distance (r) away from A in a defined angle (theta). You don't have to know or use any of the coordinates, you just say "that starting point, but go 139.2 units away from it in the direction of 12 degrees". It is a new point that must be cleaned up just like any other point you create.

The angle used for projection is not relative; it uses the fixed wc3 coordinate plane: +x direction is East, -x is West, +y North, -y South, all angles are measured starting from due East (along +x). Since angles are periodic (30 degrees = 390 degrees = 3630 degrees), you can literally just read the unit's facing and save that as the 'first' angle, then add (360/<total number of dummies>) to it each timer tick to get the next correct angle (just don't re-read the caster's facing in case something changed it).
as for the leak I'll try to figure it out.
If you would like to use this as an exercise to test your mettle, I've hidden the solution below. Here are some hints:
  • This group exists because the array size being 1 means Al_Huma_Dummy_Group[1] is assigned the value of "empty unit group" on map init.
  • You can't stop this value from being assigned except by crashing the init thread (bad, lol).
  • You can't change the value to anything else in the variable editor, nor can you reduce the array size to 0.
  • That leaves you with only two options: <verb> or <verb> the group in index 1
  • One option will require you to alter your cast trigger and introduces an additional if/then/else check on every cast.
  • One option will require you to create a new trigger or add to an existing one other than the 2 you've shown here.
Use or destroy.

You could decide that the first cast of this spell will simply use that group via some special logic to check if the group already exists before overwriting it with a new empty group. That alters the cast trigger and is an I/T/E check that every cast but the first will fail.

You could also just destroy the group on map init before anything has had a chance to cast the spell yet.

I don't want to bother you more than I already have, thanks for taking the time type out these lengthy explanations and solutions, I appreciate it!
I wouldn't write so much if I didn't like linguistically jacking myself off with verbose explanations that I hope help people learn, lol. I can at least make fun of myself for that. You appreciating and absorbing what I've written is a nice bonus. :) This forum exists to ask questions of knowledgeable people, there's no reason to be afraid doing so is a faux pas.
I also figured out why I couldn't destroy groups via custom script, it was because I didn't define the array which was such a stupid mistake.
Today I became very distressed about losing my friend's loaned hair tie in the span of 10 seconds in a mostly empty bathroom. I was going on stage to perform and needed it, so I looked for at least 5 minutes in every pocket of my suit multiple times. I loudly complained to him that I couldn't find it. Right before we went on stage I realized it had been on my wrist the entire time. We all do dumb shit, but better that you know what happened now!
(Hopefully those were the leaks you were talking about)
There are also the points associated with where the dummies are created (as I said above polar projection makes new points you have to account for). If you post your updated triggers I'll confirm you've gotten them all. I also didn't mention above but it's possible to only need 1 dummy unit to cast multiple spells essentially simultaneously without needing to turn to the cast point, as long as those spells aren't channeled. Uncle explained the proper setup here. Since I don't know if the dummies you create are visual or not, I wasn't sure if this was relevant.
 
Last edited:
Level 3
Joined
Jul 23, 2019
Messages
12
There's not much to know other than to understand what it is doing. Given point (Ax,Ay) it creates a new point (Bx,By) such that B is some defined distance (r) away from A in a defined angle (theta). You don't have to know or use any of the coordinates, you just say "that starting point, but go 139.2 units away from it in the direction of 12 degrees". It is a new point that must be cleaned up just like any other point you create. The angle used for projection is not relative; it uses the fixed wc3 coordinate plane: +x direction is East, -x is West, +y North, -y South, all angles are measured starting from due East (along +x). Since angles are periodic, you can literally just read the unit's facing and save that as the 'first' angle, then add (360/<total number of dummies>) to it each timer tick to get the next point (just don't re-read the caster's facing in case something changed it).
I'll give this a good read tomorrow, I was about to hit the hay before I saw your reply, everything looks foreign to me rn lol.

If you would like to use this as an exercise to test your mettle, I've hidden the solution below. Here are some hints:
  • This group exists because the array size being 1 means Al_Huma_Dummy_Group[1] is assigned the value of "empty unit group" on map init.
  • You can't stop this value from being assigned except by crashing the init thread (bad, lol).
  • You can't change the value to anything else in the variable editor, nor can you reduce the array size to 0.
  • That leaves you with only two options: <verb> or <verb> the group in index 1
  • One option will require you to alter your cast trigger and introduces an additional if/then/else check on every cast.
  • One option will require you to create a new trigger or add to an existing one other than the 2 you've shown here.
I don't think I would have ever guessed the answers, so on map init it creates the variable/empty unit group? (therefore the first initial leak) Best case would just to be destroy it so it goes to.. 0..? Or a "new" 1? I'm not sure haha, creating complicated triggers on the world editor made me realize how jank it is and it forces you to kind of think outside the box and how common logic might not work here.

My next goal is to some how make the dummies "move" (Hence why I asked about point with polar offset guides) into/towards the target to deal damage instead of simply casting a spell, I'm not sure how to go about doing that yet. All I know is every 0.03 something something etc.

Damaging via trigger before the spell hits the target doesn't make sense.. I searched up some projectile/missile systems but it's all gibberish to me, all I see are variables and I get incredibly overwhelmed. I tried looking for when the damage gets applied but I usually give up before that.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Best case would just to be destroy it so it goes to.. 0..? Or a "new" 1?
  • Yeehaw
    • Events
      • Map Initialization
    • Conditions
    • Actions
      • Custom script: call DestroyGroup(Al_Huma_Dummy_Group[1])
Yeah, that's all. The internal map init thread gives all variables their initial value slightly before that event fires, so this cleans up that leak. In any case leaking that single group doesn't really matter, which is why I left it out.

Your understanding is correct, you just don't know the words. When a handle (a category of types that unit group is part of along with unit, player, timer, and a whole bunch else) doesn't have a value assigned it's called null in JASS or nil in Lua (editor can be set to use either language). Primitive types (integer, real, boolean, string) have default values for uninitialized array indices that are different. They are in order: 0, 0., false, <the empty string>. Such variables don't need to be dealt with in the same way.

You want to destroy the data that currently occupies that the [1] slot in the unit group array, using the DestroyGroup command. That way, later when you create a new group and put it in index [1] you don't overwrite the old data, which would leave it permanently allocated but unable to be referenced to be destroyed any more. That's what a memory leak is. Instead the empty, null, variable is assigned to the new group.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
My next goal is to some how make the dummies "move" (Hence why I asked about point with polar offset guides) into/towards the target to deal damage instead of simply casting a spell, I'm not sure how to go about doing that yet. All I know is every 0.03 something something etc.
To move dummies you will usually use a periodic trigger running at a high frequency like 0.02, 0.03, 0.03125 (which is 32 fps but GUI won't let you directly input past 2 decimal places in timer period fields), or 0.2 which are generally common periods for different applications. There are reasons you might use something else too. This generally involves reading the location of the unit (or referencing a variable that saved the last position it was moved to), determining the direction it should move by reading its facing angle or some variable that stores the direction or by computing the angle towards some other target point, and then moving the unit by (SPEED x TIMER_PERIOD) in that direction.

If you wanted to make all the dummies slowly approach the center every tick you could do something like this:
  • Unit Group - Pick every unit in DummyGroup[Index] and do (Actions)
    • Loop - Actions
      • Set DP = (Position of (Picked Unit))
      • Set Ang = (Angle between DP and CenterPoint[Index]) //or you could use Facing Angle of Picked Unit if it's appropriate
      • Set DP_New = (DP offset by (SPEED x TIMER_PERIOD) towards Ang degrees)
      • Unit - Move (Picked Unit) instantly to DP_New
      • Custom script: call RemoveLocation(udg_DP)
      • Custom script: call RemoveLocation(udg_DP_New)
This depends on their being a way to know what the center point is for a given dummy. GUI usually manages dummies by storing them in a group and then looping over the group, since populating some parallel arrays to hold dummy position/angle/target/distance moved/speed/etc. is generally more annoying to work with. But there might be instances where each dummy needs to move independently in some way so you would need to attach the relevant data to the dummy so that it can be read and used when needed. Such attachment usually relies on a Hashtable to store the data (using the unit as a key) or a Unit Indexer to make working with parallel arrays easier. A hashtable is essentially just a non-typed array (different indices can hold a unit or a player or integer or whatever, not all the same) that has two different indices instead of just one... and the indices don't have to 'be' integers, they can be strings or all sorts of other stuff that can be converted into integers easily. A version that used such a hashtable might look like this:
  • Unit Group - Pick every unit in DummyGroup[Index] and do (Actions)
    • Loop - Actions
      • Set DP = (Position of (Picked Unit))
      • Set Ang = (Load Key("facing angle") of Key((Picked Unit)) from SPELL_HASHTABLE)
      • Set Speed = (Load Key("speed") of Key((Picked Unit)) from SPELL_HASHTABLE)
      • Set DP_New = (DP offset by (Speed x TIMER_PERIOD) towards Ang degrees)
      • Unit - Move (Picked Unit) instantly to DP_New
      • Custom script: call RemoveLocation(udg_DP)
      • Custom script: call RemoveLocation(udg_DP_New)
It doesn't have to be particularly complicated if it's just for visual purposes, though. Often the easiest and simplest solution is to give your dummy units Locust, flying movement, the correct move speed, and then just order them to move to a targeted point with a trigger. Or, similar to what you've done here, use the unit model as the projectile for something like Storm Bolt or Carrion Swarm so that you can just cast the spell at a target unit/location and the correct model flies from caster to target automatically. Work smart!
 
Level 3
Joined
Jul 23, 2019
Messages
12
If you wanted to make all the dummies slowly approach the center every tick you could do something like this:
  • unitgroup.gif
    Unit Group - Pick every unit in DummyGroup[Index] and do (Actions)
    • joinbottomminus.gif
      actions.gif
      Loop - Actions
      • empty.gif
        join.gif
        set.gif
        Set DP = (Position of (Picked Unit))
      • empty.gif
        join.gif
        set.gif
        Set Ang = (Angle between DP and CenterPoint[Index]) //or you could use Facing Angle of Picked Unit if it's appropriate
      • empty.gif
        join.gif
        set.gif
        Set DP_New = (DP offset by (SPEED x TIMER_PERIOD) towards Ang degrees)
      • empty.gif
        join.gif
        unit.gif
        Unit - Move (Picked Unit) instantly to DP_New
      • empty.gif
        join.gif
        page.gif
        Custom script: call RemoveLocation(udg_DP)
      • empty.gif
        joinbottom.gif
        page.gif
        Custom script: call RemoveLocation(udg_DP_New)
Omg I wish I saw this reply before I started looking up how to move something via GUI lol. I more or less got it to work through sheer trial and error and with a little logic.

It doesn't have to be particularly complicated if it's just for visual purposes, though. Often the easiest and simplest solution is to give your dummy units Locust, flying movement, the correct move speed, and then just order them to move to a targeted point with a trigger. Or, similar to what you've done here, use the unit model as the projectile for something like Storm Bolt or Carrion Swarm so that you can just cast the spell at a target unit/location and the correct model flies from caster to target automatically. Work smart!
You're actually a genius.. Idk why I never thought of that, instead of being all fancy I could have just opted for grouping them, picking them all and issuing a move command.

BUT I regret nothing ahaha I'm learning something new! This is just another example of thinking outside the box. Plus it's useful incase I need to move something above the movespeed cap

Now to learn how to move something via setunit(x,y) but it shouldn't be too necessary if only moving dummies, the spam stop command won't be a problem.

And as always, thanks for all the advice Pyro!
 
Top