• 🏆 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!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!

[Spell] A unit takes damage as a unit group unit variable for spells

Status
Not open for further replies.

deepstrasz

Map Reviewer
Level 71
Joined
Jun 4, 2009
Messages
19,228
I'm trying to use Carrion Swarm to slow down (using a dummy unit) units which are being hit/damaged by it. It seems not to work if I use a picked unit variable as the unit taking damage as seen here:
  • Events
    • Unit - A unit Starts the effect of an ability
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • And - All (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Arcane Blast (Carrion Swarm)
    • Then - Actions
      • Game - Display to (All players) the text: ARCANE CAST
      • Set ArcaneBlastCasterPoint01 = (Position of (Casting unit))
      • Set ArcaneBlastGroup01 = (Units within 3000.00 of ArcaneBlastCasterPoint01 matching (((Matching unit) belongs to an enemy of Player 4 (Purple)) Equal to True))
      • Unit Group - Pick every unit in ArcaneBlastGroup01 and do (Actions)
        • Loop - Actions
          • Game - Display to (All players) the text: GROUP SET
          • Set ArcaneBlastTarget01 = (Picked unit)
          • Trigger - Add to Faceless 3n4 Spell Slow <gen> the event (Unit - ArcaneBlastTarget01 Takes damage)
    • Else - Actions
      • Do nothing
  • Faceless 3n4 Spell Slow
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Owner of (Damage source)) Equal to Player 4 (Purple)
              • (Damage taken) Greater than or equal to 140.00
        • Then - Actions
          • Game - Display to (All players) the text: Arcane HITS
          • -------- Slow --------
          • Set ArcaneBlastTargetPoint01 = (Position of ArcaneBlastTarget01)
          • Unit - Create 1 Arcane Blast Slow Caster for Player 4 (Purple) at ArcaneBlastTargetPoint01 facing (Facing of (Picked unit)) degrees
          • Set ArcaneBlastSlow01 = (Last created unit)
          • Unit - Add a 4.00 second Generic expiration timer to ArcaneBlastSlow01
          • Unit - Order ArcaneBlastSlow01 to Human Sorceress - Slow ArcaneBlastTarget01
        • Else - Actions
          • Do nothing
What happens, is that random units from the group might get slowed (not all) and certainly not the actual one(s) which got damaged.
Don't mind the leaks. It's just a stub.

So, if you've got any idea(s), please lend a hand.
 
Last edited:
Level 15
Joined
Mar 25, 2016
Messages
1,327
What is ArcaneBlastTarget01 in the context of the second trigger?
From these two triggers it seems to be the last unit in the unit group.
Picked unit also has no context in the second trigger

If you want to access the damaged unit, you need to use triggering unit. You could simply set ArcaneBlastTarget01 to triggering unit at the beginning of the trigger and then use that.
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
Trigger the whole spell.

Use a channel or keep carrion swarm with no damage and removed art.
With that spawn a sfx or a dummy unit at the position of the caster to act as missile.
In a loop move it towards the direction of the target point while picking units in AoE range.
Use a single dummy unit to cast the slow on everything in the AoE.

Edit// @Jampion Is that such a good idea ? I mean, the second trigger would leak events like no tomorrow and also there is no good way to isolate only units hit by the spell...

regards
-Ned
 
Last edited:
Level 15
Joined
Mar 25, 2016
Messages
1,327
The easiest way to do this is using frost breath together with a damage detection system, if you don't want to trigger the whole spell.

The trigger would look like this:
a unit takes damage
if unit has frost breath buff
remove frost breath buff
trigger your custom effect (slow in this case)

The buff is used to verify that the damage came from frost breath and then immediatly removed.
 

deepstrasz

Map Reviewer
Level 71
Joined
Jun 4, 2009
Messages
19,228
What is ArcaneBlastTarget01 in the context of the second trigger?
It's the picked unit from the first trigger but I guess it's not for some reason?
The last unit? That's how it work? Weird, then how does slow work on all units in a range of a dummy unit then using the unit group action? (remember the link below?).
Picked unit also has no context in the second trigger
Why? I've linked it with the Add new event action.
If you want to access the damaged unit, you need to use triggering unit. You could simply set ArcaneBlastTarget01 to triggering unit at the beginning of the trigger and then use that.
I'll try it, see what happens.

Trigger the whole spell.

Use a channel or keep carrion swarm with no damage and removed art.
With that spawn a sfx or a dummy unit at the position of the caster to act as missile.
In a loop move it towards the direction of the target point while picking units in AoE range.
Use a single dummy unit to cast the slow on everything in the AoE.
Tried moving it with move unit but then the a unit comes within range event doesn't work as the unit is not really there (within the range?) anymore.
Plus, I can't make it move more than 522, normally.
The spell works with a dummy unit as seen here: Locust, moving & enter regions, unit groups but I need it to be as fast as a projectile.

The buff is used to verify that the damage came from frost breath and then immediatly removed.
That's smart. I won't use a damage detection system as I'm too stupid to do so.
I'll come back with a response pertaining the Triggering Unit function.
Thank you guys.
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
It's the picked unit from the first trigger but I guess it's not for some reason?
The last unit? That's how it work? Weird, then how does slow work on all units in a range of a dummy unit then using the unit group action? (remember the link below?).

Oh, no, you have:
Code:
Loop Group
  Set Variable = picked unit
end loop

Second trigger
 do stuff to Variable
You see Variable transfers to the second trigger, it is only a single unit.
When you loop the group, at the end of the first trigger Variable points to the last unit of the group.

Tried moving it with move unit but then the a unit comes within range event doesn't work as the unit is not really there (within the range?) anymore.
Plus, I can't make it move more than 522, normally.
The spell works with a dummy unit as seen here: Locust, moving & enter regions, unit groups but I need it to be as fast as a projectile.
Oh, I should have specified, apologies:

Don't use "Order - Move to position"
Use "Move Unit instantly to Position" or "Set unit X/Y Coordinates" (second one does not exist in GUI) Edit// you need the second one actually for spells. the first one checks pathing and your missile should be able to go through trees and other units. //endedit
You do this within a trigger like:
  • LoopForSpell
    • Event
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Move DummyUnitOfSpell by 25 towards angle between CastPoint and TargetPoint /////The syntax here is totally made up
You see, now this makes 825 speed per second.
0.03 is about 33 frames. Move by 20 so you have 33 * 20 ~= 825

regards
-Ned
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
Why? I've linked it with the Add new event action.
You seem to missunderstand how adding trigger events work.

In your first trigger you add an event to the second trigger. This only adds an event to the second trigger. So it is not different than if you would have added the exact same event in the world editor.
The triggers are linked in no way to each other.
Let's say you have 2 units in your unit group: unit1 unit2
the unit group runs for the first unit:
picked unit is unit1
ArcaneBlastTarget01 is unit1
the event "unit1 is damaged" is added to the second trigger
now the group runs for unit2
picked unit is unit2
ArcaneBlastTarget01 is unit2
the event "unit2 is damaged" is added to the second trigger

some time later the second trigger runs, because unit1 was damaged.
ArcaneBlastTarget01 is still unit2, because the last time it was set was in the unit group
picked unit is not defined, as you are not inside a unit group
this trigger runs on its own like every other trigger would that has a normal unit event
it does not know that its event was added inside a unit group, where picked unit was still defined

I hope that clarifies what adding events to triggers does to some extent.


Missile system do not have to use unit movement. They teleport the unit every 0.03 seconds for example. This allows very high movement speeds.
Anyway triggering it by yourself is always more difficult then using an already existing ability.

As I said the easiest is using a damage detection system. It is literally like 3 lines to get the event when a unit is hit by the breath of frost missile. After that you only have to use the dummy caster, but you already have that in your trigger.
What you are doing right now (adding unit takes damage events) is kind of what a damage detection system does. Additionally a damage system cleans the events up. If you added an event for a unit and the unit is removed this event is unnecessary and will decrease the performance of the trigger. A damage system makes sure not that many events for removed units are in the trigger.

This should be one of the easiest damage detection systems to use: GUI-Friendly Damage Detection v1.2.1
 

deepstrasz

Map Reviewer
Level 71
Joined
Jun 4, 2009
Messages
19,228
When you loop the group, at the end of the first trigger Variable points to the last unit of the group.
So, how can I have a variable be any unit in a specified group?
You see, now this makes 825 speed per second.
0.03 is about 33 frames. Move by 20 so you have 33 * 20 ~= 825
I did something like that too but as I've mentioned, the slow wasn't being triggered anymore because the unit being unnaturally moved, the enemy units near it weren't detected in a unit comes within range of (moved dummy unit). Plus, that speed is still not quite enough for a projectile. Carrion Swarm's is 1000. Thanks though.

Anyways, thanks @Jampion (post), now it seems to be working like a charm:
  • Faceless 3n4 Spell Slow
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Set ArcaneBlastGroup01 = (Units in (Playable map area))
      • Unit Group - Pick every unit in ArcaneBlastGroup01 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • ((Picked unit) belongs to an enemy of Player 4 (Purple)) Equal to True
                  • ((Picked unit) has buff Breath of Frost) Equal to True
            • Then - Actions
              • Unit - Remove Breath of Frost buff from ArcaneBlastTarget01
              • Set ArcaneBlastTarget01 = (Picked unit)
              • Game - Display to (All players) the text: Arcane SLOW
              • -------- Slow --------
              • Set ArcaneBlastTargetPoint01 = (Position of ArcaneBlastTarget01)
              • Unit - Create 1 Arcane Blast Slow Caster for Player 4 (Purple) at ArcaneBlastTargetPoint01 facing (Facing of ArcaneBlastTarget01) degrees
              • Set ArcaneBlastSlow01 = (Last created unit)
              • Unit - Add a 4.00 second Generic expiration timer to ArcaneBlastSlow01
              • Unit - Order ArcaneBlastSlow01 to Human Sorceress - Slow ArcaneBlastTarget01
            • Else - Actions
              • Do nothing
      • -------- Remove Leaks --------
      • Custom script: call RemoveLocation (udg_ArcaneBlastTargetPoint01)
      • Custom script: call DestroyGroup (udg_ArcaneBlastGroup01)
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
So, how can I have a variable be any unit in a specified group?
In your original trigger, that should have been (Triggering unit) instead of the variable. As Jampion suggested

I did something like that too but as I've mentioned, the slow wasn't being triggered anymore because the unit being unnaturally moved, the enemy units near it weren't detected in a unit comes within range of (moved dummy unit). Plus, that speed is still not quite enough for a projectile. Carrion Swarm's is 1000. Thanks though.
Erm, that is an event, not a comparison... what you would do with a missile system is,
  • Events
    • Time - Every 0.03 seconds of game time
  • Conditions
  • Actions
    • Pick all units in 100 range of position of DummyMissile //Create a unit group here containing all the units in range
      • Deal damage
      • Slow Picked unit
    • Move missile by 30 towards angle between cast point and target point
You just increase the step to 30 and now you have 999 speed. 33.(3) * 30 ~= 999
Otherwise, you could decrease the interval to 0.02 making it 50 FPS then you have 50*20 = 1000

There are a few other things to consider to make it "as desired"

Anyways, thanks @Jampion (post), now it seems to be working like a charm:
  • Faceless 3n4 Spell Slow
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Set ArcaneBlastGroup01 = (Units in (Playable map area))
      • Unit Group - Pick every unit in ArcaneBlastGroup01 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • ((Picked unit) belongs to an enemy of Player 4 (Purple)) Equal to True
                  • ((Picked unit) has buff Breath of Frost) Equal to True
            • Then - Actions
              • Unit - Remove Breath of Frost buff from ArcaneBlastTarget01
              • Set ArcaneBlastTarget01 = (Picked unit)
              • Game - Display to (All players) the text: Arcane SLOW
              • -------- Slow --------
              • Set ArcaneBlastTargetPoint01 = (Position of ArcaneBlastTarget01)
              • Unit - Create 1 Arcane Blast Slow Caster for Player 4 (Purple) at ArcaneBlastTargetPoint01 facing (Facing of ArcaneBlastTarget01) degrees
              • Set ArcaneBlastSlow01 = (Last created unit)
              • Unit - Add a 4.00 second Generic expiration timer to ArcaneBlastSlow01
              • Unit - Order ArcaneBlastSlow01 to Human Sorceress - Slow ArcaneBlastTarget01
            • Else - Actions
              • Do nothing
      • -------- Remove Leaks --------
      • Custom script: call RemoveLocation (udg_ArcaneBlastTargetPoint01)
      • Custom script: call DestroyGroup (udg_ArcaneBlastGroup01)
Are we still leaving leaks aside?

regards
-Ned
 

deepstrasz

Map Reviewer
Level 71
Joined
Jun 4, 2009
Messages
19,228
You just increase the step to 30 and now you have 999 speed. 33.(3) * 30 ~= 999
Otherwise, you could decrease the interval to 0.02 making it 50 FPS then you have 50*20 = 1000
Interesting. Well, now, I guess I'll try that another time.
Are we still leaving leaks aside?
Which ones?
EDIT: you mean to place those in the unit group loop? Sure.
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
Which ones?
EDIT: you mean to place those in the unit group loop? Sure.
;)

Also
  • Do nothing
this... does nothing... it is code that... does nothing.
It is the same as having nothing, which is more efficient because nothing does not get compiled and executed while "do nothing" does.

If you like/need it for visual indication, leave it.
Otherwise, remove all of those.

regards
-Ned
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
I will leave this map for reference here. For anyone interested how this will work with a damage detection system.

This is the trigger:
  • BreathOfSlow
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GDD_DamagedUnit has buff BreathOfSlowDetection ) Equal to True
        • Then - Actions
          • Unit - Remove BreathOfSlowDetection buff from GDD_DamagedUnit
          • -------- Apply Effect: --------
          • Set TempPoint = (Position of GDD_DamagedUnit)
          • Unit - Create 1 Dummy for Neutral Passive at TempPoint facing Default building facing degrees
          • Unit - Add Slow (dummy) to (Last created unit)
          • Unit - Order (Last created unit) to Human Sorceress - Slow GDD_DamagedUnit
          • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
          • Custom script: call RemoveLocation(udg_TempPoint)
        • Else - Actions
It is more efficient, because it does not loop through every unit on the map. If you have a lot of units on your map this can slow the map down by a lot.
Additionally the slow effect is applied instantly.
 

Attachments

  • BreathOfSlow.w3x
    25.6 KB · Views: 43
Status
Not open for further replies.
Top