• 🏆 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!

[Solved] 1 Dummy Casting on Unit Group vs. 1 Dummy for Every Unit in Unit Group

Level 5
Joined
Dec 30, 2022
Messages
36
Hello!

I have two example triggers below. The first works on every unit in the unit group, and the second does not - It only seems to hit a handful of random units in the group. I am not sure why the second doesn't work.

My reasoning for trigger #2 is to create less units overall in the game, reducing leaks/lag in the log run.

  • alifeCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Antilife Shell (Necro)
    • Actions
      • Set VariableSet alifeCasterLoc[(Player number of (Owner of (Triggering unit)))] = (Position of (Triggering unit))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 800.00 of alifeCasterLoc[(Player number of (Owner of (Triggering unit)))].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is dead) Equal to True
              • (Color of (Owner of (Picked unit))) Equal to (Color of Player 12 (Brown))
            • Then - Actions
              • Set VariableSet alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] = (alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] + 1)
              • Set VariableSet alifeCorpseLoc[(Player number of (Owner of (Triggering unit)))] = (Position of (Picked unit))
              • Special Effect - Create a special effect at alifeCorpseLoc[(Player number of (Owner of (Triggering unit)))] using Objects\Spawnmodels\Undead\UndeadDissipate\UndeadDissipate.mdl
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call RemoveLocation(udg_alifeCorpseLoc[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
            • Else - Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 800.00 of alifeCasterLoc[(Player number of (Owner of (Triggering unit)))].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] Greater than 0
              • ((Owner of (Picked unit)) controller) Equal to User
              • ((Picked unit) is dead) Equal to False
            • Then - Actions
              • Unit - Create 1 dummy_unit for (Owner of (Triggering unit)) at alifeCasterLoc[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
              • Unit - Add a 0.30 second Generic expiration timer to (Last created unit)
              • Set VariableSet alifeDummyUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
              • Unit - Add Antilife Shell (Necro Dummy) to alifeDummyUnit[(Player number of (Owner of (Triggering unit)))]
              • Ability - Set Ability: (Unit: alifeDummyUnit[(Player number of (Owner of (Triggering unit)))]'s Ability with Ability Code: Antilife Shell (Necro Dummy))'s Integer Level Field: Defense Increase ('Inf2') of Level: 0 to (alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] x 5)
              • Set VariableSet alifeArmorTarget[(Player number of (Owner of (Triggering unit)))] = (Picked unit)
              • Unit - Order alifeDummyUnit[(Player number of (Owner of (Triggering unit)))] to Human Priest - Inner Fire alifeArmorTarget[(Player number of (Owner of (Triggering unit)))]
            • Else - Actions
      • Set VariableSet alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] = 0
      • Custom script: call RemoveLocation(udg_alifeCasterLoc[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])

  • alifeCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Antilife Shell (Necro)
    • Actions
      • Set VariableSet alifeCasterLoc[(Player number of (Owner of (Triggering unit)))] = (Position of (Triggering unit))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 800.00 of alifeCasterLoc[(Player number of (Owner of (Triggering unit)))].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is dead) Equal to True
              • (Color of (Owner of (Picked unit))) Equal to (Color of Player 12 (Brown))
            • Then - Actions
              • Set VariableSet alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] = (alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] + 1)
              • Set VariableSet alifeCorpseLoc[(Player number of (Owner of (Triggering unit)))] = (Position of (Picked unit))
              • Special Effect - Create a special effect at alifeCorpseLoc[(Player number of (Owner of (Triggering unit)))] using Objects\Spawnmodels\Undead\UndeadDissipate\UndeadDissipate.mdl
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call RemoveLocation(udg_alifeCorpseLoc[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
            • Else - Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit - Create 1 dummy_unit for (Owner of (Triggering unit)) at alifeCasterLoc[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Set VariableSet alifeDummyUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
      • Unit - Add Antilife Shell (Necro Dummy) to alifeDummyUnit[(Player number of (Owner of (Triggering unit)))]
      • Ability - Set Ability: (Unit: alifeDummyUnit[(Player number of (Owner of (Triggering unit)))]'s Ability with Ability Code: Antilife Shell (Necro Dummy))'s Integer Level Field: Defense Increase ('Inf2') of Level: 0 to (alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] x 5)
      • Unit Group - Pick every unit in (Units within 800.00 of alifeCasterLoc[(Player number of (Owner of (Triggering unit)))].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] Greater than 0
              • ((Owner of (Picked unit)) controller) Equal to User
              • ((Picked unit) is dead) Equal to False
            • Then - Actions
              • Set VariableSet alifeArmorTarget[(Player number of (Owner of (Triggering unit)))] = (Picked unit)
              • Unit - Order alifeDummyUnit[(Player number of (Owner of (Triggering unit)))] to Human Priest - Inner Fire alifeArmorTarget[(Player number of (Owner of (Triggering unit)))]
            • Else - Actions
      • Set VariableSet alifeCorpseCount[(Player number of (Owner of (Triggering unit)))] = 0
      • Custom script: call RemoveLocation(udg_alifeCasterLoc[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])

As always, thanks for the help! :wthumbsup:
 
Level 19
Joined
Feb 27, 2019
Messages
590
Does the dummy have 0 movement speed? It makes it so it doesnt have to face targets when casting abilities on them.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,544
You can use a Dummy recycling system (search Hive for one) in addition to what [db]east said to further optimize your dummy usage.

Or just do it yourself with a simple system:

Map init -> Pick every player -> Create 1 Dummy for (picked player) -> Set variable PlayerDummy[Player number of (picked player)] = (Last created unit)

This creates 1 Dummy unit per Player. Each Dummy unit can then be referenced almost whenever you want. Note that you'll need to use a different Dummy unit when you order it to cast a channeled ability or one with Casting Time, since that will occupy it's time for a moment.
 
Level 5
Joined
Dec 30, 2022
Messages
36
Does the dummy have 0 movement speed? It makes it so it doesnt have to face targets when casting abilities on them.
Yep 0 move speed, thanks for the suggestion.

You can use a Dummy recycling system (search Hive for one) in addition to what [db]east said to further optimize your dummy usage.

Or just do it yourself with a simple system:

Map init -> Pick every player -> Create 1 Dummy for (picked player) -> Set variable PlayerDummy[Player number of (picked player)] = (Last created unit)

This creates 1 Dummy unit per Player. Each Dummy unit can then be referenced almost whenever you want. Note that you'll need to use a different Dummy unit when you order it to cast a channeled ability or one with Casting Time, since that will occupy it's time for a moment.
Didn't even think about this and will definitely implement at some point. However I don't think this solves the particular issue/question I have here. My dummy unit has a 0 cast point/cast backswing & the spell has a 0 cast time. How come I can't have 1 unit cast on the entire group of picked units?
 
Level 19
Joined
Feb 27, 2019
Messages
590
It can be easier to spot dummy issues if the dummy is visible and intractable. Give the dummy a model, remove the locust ability and dont add an expiration timer. Cast the spell and see what happens.
 
Level 12
Joined
Jan 10, 2023
Messages
191
So, this is another question, but related:

Do most abilities activate rapidly and instantly when 1 unit is told to cast an ability many many times? I would have thought there would be a time-based limit to the frequency even with a casting time of zero, but I'm glad it is possible, I just wouldn't have thought it was..
 
Level 19
Joined
Feb 27, 2019
Messages
590
So, this is another question, but related:

Do most abilities activate rapidly and instantly when 1 unit is told to cast an ability many many times? I would have thought there would be a time-based limit to the frequency even with a casting time of zero, but I'm glad it is possible, I just wouldn't have thought it was..
Yes, but the spell effect may take at least another instant to take effect. Most damage dealing spells take at least an instant to take effect except for like finger of death and maybe chain lightning. Its possible to make an invulnerable target vulnerable, create a dummy unit, order the dummy unit to cast finger of death on the target then make the target invulnerable again in the same instant and the target would take damage.
 
Level 5
Joined
Dec 30, 2022
Messages
36
It can be easier to spot dummy issues if the dummy is visible and intractable. Give the dummy a model, remove the locust ability and dont add an expiration timer. Cast the spell and see what happens.
Since the trigger is happening in less than a quarter of a second I don't think this will help at all.
 
Level 12
Joined
Jan 10, 2023
Messages
191
Since the trigger is happening in less than a quarter of a second I don't think this will help at all.
The trigger is [not] happening in a quarter of a second...

Troubleshooting is your friend. It's what we don't know that is preventing us from helping.

Debug messages (display text to player).

I'm gonna second [db]east on that. You might feel sure that you will learn nothing. That's going to hinder you more than anything. It also screams "don't help me, I don't even help me".

The goal is to find out what IS happening and why that is different from what you want to have happen.

[db]east's advice may lead no where, but it might bring up some obscure problem that wouldn't have otherwise been noticed.

Regardless, if it takes no time at all to run a single test like this and you refuse after saying you have no idea why it doesn't work, who can help you?
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
I see in the second (not working) trigger that the order given is 'Inner Fire'. So I created an empty map, created dummy and a dummy version of spell based on the inner fire ability.
I placed 50 footman/knights around a circle of power and then ran the following trigger:
  • Test
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Unit - Create 1 Dummy for Player 1 (Red) at (Position of Circle of Power 0007 <gen>) facing Default building facing degrees
      • Set VariableSet dummy = (Last created unit)
      • Unit - Add Test Spell to dummy
      • Unit Group - Pick every unit in (Units within 800.00 of (Position of Circle of Power 0007 <gen>) matching ((Owner of (Matching unit)) Equal to Player 1 (Red)).) and do (Actions)
        • Loop - Actions
          • Unit - Order dummy to Human Priest - Inner Fire (Picked unit)
      • Unit - Remove dummy from the game
That trigger applied the Inner Fire on all 50 units.
So my guess is that you are doing something wrong. Could be mana cost of ability causes dummy to end up with no mana, or the spell's actual range is not the 800.00 pick up range, etc.
 
Level 5
Joined
Dec 30, 2022
Messages
36
I am an idiot - I thought my dummy's movespeed is at 0 and it wasn't 🤦‍♂️ changing it to zero fixed my issue.

Thanks all!
 
Top