• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] When a unit is Attacked, the owner of unit loses Gold

Status
Not open for further replies.
Level 4
Joined
Dec 12, 2012
Messages
96
I'm trying to create a trigger that whenever a unit is attacked by GS_Hero (Gold Stealer), the owner of the attacked unit loses gold equivalent to the damage taken by the unit. So far my trigger ain't working. I think it's the variable where I set Event Response - Damage Taken but I'm not so sure.


  • Events
    • Unit - A unit Is attacked
  • Conditions
    • (Attacking unit) Equal to GS_Hero
  • Actions
    • Set GS_Attacker2 = GS_Hero
    • Set GS_Receiver2 = (Attacked unit)
    • Set GS_Owner = (Owner of GS_Receiver2)
    • Set GS_Dmg_Rec = (Damage taken)
    • Set GS_Dmg_Rec_int = (Integer(GS_Dmg_Rec))
    • Player - Set GS_Owner Current gold to ((GS_Owner Current gold) - GS_Dmg_Rec_int)
    • Floating Text - Create floating text that reads (- + ((String(GS_Dmg_Rec_int)) + Gold)) above GS_Receiver2 with Z offset -10.00, using font size 10.00, color (100.00%, 100.00%, 0.00%), and 10.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 fading age of (Last created floating text) to 1.00 seconds
    • Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds
 
Level 19
Joined
Feb 25, 2009
Messages
2,004
Your event fires when an attack begins, before any damage is taken.
You must use (<Unit> takes damage) event instead.

Also, you don't a separate integer for the conversion, it can be done in the "Player - Set GS_Owner Current gold to ((GS_Owner Current gold) - GS_Dmg_Rec_int)" call using Real to Integer conversion.

Since this is quite simple, you can remove most of the variables as they are not really that much required
or just simply use local ones as they won't take that much of memory.
 
Level 4
Joined
Dec 12, 2012
Messages
96
Your event fires when an attack begins, before any damage is taken.
You must use (<Unit> takes damage) event instead.
But this have to choose a specific unit on the map.

Also, you don't a separate integer for the conversion, it can be done in the "Player - Set GS_Owner Current gold to ((GS_Owner Current gold) - GS_Dmg_Rec_int)" call using Real to Integer conversion.

I had to convert real to integer since damage-taken is a real type and Player-set property is integer type. Right?
 
Level 16
Joined
Mar 27, 2011
Messages
1,349
But this have to choose a specific unit on the map.

Im fairly new to this point, however you need to look into a "Damage Detection System"

If you do not do this properly, a player can spam right click to attack an enemy and hit "S" to stop. Rapid spamming means this trigger is rapidly fired. People abuse this bug.
 
Level 4
Joined
Dec 12, 2012
Messages
96
Im fairly new to this point, however you need to look into a "Damage Detection System"

If you do not do this properly, a player can spam right click to attack an enemy and hit "S" to stop. Rapid spamming means this trigger is rapidly fired. People abuse this bug.

What is a damage detection system? And how do I use it? Is it by trigger?
 
Level 4
Joined
Dec 12, 2012
Messages
96

Kusanagi Kuro

Hosted Project: SC
Level 10
Joined
Mar 11, 2012
Messages
708
Well, I know someone have suggested that but u ask where u can find it so I just send the link. All the other information (included instructions) is inside that link too (its author has written it).
 
Level 4
Joined
Dec 12, 2012
Messages
96
Well, I know someone have suggested that but u ask where u can find it so I just send the link. All the other information (included instructions) is inside that link too (its author has written it).

Yeah, i'm pretty sure it'll come handy. Just didn't expect my idea will need a complex trigger :p thank you
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
aint this much better than a advanced trigger? ;)
  • Untitled Trigger 001
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Trigger - Add to Untitled Trigger 002 <gen> the event (Unit - (Picked unit) Takes damage)
  • Untitled Trigger 002
    • Events
    • Conditions
    • Actions
      • Set integer = (Integer((Damage taken)))
      • Game - Display to (All players) the text: (String(integer))
 
Level 4
Joined
Dec 12, 2012
Messages
96
aint this much better than a advanced trigger? ;)
  • Untitled Trigger 001
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Trigger - Add to Untitled Trigger 002 <gen> the event (Unit - (Picked unit) Takes damage)
  • Untitled Trigger 002
    • Events
    • Conditions
    • Actions
      • Set integer = (Integer((Damage taken)))
      • Game - Display to (All players) the text: (String(integer))


IT WORKEDDD!!!! OHHHHOOLLYYYYYY *#(&@#$$ =))) thanks man mwuah mwuah +rep haha

now i just need to set the variables of the damage source and damage taker.
 

Kusanagi Kuro

Hosted Project: SC
Level 10
Joined
Mar 11, 2012
Messages
708
aint this much better than a advanced trigger? ;)
  • Untitled Trigger 001
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Trigger - Add to Untitled Trigger 002 <gen> the event (Unit - (Picked unit) Takes damage)
  • Untitled Trigger 002
    • Events
    • Conditions
    • Actions
      • Set integer = (Integer((Damage taken)))
      • Game - Display to (All players) the text: (String(integer))

Sorry but this trigger wont work properly. Why? Because if there is an unit that is enter the map after the Map Intialization, the trigger wont work with it. U should put one more line in the first trigger. It is: Unit - Unit enters Playable area.

Maltheo: For ur question, if u use Damage Engine by Bribe, if u want to set the unit that deal damage as an variable, u will see the variable "DamageEventSource" in the Damage Engine. This variable saves the unit that deal damage. (Ahhhh, I cant explain it clearly). The damage taken will be "DamageEventAmount".
 
Level 4
Joined
Dec 12, 2012
Messages
96
@Hayaku Thanks man but I finally SOLVED it. :p

So far i only got 1 minor leak but it doesn't matter. It's not a big deal.

  • GS activate1
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Picked unit) Equal to GS_Hero
            • Then - Actions
              • Trigger - Add to GS when ATTACKED <gen> the event (Unit - (Picked unit) Takes damage)
            • Else - Actions
  • GS when ATTACKED
    • Events
    • Conditions
    • Actions
      • Set GS_Attacker2 = (Damage source)
      • Set GS_Owner = (Owner of GS_Attacker2)
      • Set GS_Dmg_Rec_int = (Integer((Damage taken)))
      • Player - Set GS_Owner Current gold to ((GS_Owner Current gold) + GS_Dmg_Rec_int)
      • Floating Text - Create floating text that reads (+ + ((String(GS_Dmg_Rec_int)) + Gold)) above GS_Attacker2 with Z offset -10.00, using font size 10.00, color (100.00%, 100.00%, 0.00%), and 10.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 fading age of (Last created floating text) to 1.00 seconds
      • Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds
  • GS activate2
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Attacking unit) Equal to GS_Hero
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Test_Int_A Equal to 0
        • Then - Actions
          • Trigger - Add to GS when ATTACKING <gen> the event (Unit - (Attacked unit) Takes damage)
        • Else - Actions
          • Set Test_Int_A = 0

  • GS when ATTACKING
    • Events
    • Conditions
      • (Damage source) Equal to GS_Hero
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Test_Int_A Equal to 0
        • Then - Actions
          • Set GS_Attacker3 = (Attacked unit)
          • Set GS_owner2 = (Owner of GS_Attacker3)
          • Set GS_Dmg_Rec_int2 = (Integer((Damage taken)))
          • Player - Set GS_owner2 Current gold to ((GS_owner2 Current gold) - GS_Dmg_Rec_int2)
          • Floating Text - Create floating text that reads (- + ((String(GS_Dmg_Rec_int2)) + Gold)) above GS_Attacker3 with Z offset -10.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 10.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 fading age of (Last created floating text) to 1.00 seconds
          • Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds
          • Game - Display to (All players) the text: (String(GS_Dmg_Rec_int2))
          • Set GS_Attacker3 = No unit
          • Set GS_owner2 = Neutral Passive
          • Set GS_Dmg_Rec_int2 = 0
          • Set Test_Int_A = 1
        • Else - Actions
 
Level 19
Joined
Feb 25, 2009
Messages
2,004
A unit needs to be registered only once, not everytime it is being attacked.

Yes, you don't need a separate integer for this thing:
  • Player - Add ((Player 1 (Red) Current gold) + (Integer((Damage taken)))) to Player 1 (Red) Current gold
The whole thing would look like this:


  • Init
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in (Playable map area) matching (((Matching unit) is A structure) Equal to False)) and do (Actions)
        • Loop - Actions
          • Trigger - Add to Gold Attack <gen> the event (Unit - (Picked unit) Takes damage)
      • Trigger - Turn on Check <gen>
      • Trigger - Turn on Gold Attack <gen>
  • Check
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is A structure) Equal to False
        • Then - Actions
          • Trigger - Add to Gold Attack <gen> the event (Unit - (Triggering unit) Takes damage)
        • Else - Actions
  • Gold Attack
    • Events
  • Conditions
    • And - All (Conditions) are true
      • Conditions
        • (Level of <Ability> for (Damage source)) Greater than 0
        • (Damage taken) Greater than 0.00
    • Actions
      • Player - Add (((Owner of (Damage source)) Current gold) + (Integer((Damage taken)))) to (Owner of (Damage source)) Current gold
      • Floating Text - Create floating text that reads (+ + (String((Integer((Damage taken)))))) above (Damage Source) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Floating Text - Show (Last created floating text) for (All players)
      • 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 2.00 seconds
      • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds


Replace <Ability> with the ability your Hero must have for this to work.

Also damage taken is not only considered from attacks, but from everything including spells and even items,
thus it can get pretty messy if you have some DoT spells which deal damage every 0.03 seconds.
 
Level 16
Joined
Mar 27, 2011
Messages
1,349
aint this much better than a advanced trigger? ;)
  • Untitled Trigger 001
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Trigger - Add to Untitled Trigger 002 <gen> the event (Unit - (Picked unit) Takes damage)
  • Untitled Trigger 002
    • Events
    • Conditions
    • Actions
      • Set integer = (Integer((Damage taken)))
      • Game - Display to (All players) the text: (String(integer))

Units are not removed from the "events". Does this being to leak (or build up in memory because it is not removed)?
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
@Chaosy
You forgot to register new unit that enters the map :)
You need to save 2 phase of the game;
1. Map Init
2. Unit enters map

This is how Damage Detection System is done.

Also, as others said, units don't get removed from the register when it dies OR not use anymore, causing a possible "leak" for the game to handle it throughout the entire game.

That is why you should not suggest the most primitive approach, because it would ruin other's experience.

Use Damage Detection System, please.
 
Level 4
Joined
Dec 12, 2012
Messages
96
Map initialization works but it only picks up the units present on that time the event occurred. Units that are then newly created are not included in the effect of the trigger. Hence, the effect of the trigger is limited.

Unit Enters Playable Map works but causes an increasing number of leaks as units are created. Multiple units entering the map regardless of owning player adds up to this event.

Time Periodic Event is more convenient than the other two since the leaks are not dependable on the units created but the game-time itself. But since periodic event doesn't allow a variable or feature that might enable the trigger to modify the game-time, this will be impossible unless I have a wider knowledge about GUI or JASS.

The best way I had so far was to use Unit is Attacked event. Though leaks here is also increasing per unit attacked, I have modified it to switch it on/off by using Integer 0 and 1 as conditions. I myself had a little trouble analyzing how this works. The minor leak is that when range units attack, two floating text appears, (1) is a normal damage inflicted (example: +10 Gold (2) is absolute 0 ( +0 Gold). But other than that, everything was okay.
I'm not sure if I've explained everything right or clearly but this is how I understood them so far. :)
 

Kusanagi Kuro

Hosted Project: SC
Level 10
Joined
Mar 11, 2012
Messages
708
^ IF u use Unit is attacked event, the owner will lose his gold even if the attack hasnt occured yet. I believe someone has told u that.
 
Level 4
Joined
Dec 12, 2012
Messages
96
^ IF u use Unit is attacked event, the owner will lose his gold even if the attack hasnt occured yet. I believe someone has told u that.

Fortunately it doesn't. The unit loses gold exactly at the time it receives damage. It seems like "Unit is attacked" equals "Unit takes damage". I don't know why or how but it magically works. :p
 

Kusanagi Kuro

Hosted Project: SC
Level 10
Joined
Mar 11, 2012
Messages
708
^ Weird. They arent equal. I'm sure about that. I have encountered that problem before. If I cancel the attack after giving the order, the owner will also lose gold.
 
Level 4
Joined
Dec 12, 2012
Messages
96
^ Weird. They arent equal. I'm sure about that. I have encountered that problem before. If I cancel the attack after giving the order, the owner will also lose gold.

I'll explain it briefly.

GS_Hero is a hero that when attacks, the owner of the attacked/targeted unit loses gold equivalent to the damage inflicted.

So you're saying that when I order GS_Hero to attack a unit (the targeted unit is my own unit), I should lose gold even before the unit gets hit, right? Well it doesn't work that way when I test the map. GS_Hero is a ranged unit, it subtracts gold at the same time it hits the unit. Even when I cancel the attack, I don't lose any gold.


  • GS activate2
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Attacking unit) Equal to GS_Hero
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Test_Int_A Equal to 0
        • Then - Actions
          • Trigger - Add to GS when ATTACKING <gen> the event (Unit - (Attacked unit) Takes damage)
        • Else - Actions
          • Set Test_Int_A = 0


  • GS when ATTACKING
    • Events
    • Conditions
      • (Damage source) Equal to GS_Hero
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Test_Int_A Equal to 0
        • Then - Actions
          • Set GS_Attacker3 = (Attacked unit)
          • Set GS_owner2 = (Owner of GS_Attacker3)
          • Set GS_Dmg_Rec_int2 = (Integer((Damage taken)))
          • Player - Set GS_owner2 Current gold to ((GS_owner2 Current gold) - GS_Dmg_Rec_int2)
          • Floating Text - Create floating text that reads (- + ((String(GS_Dmg_Rec_int2)) + Gold)) above GS_Attacker3 with Z offset -10.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 10.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 fading age of (Last created floating text) to 1.00 seconds
          • Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds
          • Game - Display to (All players) the text: (String(GS_Dmg_Rec_int2))
          • Set GS_Attacker3 = No unit
          • Set GS_owner2 = Neutral Passive
          • Set GS_Dmg_Rec_int2 = 0
          • Set Test_Int_A = 1
        • Else - Actions
 
Level 4
Joined
Dec 12, 2012
Messages
96
Oh. Sorry. I havent looked through ur trigger. I thought u set the event for the 2nd trigger is Unit is attacked. :D

You said "Unit is Attacked" and "Unit takes Damage" aren't equal. Probably they aren't but maybe they are in some ways. And it just so happens that they are both the same in my trigger. :D
 
Level 2
Joined
Dec 7, 2012
Messages
16
You said "Unit is Attacked" and "Unit takes Damage" aren't equal. Probably they aren't but maybe they are in some ways. And it just so happens that they are both the same in my trigger. :D

As far as I understand it, Unit takes Damage fires when the unit is damaged, which means for melee attacks it has to wait for the Animation - Damage Point of the attacking unit. Unit is Attacked, on the other hand, fires immediately. Edit: I have just tested for a ranged attack, at the Unit is Attacked triggers as soon as the projectile is created! This can be significantly before any damage is dealt.
 
Last edited:
Level 4
Joined
Dec 12, 2012
Messages
96
As far as I understand it, Unit takes Damage fires when the unit is damaged, which means for melee attacks it has to wait for the Animation - Damage Point of the attacking unit. Unit is Attacked, on the other hand, fires immediately. Edit: I have just tested for a ranged attack, at the Unit is Attacked triggers as soon as the projectile is created! This can be significantly before any damage is dealt.

True, I figured this out yesterday when I made a trigger that orders a certain building to cast big bad voodoo (with dummy) to make nearby units invulnerable when attacked. Apparently, the trigger works only when the unit's attack animation started and not when it is "ordered to attack".

However, in the trigger I've provided here has the same event (Unit is attacked) but it activates when it takes damage and not when the animation start, this is because I included the Damage Source as condition.

More likely:
Event: Unit is attacked + Condition: Damage Source = Event: Unit takes damage
 
Status
Not open for further replies.
Top