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

[Trigger] Hex on attack,need help

Level 2
Joined
Dec 8, 2023
Messages
9
Hello, friends!

I made a skill in which when hero attacks, he has a chance to hex the target. it works but sometimes my units randomly gets hexed. is this

THIS IS CONFIG
  • Wukongs Mischief config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked player) slot status) Equal to Is playing
            • Then - Actions
              • Unit - Create 1 illusion caster wukong for (Picked player) at (Center of (Playable map area)) facing Default building facing degrees
              • Set WukongsMischiefcasterunit[(Player number of (Picked player))] = (Last created unit)
              • Animation - Change WukongsMischiefcasterunit[(Player number of (Picked player))]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 100.00% transparency
              • Hero - Create Wukong's Staff of Illusions wukong's mischief and give it to WukongsMischiefcasterunit[(Player number of (Picked player))]
            • Else - Actions
              • Do nothing
THIS IS THE SKILL
  • Wukongs Mischief hex effect
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • Set WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] = (Random integer number between 1 and 100)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Unit-type of (Attacking unit)) Equal to Monkey King
              • (Level of Wukong's Mischief - Hex monkey king for (Attacking unit)) Equal to 1
              • WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] Less than or equal to 5
        • Then - Actions
          • Unit - Order WukongsMischiefcasterunit[(Player number of (Owner of (Attacking unit)))] to Orc Shadow Hunter - Hex (Attacked unit)
          • Set WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] = 0
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • (Unit-type of (Attacking unit)) Equal to Monkey King
                  • (Level of Wukong's Mischief - Hex monkey king for (Attacking unit)) Equal to 2
                  • WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] Less than or equal to 10
            • Then - Actions
              • Unit - Order WukongsMischiefcasterunit[(Player number of (Owner of (Attacking unit)))] to Orc Shadow Hunter - Hex (Attacked unit)
              • Set WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] = 0
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • (Unit-type of (Attacking unit)) Equal to Monkey King
                      • (Level of Wukong's Mischief - Hex monkey king for (Attacking unit)) Equal to 3
                      • WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] Less than or equal to 15
                • Then - Actions
                  • Unit - Order WukongsMischiefcasterunit[(Player number of (Owner of (Attacking unit)))] to Orc Shadow Hunter - Hex (Attacked unit)
                  • Set WukongsMischiefhexinteger[(Player number of (Owner of (Attacking unit)))] = 0
                • Else - Actions
                  • Do nothing
 
Last edited by a moderator:

Uncle

Warcraft Moderator
Level 66
Joined
Aug 10, 2018
Messages
6,744
Hello, if you want this to work properly you should be relying on a Damage Engine to detect when your Hero deals damage to the target. You'll need to find an older version that is compatible with the patch that you're on.

This is because the "A unit is attacked" Event occurs before the unit even begins swinging it's weapon. It's a very misleading Event, it should really be called "A unit BEGINS an attack". The big issue here is that you can cancel this attack on command and as a result immediately try to attack again. You can test this in-game, let your hero autoattack a nearby unit and spam the Stop button. You'll see that this trigger runs 10+ times per second regardless of your attack speed and regardless of whether you actually dealt any attack damage.

Also, you're making some other mistakes in your triggers:
1) You don't need a special Dummy unit for each Player.
2) You don't need to use And - All (Conditions) are true, that's the default behavior of Conditions.
3) You don't need to use Do nothing, it's no different from a comment.
4) You don't need to use an Array for WukongsMischiefhexinteger, this variable doesn't suffer from any MUI issues and doesn't need to be tracked over time or on a per-Player basis. There's no reason to reset it back to 0 either.
5) You don't need to make so many redundant checks in your hex effect trigger. Simply confirm that it's the Monkey King dealing the damage in the main Conditions block, then roll some dice based on the level of the hero's ability, and proceed from there.

Here's an example of how you can make your triggers a lot more efficient, clean, and expandable:
  • Mischief Config
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • -------- Define the chance per level that the hex will occur: --------
      • Set Mischief_Chance_Per_Lvl[1] = 5
      • Set Mischief_Chance_Per_Lvl[2] = 10
      • Set Mischief_Chance_Per_Lvl[3] = 15
  • Mischief Hex
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Unit-type of (Attacking unit)) Equal to Monkey King
      • ((Attacked unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True
    • Actions
      • Set Mischief_Lvl = (Level of Wukong's Mischief for (Attacking unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Mischief_Lvl Greater than 0
        • Then - Actions
          • Set Mischief_Roll = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Mischief_Roll Less than or equal to Mischief_Chance_Per_Lvl[Mischief_Lvl]
            • Then - Actions
              • Set Mischief_Point = (Position of (Attacked unit))
              • Unit - Create 1 Dummy for (Owner of (Attacking unit)) at Mischief_Point facing Default building facing degrees
              • Custom script: call RemoveLocation( udg_Mischief_Point )
              • Set Mischief_Dummy = (Last created unit)
              • Unit - Add a 0.20 second Generic expiration timer to Mischief_Dummy
              • Unit - Add Hex (Wukong) to Mischief_Dummy
              • Unit - Set level of Hex (Wukong) for Mischief_Dummy to Mischief_Lvl
              • Unit - Order Mischief_Dummy to Orc Shadow Hunter - Hex (Attacked unit)
            • Else - Actions
        • Else - Actions
If you implement the Damage Engine then the above trigger will need to be changed. All you have to do is switch out the Event and Event Responses to use the variables provided by the system: A unit Is attacked = DamageEvent becomes equal to 1.00, (Attacking unit) = DamageEventSource, (Attacked unit) = DamageEventTarget.

Also, make sure that you've created your Dummy unit exactly like this:
Step 1) Copy and paste the Locust. (Undead - Special unit)
Step 2) Set it's Model = None, Shadow = None, Attacks Enabled = None, Movement Type = None, and Speed Base = 0.

A lot of people have improper Dummy units that actually have a delay before they cast their spells due to bad settings. With these settings, the Dummy unit can cast spells "instantly" without needing to turn to face it's target. It also allows you to order a single one of these Dummy units to cast multiple spells at once (an AoE Hex for example). Also, you can reuse this same type of Dummy throughout all of your triggers, there's no need to create a new Unit-Type each time.

Lastly, if you're interested in optimizing Dummy usage, which your Config trigger implies, you could look up Dummy recycling systems. The idea is that each Player has their own personal re-usable Dummy unit that you can call on command. But I don't think this is all that necessary and it could be a pain to use in GUI.
 
Last edited:
Level 2
Joined
Dec 8, 2023
Messages
9
Hello, if you want this to work properly you should be relying on a Damage Engine to detect when your Hero deals damage to the target. You'll need to find an older version that is compatible with the patch that you're on.

Anyway, the "A unit is attacked" Event occurs before the unit even begins swinging it's weapon. It's a very misleading Event, it should really be called "A unit BEGINS an attack". The big issue here is that you can cancel this attack whenever you want and then immediately try to attack again. You can test this in-game, let your hero autoattack a nearby unit and spam the Stop button. You'll see that this trigger runs 10+ times per second regardless of your attack speed and regardless of whether you actually dealt any damage.

Also, you're making some other mistakes:
1) You don't need a special Dummy unit for each Player.
2) You don't need to use And - All (Conditions) are true, that's the default behavior of Conditions.
3) You don't need to use Do nothing, it's no different from a comment.
4) You don't need to use an Array for WukongsMischiefhexinteger, this variable doesn't suffer from any MUI issues and doesn't need to be tracked over time or on a per-Player basis. There's no reason to reset it back to 0 either.
5) You don't need to make so many redundant checks in your hex effect trigger. Simply confirm that it's the Monkey King dealing the damage in the main Conditions block, then roll some dice based on the level of the Hex ability, and proceed from there.

Here's an example of how you can make your triggers a lot more efficient, clean, and expandable:
  • Mischief Config
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • -------- Define the chance per level that the hex will occur: --------
      • Set Mischief_Chance_Per_Lvl[1] = 5
      • Set Mischief_Chance_Per_Lvl[2] = 10
      • Set Mischief_Chance_Per_Lvl[3] = 15
  • Mischief Hex
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Unit-type of (Attacking unit)) Equal to Monkey King
      • ((Attacked unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True
    • Actions
      • Set Mischief_Lvl = (Level of Wukong's Mischief for (Attacking unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Mischief_Lvl Greater than 0
        • Then - Actions
          • Set Mischief_Roll = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Mischief_Roll Less than or equal to Mischief_Chance_Per_Lvl[Mischief_Lvl]
            • Then - Actions
              • Set Mischief_Point = (Position of (Attacked unit))
              • Unit - Create 1 Dummy for (Owner of (Attacking unit)) at Mischief_Point facing Default building facing degrees
              • Custom script: call RemoveLocation( udg_Mischief_Point )
              • Set Mischief_Dummy = (Last created unit)
              • Unit - Add a 0.20 second Generic expiration timer to Mischief_Dummy
              • Unit - Add Hex (Wukong) to Mischief_Dummy
              • Unit - Set level of Hex (Wukong) for Mischief_Dummy to Mischief_Lvl
              • Unit - Order Mischief_Dummy to Orc Shadow Hunter - Hex (Attacked unit)
            • Else - Actions
        • Else - Actions
If you implement the Damage Engine then the above trigger will need to be changed. All you have to do is switch out the Event and Event Responses to use the variables provided by the system: A unit Is attacked = DamageEvent becomes equal to 1.00, (Attacking unit) = DamageEventSource, (Attacked unit) = DamageEventTarget.

Also, make sure that you've created your Dummy unit exactly like this:
Step 1) Copy and paste the Locust. (Undead - Special unit)
Step 2) Set it's Model = None, Shadow = None, Attacks Enabled = None, Movement Type = None, and Speed Base = 0.

This Dummy unit can cast spells "instantly" without needing to turn to face it's target. A lot of people have improper Dummy units that actually have a delay before they cast their spells due to bad settings. This also allows you to order a single one of these Dummy units to cast multiple spells at once (AoE Hex for example). Also, you can reuse this same type of Dummy throughout all of your triggers, there's no need to create a new Unit-Type each time.

But if you're interested in optimizing Dummy usage, look up Dummy recycling systems. The idea is that each Player has 1 re-usable Dummy unit. But I really don't think it matters all that much and it could be a pain to use in GUI.
Wow! i really thought it can still be optimized but not to this degree. this is just, as you said, very clean, brief and efficient. you've always been such a great help Uncle. Thank you very much. I was also thinking of just creating the dummy on attack instead of the way i made it but thought it might lag lol that's why it's like that haha. Also i did notice the error with the A Unit is ATTACKED event in some other trigger, unfortunately i don't understand the damage engine thingy that's why i only rely on the Attack Event. Anyway, thanks again! Have a great day!
 

Uncle

Warcraft Moderator
Level 66
Joined
Aug 10, 2018
Messages
6,744
The real difficult part is finding a Damage Engine that is compatible since you aren't using the latest patch of Warcraft 3. Luckily, Damage Engine has been around for a while and should have a version for you. You can probably find it here:

Once you find an openable map of Damage Engine, you simply open the Trigger Editor and copy the folder containing all of it's triggers (ignore anything that says Demo as that's meant for demonstration purposes and isn't needed). There may be a custom ability to copy from the Object Editor as well. Then you open your own map and paste these into the correct places. Once that's done, you select the Config trigger that comes with the system and read the instructions inside, it's all explained in great detail. There's not much to do there besides assigning a variable or two.

After that you should be all finished and the system will run automatically when you play your map. However, you of course need to learn how to USE the system.

Here's the Hex trigger from before but using the Damage Engine:
  • Mischief Hex
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Monkey King
      • (DamageEventTarget belongs to an enemy of (Owner of DamageEventSource) Equal to True
    • Actions
      • Set Mischief_Lvl = (Level of Wukong's Mischief for DamageEventSource)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Mischief_Lvl Greater than 0
        • Then - Actions
          • Set Mischief_Roll = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Mischief_Roll Less than or equal to Mischief_Chance_Per_Lvl[Mischief_Lvl]
            • Then - Actions
              • Set Mischief_Point = (Position of DamageEventTarget)
              • Unit - Create 1 Dummy for (Owner of DamageEventSource) at Mischief_Point facing Default building facing degrees
              • Custom script: call RemoveLocation( udg_Mischief_Point )
              • Set Mischief_Dummy = (Last created unit)
              • Unit - Add a 0.20 second Generic expiration timer to Mischief_Dummy
              • Unit - Add Hex (Wukong) to Mischief_Dummy
              • Unit - Set level of Hex (Wukong) for Mischief_Dummy to Mischief_Lvl
              • Unit - Order Mischief_Dummy to Orc Shadow Hunter - Hex DamageEventTarget
            • Else - Actions
        • Else - Actions
Note the new Event and how I changed (Attacked unit) and (Attacking unit) to use the DamageEvent variables provided by the system.

DamageEvent becomes Equal to 1.00 = This is a custom Event that runs when a unit takes damage.
DamageEventSource = The source of the damage. So the unit that dealt the damage.
DamageEventTarget = The target of the damage. So the unit that took the damage.

Note that the damage at this stage hasn't actually been dealt yet and can be modified. This is done using a Real variable called DamageEventAmount. For example, let's add 50.00 bonus damage:
  • Set DamageEventAmount = (DamageEventAmount + 50.00)
So if the Monkey King dealt 25 damage to an enemy Ghoul, it's now going to deal 25.00 + 50.00 = 75 total damage.

The system has a million other variables, which I realize is intimidating, but that's only because there's A LOT of different things that you can do with it. Understand that most of the time you only need the above Event and those 3-4 variables to achieve what you want.
 
Last edited:
Level 2
Joined
Dec 8, 2023
Messages
9
The real difficult part is finding a Damage Engine that is compatible since you aren't using the latest patch of Warcraft 3. Luckily, Damage Engine has been around for a while and should have a version for you. You can probably find it here:

Once you find an openable map of Damage Engine, you simply open the Trigger Editor and copy the folder containing all of it's triggers (ignore anything that says Demo as that's meant for demonstration purposes and isn't needed). There may be a custom ability to copy from the Object Editor as well. Then you open your own map and paste these into the correct places. Once that's done, you select the Config trigger that comes with the system and read the instructions inside, it's all explained in great detail. There's not much to do there besides assigning a variable or two.

After that you should be all finished and the system will run automatically when you play your map. However, you of course need to learn how to USE the system.

Here's the Hex trigger from before but using the Damage Engine:
  • Mischief Hex
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Monkey King
      • (DamageEventTarget belongs to an enemy of (Owner of DamageEventSource) Equal to True
    • Actions
      • Set Mischief_Lvl = (Level of Wukong's Mischief for DamageEventSource)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Mischief_Lvl Greater than 0
        • Then - Actions
          • Set Mischief_Roll = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Mischief_Roll Less than or equal to Mischief_Chance_Per_Lvl[Mischief_Lvl]
            • Then - Actions
              • Set Mischief_Point = (Position of DamageEventTarget)
              • Unit - Create 1 Dummy for (Owner of DamageEventSource) at Mischief_Point facing Default building facing degrees
              • Custom script: call RemoveLocation( udg_Mischief_Point )
              • Set Mischief_Dummy = (Last created unit)
              • Unit - Add a 0.20 second Generic expiration timer to Mischief_Dummy
              • Unit - Add Hex (Wukong) to Mischief_Dummy
              • Unit - Set level of Hex (Wukong) for Mischief_Dummy to Mischief_Lvl
              • Unit - Order Mischief_Dummy to Orc Shadow Hunter - Hex DamageEventTarget
            • Else - Actions
        • Else - Actions
Note the new Event and how I changed (Attacked unit) and (Attacking unit) to use the DamageEvent variables provided by the system.

DamageEvent becomes Equal to 1.00 = This is a custom Event that runs when a unit takes damage.
DamageEventSource = The source of the damage. So the unit that dealt the damage.
DamageEventTarget = The target of the damage. So the unit that took the damage.

Note that the damage at this stage hasn't actually been dealt yet and can be modified. This is done using a Real variable called DamageEventAmount. For example, let's add 50.00 bonus damage:
  • Set DamageEventAmount = (DamageEventAmount + 50.00)
So if the Monkey King dealt 25 damage to an enemy Ghoul, it's now going to deal 25.00 + 50.00 = 75 total damage.

The system has a million other variables, which I realize is intimidating, but that's only because there's A LOT of different things that you can do with it. Understand that most of the time you only need the above Event and those 3-4 variables to achieve what you want.
I learned a lot from you, but i still need to study these damage engines. I will implement these suggestions and look into these damage engines to see what other modifications can be made. Again, thank you very much! I hope you are doing well.
 

Uncle

Warcraft Moderator
Level 66
Joined
Aug 10, 2018
Messages
6,744
No problem, and try not to overthink it too much, the Damage Engine is simply some code that gives you access to this Event:
  • Events
    • Unit - A unit Takes damage
^ The standard Trigger Editor doesn't have access to this Event on older patches.

The system also has extra features for making this Event easier to work with.
 
Level 2
Joined
Dec 8, 2023
Messages
9
No problem, and try not to overthink it too much, the Damage Engine is simply some code that gives you access to this Event:
  • Events
    • Unit - A unit Takes damage
^ The standard Trigger Editor doesn't have access to this Event on older patches.

The system also has extra features for making this Event easier to work with.
Noted.
 
Level 2
Joined
Dec 8, 2023
Messages
9
No problem, and try not to overthink it too much, the Damage Engine is simply some code that gives you access to this Event:
  • Events
    • Unit - A unit Takes damage
^ The standard Trigger Editor doesn't have access to this Event on older patches.

The system also has extra features for making this Event easier to work with.
This is in relation to the ability above. I have another ability that makes it so that "When Wukong is attacked" there is a chance to create an illusion. The problem is that the illusion ability is not in the "Issue order targeting a unit action" which means i have to make an item for a dummy to use. This is also a reason, I forgot to mention, why I have to make the dummies for each player the way i did above. because if i don't and use the "Create unit" each time it is triggered, there are times where an item is created that should be given to the dummy but instead left on the ground. How do i go about this, Uncle?
 

Uncle

Warcraft Moderator
Level 66
Joined
Aug 10, 2018
Messages
6,744
This is in relation to the ability above. I have another ability that makes it so that "When Wukong is attacked" there is a chance to create an illusion. The problem is that the illusion ability is not in the "Issue order targeting a unit action" which means i have to make an item for a dummy to use. This is also a reason, I forgot to mention, why I have to make the dummies for each player the way i did above. because if i don't and use the "Create unit" each time it is triggered, there are times where an item is created that should be given to the dummy but instead left on the ground. How do i go about this, Uncle?
If an Order is missing from the standard Trigger Editor, know that it does still exist but you have to reference it through code:
  • Set Hero = (Your unit)
  • Unit - Create 1 Dummy for (Owner of Hero) at (Position of Hero) facing Default building facing degrees
  • Set Dummy = (Last created unit)
  • Unit - Add a 0.20 second Generic expiration timer to Dummy
  • Unit - Add Wand of Illusion (Monkey King) to Dummy
  • Custom script: call IssueTargetOrderById(udg_Dummy, 852274, udg_Hero)
You can find the Order Id by googling around, plus Hiveworkshop has many threads answering this question already.
 
Level 2
Joined
Dec 8, 2023
Messages
9
If an Order is missing from the standard Trigger Editor, know that it does still exist but you have to reference it through code:
  • Set Hero = (Your unit)
  • Unit - Create 1 Dummy for (Owner of Hero) at (Position of Hero) facing Default building facing degrees
  • Set Dummy = (Last created unit)
  • Unit - Add a 0.20 second Generic expiration timer to Dummy
  • Unit - Add Wand of Illusion (Monkey King) to Dummy
  • Custom script: call IssueTargetOrderById(udg_Dummy, 852274, udg_Hero)
You can find the Order Id by googling around, plus Hiveworkshop has many threads answering this question already.
Hello, Uncle. The world is so big that things like these I don't even know where to look, much less find. So I always don't know what to do or where to go and always gets stuck. Noob alert lol. But, since you mentioned it, i will try to scour the Hive even more. I guess there are more hidden gems to find. Thanks again, Uncle! Your help is greatly appreciated.
 
Level 40
Joined
Feb 27, 2007
Messages
5,137
You can create a trigger to learn the integer order id of any issued order, then test doing the thing you want to find the order of.
  • Events
    • Unit - A unit is issued an order with no target
    • Unit - A unit is issued an order targeting a unit
    • Unit - A unit is issued an order targeting a location
  • Conditions
  • Actions
    • Custom script: call BJDebugMsg(I2S(GetIssuedOrderId()))
 
Level 2
Joined
Dec 8, 2023
Messages
9
You can create a trigger to learn the integer order id of any issued order, then test doing the thing you want to find the order of.
  • Events
    • Unit - A unit is issued an order with no target
    • Unit - A unit is issued an order targeting a unit
    • Unit - A unit is issued an order targeting a location
  • Conditions
  • Actions
    • Custom script: call BJDebugMsg(I2S(GetIssuedOrderId()))
Ohhhh, thanks for this! It's helpful! Thank you all for all your help @Uncle and Pyrogasm!
 
Top