• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Solved] When a unit evades an attack it cast defend

Level 12
Joined
Oct 28, 2019
Messages
480
Dont know how do this trigger. Appears simple, looking for information it looks like impossible.

A footman has evade of 20%. But I want a animation when the attack get missed. it cast defend

Already tried "A unit is about to take damage" is useless cause is the same of "A unit takes damage"
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
Using a Damage Engine, trigger Evasion yourself, then you can do anything you'd like in response.

Note that Animations can be difficult to get right because the unit can easily interrupt the animation with other orders.

The solution is to use SetUnitAnimationByIndex() which is a function unavailable in GUI that can play animations that won't get interrupted by movement. I'm pretty sure the animation still gets interrupted by attacks/spells though, but I could be wrong.
 
Level 12
Joined
Oct 28, 2019
Messages
480
Using a Damage Engine, trigger Evasion yourself, then you can do anything you'd like in response.

Note that Animations can be difficult to get right because the unit can easily interrupt the animation with other orders.

The solution is to use SetUnitAnimationByIndex() which is a function unavailable in GUI that can play animations that won't get interrupted by movement. I'm pretty sure the animation still gets interrupted by attacks/spells though, but I could be wrong.
I´ve tried the Damage engime in previous maps, and I dont know how work on it, its looks complicate, plz send a tutorial to use the damage engine
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
It depends on which version of Warcraft 3 you're using and which Damage Engine you want to go with. Most people use Bribe's Damage Engine since he has been working on it for so long and it covers pretty much everything damage related. My only complaint, and this isn't his fault as it's just the nature of working in GUI and with something that's so flexible, is the huge amount of variables required. That being said, if you don't mind that then it's the best option we have available.


After importing that into your map, you can create your Evasion trigger like this:
  • Example
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Level of Evasion (Custom) for DamageEventTarget) Not equal to 0
      • IsDamageSpell Equal to False
      • IsDamageCode Equal to False
      • (Random integer number between 1 and 100) Less than or equal to 20
    • Actions
      • Set Variable DamageEventAmount = 0
All of these Damage variables come with the system. Older versions may be missing some of these.

There are several different Real Events provided by the system which you can choose from. These allow you to do things like modify damage before armor is calculated or after armor is calculated. I generally like to keep it simple and stick with the Event I chose above, which I believe happens after most if not all calculations are made. You can learn more about these on the Damage Engine page.

DamageEventTarget is the unit that was dealt damage. DamageEventSource is the unit that dealt the damage.

IsDamageSpell, IsDamageCode, IsDamageMelee, and IsDamageRanged are Booleans which are there to help you figure out where the damage came from. In this case we've narrowed it down so that the trigger only runs if the damage came from a Melee or Ranged unit.

DamageEventAmount is how much damage is going to be dealt. This variable gets set before the Event runs so it's ready to be used right away. You can change it in the Actions to whatever you'd like. Since this is an Evasion ability I am setting it to 0, so no damage is going to be dealt.

Here's an example of increasing the damage dealt using simple Arithmetic:
  • Set Variable DamageEventAmount = (DamageEventAmount + 100.00)
Now the unit is dealing 100 bonus damage.
 
Last edited:
Level 12
Joined
Oct 28, 2019
Messages
480
ive copied the engine but cant install

how do I import the triggers without replace the preview maps trigger
1674766907222.png
 

Attachments

  • 1674764740435.png
    1674764740435.png
    71.9 KB · Views: 2
Last edited:
Level 12
Joined
Oct 28, 2019
Messages
480
Solved, I´ve Used the JAJAJA version....

worked nice but the animation is a problem

  • WarriorBlock
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 5) Equal to 1
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
          • Unit - Order DamageEventTarget to Human Footman - Defend.
          • Wait 0.10 seconds
          • Unit - Order DamageEventTarget to Human Footman - Stop Defend.
        • Else - Actions
the warrior cast defend but dont stop defend
 
Level 39
Joined
Feb 27, 2007
Messages
5,031
...why do you want to defend for 1/10th of a second? Are you trying to reduce damage taken by subsequent attacks? To reflect a projectile that the enemy dodged?
  • 0.10s is way too short for a wait to work (minimum duration is about 0.27 seconds).
  • DamageEventTarget no longer has the correct value after time has passed (its set by the DDS any time any unit takes any damage).
  • Even if 0.10s wait could be performed, the unit can't defend and undefend that fast because of animation times/cast time of the ability.
  • If the damaged unit is stunned or silenced it won't be able to use defend anyway.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
Yeah, I don't think you're getting anything out of toggling Defend, if you simply want the animation then use this:
  • Custom script: call SetUnitAnimationByIndex(udg_DamageEventTarget, 4)
The number 4 is which animation is played. I'm pretty sure 4 is the Footman's Defend animation but you can try other numbers if that one doesn't work.

You can also create a Special Effect so it looks exactly like the real Defend ability.

Lastly, if you wish to use a Wait then you'll want to use a local variable to store the damaged unit:
  • WarriorBlock
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Random integer number between 1 and 5) Equal to 1
    • Actions
      • Custom script: local unit u = udg_DamageEventTarget
      • Set VariableSet DamageEventAmount = 0.00
      • Custom script: call SetUnitAnimationByIndex(u, 4)
      • Wait 0.10 seconds
      • Custom script: call ResetUnitAnimation(u)
      • Custom script: set u = null
^ Keep in mind this is missing some of the important Conditions that you most likely want.
 
Last edited:
Level 12
Joined
Oct 28, 2019
Messages
480
...why do you want to defend for 1/10th of a second? Are you trying to reduce damage taken by subsequent attacks? To reflect a projectile that the enemy dodged?
  • 0.10s is way too short for a wait to work (minimum duration is about 0.27 seconds).
  • DamageEventTarget no longer has the correct value after time has passed (its set by the DDS any time any unit takes any damage).
  • Even if 0.10s wait could be performed, the unit can't defend and undefend that fast because of animation times/cast time of the ability.
  • If the damaged unit is stunned or silenced it won't be able to use defend anyway.
Its just the animation shield blocking an attack, not to use the ability "defend"
Yeah, I don't think you're getting anything out of toggling Defend, if you simply want the animation then use this:
  • Custom script: call SetUnitAnimationByIndex(udg_DamageEventTarget, 4)
The number 4 is which animation is played. I'm pretty sure 4 is the Footman's Defend animation but you can try other numbers if that one doesn't work.

You can also create a Special Effect so it looks exactly like the real Defend ability.

Lastly, if you wish to use a Wait then you'll want to use a local variable to store the damaged unit:
  • WarriorBlock
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Custom script: local unit u = udg_DamageEventTarget
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 5) Equal to 1
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
          • Custom script: call SetUnitAnimationByIndex(u, 4)
          • Wait 0.10 seconds
          • Custom script: call ResetUnitAnimation(u)
        • Else - Actions
I will try this, So 4 is the defend animation, and to stand back the older animation how do? theres other.... when a Footman block an attack with his hield, appears a floating text "block"
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
ResetUnitAnimation() is the function that resets the Footman back to the default animation. Again, the Footman can interrupt this animation pretty easily so don't expect it to always work.

You can use Floating Text to create the "block" text effect. I'd be surprised if you haven't used this before but it's pretty much always the same process.

Also, I updated my last post, the trigger is different.
 
Last edited:
Level 20
Joined
Feb 27, 2019
Messages
593
Here is an alternate option for the defend animation. It works pretty neatly but can ruin attack animations that occur slightly after the event triggers.
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Random integer number between 1 and 5) Equal to 1
    • Then - Actions
      • Animation - Add the defend animation tag to (Triggering unit)
      • Wait 0.10 seconds
      • Animation - Remove the defend animation tag to (Triggering unit)
    • Else - Actions
 
Level 12
Joined
Oct 28, 2019
Messages
480
Yeah, I don't think you're getting anything out of toggling Defend, if you simply want the animation then use this:
  • Custom script: call SetUnitAnimationByIndex(udg_DamageEventTarget, 4)
The number 4 is which animation is played. I'm pretty sure 4 is the Footman's Defend animation but you can try other numbers if that one doesn't work.

You can also create a Special Effect so it looks exactly like the real Defend ability.

Lastly, if you wish to use a Wait then you'll want to use a local variable to store the damaged unit:
  • WarriorBlock
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Random integer number between 1 and 5) Equal to 1
    • Actions
      • Custom script: local unit u = udg_DamageEventTarget ********** THIS SCRIPT IS GOIN ERROR
      • Set VariableSet DamageEventAmount = 0.00
      • Custom script: call SetUnitAnimationByIndex(u, 4)
      • Wait 0.10 seconds
      • Custom script: call ResetUnitAnimation(u)
      • Custom script: set u = null
^ Keep in mind this is missing some of the important Conditions that you most likely want.
 
Level 39
Joined
Feb 27, 2007
Messages
5,031
@Herod Don't just put a comment in the middle of a quoted block of text and hope someone decides to decipher what the fuck your reply that's just a quote is supposed to say.
  • Custom script: local unit u = udg_DamageEventTarget ********** THIS SCRIPT IS GOIN ERROR
No it doesn't; you typed something wrong. That variable exists from DamageEngine.
 
Level 12
Joined
Oct 28, 2019
Messages
480
@Herod Don't just put a comment in the middle of a quoted block of text and hope someone decides to decipher what the fuck your reply that's just a quote is supposed to say.
  • Custom script: local unit u = udg_DamageEventTarget ********** THIS SCRIPT IS GOIN ERROR
No it doesn't; you typed something wrong. That variable exists from DamageEngine.
IDK I´ve copy all the codes and get a script error, didnt try with the script way...
My map has 10 footmans, I´ve noticed that some stay with "defend" position and dont stand back, cause the trigger choose ( in a time, the wait 0.27 seconds) other variable.
IF I set every footman one variable for each I can solve this right?
 
Level 12
Joined
Oct 28, 2019
Messages
480
Tell us what the error says or send a screenshot. You most likely misspelled something, it's case sensitive.

I tested that custom script out in the editor just now and didn't get any issues. Maybe you don't have the DamageEventTarget variable?
  • WarriorDamaged Copy
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventTarget) Equal to Warrior
      • (Unit-type of DamageEventSource) Not equal to Flame Arrow Dummy
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 1) Equal to 1
          • ((Triggering unit) has buff Stunned (Pause)) Equal to False
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
          • Set VariableSet UnitWarrior = DamageEventTarget
          • Custom script: local unit u = udg_DamageEventTarget
          • Custom script: call SetUnitAnimationByIndex(u, 4)
          • Floating Text - Create floating text that reads |cff808080Block|r at (Position of UnitWarrior) with Z offset 0.00, using font size 8.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
          • Custom script: call ResetUnitAnimation(u)
          • Custom script: set u = null
        • Else - Actions
          • Set VariableSet UnitWarrior = DamageEventTarget
          • Unit - Create 1 Bash Dummy HIT for Neutral Passive at (Position of UnitWarrior) facing Default building facing degrees
          • Unit - Add a 10.00 second Generic expiration timer to (Last created unit)
          • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt UnitWarrior
1674872899535.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
Local variables need to be declared at the very start of the Actions.

Also, this is unnecessary:
  • Set VariableSet UnitWarrior = DamageEventTarget
And make sure to reference the Damage variables:
  • ((Triggering unit) has buff Stunned (Pause)) Equal to False
(Triggering unit) probably still works though, I'd assume it's the unit that took the damage in this case.
 
Level 12
Joined
Oct 28, 2019
Messages
480
this is almost solved,
  • WarriorDamaged1
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventTarget) Equal to Warrior
        • Actions
      • Set VariableSet UnitWarrior = DamageEventTarget
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 4) Equal to 1
          • (DamageEventTarget has buff Stunned (Pause)) Equal to False
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
          • Unit - Order DamageEventTarget to Human Footman - Defend.
          • Floating Text - Create floating text that reads |cff808080Block|r at (Position of DamageEventTarget) with Z offset 0.00, using font size 8.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
          • Countdown Timer - Start TimerDefend as a One-shot timer that will expire in 2.00 seconds
        • Else - Actions
  • Timer
    • Events
      • Time - TimerDefend expires
    • Conditions
    • Actions
      • Unit - Order UnitWarrior to Human Footman - Stop Defend.
Theres other conditions i´ve removed to see better,

Its simple, A warrior has 25% chance to block an attack, if it blocks, it cast defend animation, until here, all ok, but how can I do it return to normal position after 1 or 2 seconds? I´ve tried wait, and timer, but in this short period Other damage events happens and fires the trigger. Originaly I was triggering every footman (warrior) in the map, but need generalizate
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
You're using one Timer for every single Warrior. You're also hoping that the UnitWarrior variable doesn't change during the 2.00 seconds that this Timer runs.

Your Warriors are all going to be fighting over who uses these variables.

Assuming you want this effect to be possible even while the Warrior is Defending then the solution would be to give each Warrior it's own unique Timer.

If a Warrior can only Block while it's NOT Defending already then you can use a local variable to track the Warrior, a Wait action to delay the Stop Defend order, and some kind of Condition to tell the WarriorDamaged1 trigger to not run again for this particular Warrior.

A Hashtable and/or Unit Indexing comes to mind for handling these effects.
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,894
I know this is a reply to an older post, but here we go:
The solution is to use SetUnitAnimationByIndex() which is a function unavailable in GUI that can play animations that won't get interrupted by movement. I'm pretty sure the animation still gets interrupted by attacks/spells though, but I could be wrong.
Adding and then removing "defend" animation tag is the solution.
 
Level 12
Joined
Oct 28, 2019
Messages
480
  • WarriorDamaged
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventTarget) Equal to Warrior
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 4) Equal to 1
          • (DamageEventTarget has buff Stunned (Pause)) Equal to False
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
          • Custom script: local unit u = udg_DamageEventTarget
          • Custom script: call SetUnitAnimationByIndex(u, 4)
          • Floating Text - Create floating text that reads |cff808080Block|r at (Position of DamageEventTarget) with Z offset 0.00, using font size 8.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
          • Wait 2.00 seconds
          • Custom script: call ResetUnitAnimation(u)
          • Custom script: set u = null
        • Else - Actions
          • Unit - Create 1 Bash Dummy for Neutral Passive at (Position of DamageEventTarget) facing Default building facing degrees
          • Unit - Add a 10.00 second Generic expiration timer to (Last created unit)
          • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt DamageEventTarget
1686945566118.png


What im going wrong
 
Level 20
Joined
Feb 27, 2019
Messages
593
You should use Animation - Add the defend animation tag to (unit) and Animation - Remove the defend animation tag to (unit) because it plays the defend animation even if the unit is walking.
 
Top