• 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.

[Solved] Help Needed for a Spell Targeting Units with "Can Rise, Does Decay" Properties and Black Arrow Spell

Level 2
Joined
Nov 27, 2021
Messages
10
Hello,

I want to create a spell that works on certain units—specifically, those that have the properties "can rise, does decay". Can any experts help me with this? I've tried many methods, but I haven't achieved any results.
 
Level 2
Joined
Nov 27, 2021
Messages
10
Thank you for your response. After extensive searching, I realized that there's no way to identify units based on the "can rise, does decay". So, I came up with the idea of putting all units with the "can't rise, doesn't decay" ability in an array and comparing this array with the unit that is to be targeted.

What I want to do is create a Black Arrow that raises skeletons based on the unit that dies. For instance, if the unit was melee, a skeleton warrior should rise, and if the unit was ranged, a skeleton archer should rise. Could you help me with this, please?
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,873
Also, Melee attacker and Ranged attacker can be accessed this way (I think these have been around forever):
  • Conditions
    • ((Dying unit) is A melee attacker) Equal to True
    • ((Dying unit) is A manged attacker) Equal to True
Anyway, one POSSIBLE solution would be to have a unique Dummy unit spawn from Black Arrow and detect that:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Set Variable Last_Dying_Unit = (Triggering unit)
  • Events
    • Unit - A unit Spawns a summoned unit
  • Conditions
    • (Unit-type of (Summoned unit)) Equal to Black Arrow Dummy
  • Actions
    • Set Variable Black_Arrow_Dummy = (Summoned unit)
    • Set Variable Black_Arrow_Point = (Position of Black_Arrow_Dummy)
    • Set Variable Black_Arrow_Is_Melee = (Last_Dying_Unit is A melee attacker)
    • -------- add more Conditions as needed --------
    • If all conditions are true then do (Actions)
      • If - Conditions
        • Black_Arrow_Is_Melee Equal to True
      • Then - Actions
        • Unit - Create 1 MELEE SKELE at Black_Arrow_Point for (Owner of Black_Arrow_Dummy)
      • Else - Actions
        • Unit - Create 1 RANGED SKELE at Black_Arrow_Point for (Owner of Black_Arrow_Dummy)
    • Custom script: call RemoveLocation( udg_Black_Arrow_Point )
    • Unit - Remove Black_Arrow_Dummy from the game
However, this is banking on the fact that the Events happen during the same frame and in the proper order (Death -> Summon). Otherwise, there could be room for error. I imagine it would be extremely rare though, and worst case it would simply summon the wrong kind of skeleton.
 
Level 2
Joined
Nov 27, 2021
Messages
10
If you are on newer patches, you should have access to 'Unit - Get Unit Boolean Field' function which allows you to detect what you want:
  • Set VariableSet canDecay = (Unit: <some unit>'s Boolean Field: Decayable ('udec'))
  • Set VariableSet canRaise = (Unit: <some unit>'s Boolean Field: Raisable ('urai'))
Unfortunately, I am using older versions and this function does not exist. Thanks again for the useful information.
 
Level 2
Joined
Nov 27, 2021
Messages
10
Also, Melee attacker and Ranged attacker can be accessed this way (I think these have been around forever):
  • Conditions
    • ((Dying unit) is A melee attacker) Equal to True
    • ((Dying unit) is A manged attacker) Equal to True
Anyway, one POSSIBLE solution would be to have a unique Dummy unit spawn from Black Arrow and detect that:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Set Variable Last_Dying_Unit = (Triggering unit)
  • Events
    • Unit - A unit Spawns a summoned unit
  • Conditions
    • (Unit-type of (Summoned unit)) Equal to Black Arrow Dummy
  • Actions
    • Set Variable Black_Arrow_Dummy = (Summoned unit)
    • Set Variable Black_Arrow_Point = (Position of Black_Arrow_Dummy)
    • Set Variable Black_Arrow_Is_Melee = (Last_Dying_Unit is A melee attacker)
    • -------- add more Conditions as needed --------
    • If all conditions are true then do (Actions)
      • If - Conditions
        • Black_Arrow_Is_Melee Equal to True
      • Then - Actions
        • Unit - Create 1 MELEE SKELE at Black_Arrow_Point for (Owner of Black_Arrow_Dummy)
      • Else - Actions
        • Unit - Create 1 RANGED SKELE at Black_Arrow_Point for (Owner of Black_Arrow_Dummy)
    • Custom script: call RemoveLocation( udg_Black_Arrow_Point )
    • Unit - Remove Black_Arrow_Dummy from the game
However, this is banking on the fact that the Events happen during the same frame and in the proper order (Death -> Summon). Otherwise, there could be room for error. I imagine it would be extremely rare though, and worst case it would simply summon the wrong kind of skeleton.
Thanks for the solution you provided. It's a very interesting method, but as you mentioned, there is a chance of error, and sometimes no skeleton is summoned at all. Do you think it's possible to make changes to the event when a unit dies? For example, could it be saved when a unit with the Black Arrow buff dies, or when a unit dies due to the caster of Black Arrow, or something similar? Wouldn't this reduce the error rate??
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,873
Thanks for the solution you provided. It's a very interesting method, but as you mentioned, there is a chance of error, and sometimes no skeleton is summoned at all. Do you think it's possible to make changes to the event when a unit dies? For example, could it be saved when a unit with the Black Arrow buff dies, or when a unit dies due to the caster of Black Arrow, or something similar? Wouldn't this reduce the error rate??
I recommend posting your triggers before we jump to the solutions listed below. I'll also see if I can get it working consistently in a test map.

Alternate solutions:
The main issue is that the buff is removed prior to the "A unit Dies" event, so you cannot detect it then. An alternate solution would be to use a Damage Engine to detect lethal damage since you can still check for buffs at that stage. Another would be a Damage Engine to detect when a unit takes damage and then check for the buff, if found, track the unit in a Unit Group until it loses the buff or dies. If it dies then spawn a skeleton.

Edit: Okay, I finished testing and found some fixes. Here's a basic setup that seems to work 100% of the time:
  • BA Any Unit Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is Mechanical) Equal to False
    • Actions
      • Set VariableSet BA_Last_Dying_Unit = (Triggering unit)
  • BA Dummy Spawns
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Black Arrow Dummy
    • Actions
      • Set VariableSet BA_Buff_Source = (Triggering unit)
      • Set VariableSet BA_Point = (Position of BA_Buff_Source)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (BA_Last_Dying_Unit is A melee attacker) Equal to True
        • Then - Actions
          • Unit - Create 1 Skeleton Warrior for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
        • Else - Actions
          • Unit - Create 1 Skeletal Mage for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
      • Set VariableSet BA_Last_Dying_Unit = No unit
      • Custom script: call RemoveLocation( udg_BA_Point )
Note the new Condition in the death trigger and the change of Event for the spawn trigger. I classified the Dummy unit as Mechanical so it wouldn't run the death trigger. I also made it so the Dummy unit uses it's timed life from the Black Arrow ability which I set to 0.10 seconds, this way we don't have to remove it manually.

Here's a setup that solves the POTENTIAL issue where the Death event fires AFTER the Enters event. Note that in my 5 tests this never happened once:
  • BA Any Unit Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is Mechanical) Equal to False
    • Actions
      • Set VariableSet BA_Last_Dying_Unit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BA_Waiting_To_Spawn Greater than 0
        • Then - Actions
          • Set VariableSet BA_Buff_Source = (Killing unit)
          • Set VariableSet BA_Point = (Position of BA_Last_Dying_Unit)
          • Trigger - Run BA Create Skeleton <gen> (ignoring conditions)
        • Else - Actions
  • BA Dummy Spawns
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Black Arrow Dummy
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BA_Last_Dying_Unit Equal to No unit
        • Then - Actions
          • Set VariableSet BA_Waiting_To_Spawn = (BA_Waiting_To_Spawn + 1)
        • Else - Actions
          • Set VariableSet BA_Buff_Source = (Triggering unit)
          • Set VariableSet BA_Point = (Position of BA_Buff_Source)
          • Trigger - Run BA Create Skeleton <gen> (ignoring conditions)
  • BA Create Skeleton
    • Events
    • Conditions
    • Actions
      • Set VariableSet BA_Waiting_To_Spawn = (BA_Waiting_To_Spawn - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (BA_Last_Dying_Unit is A melee attacker) Equal to True
        • Then - Actions
          • Unit - Create 1 Skeleton Warrior for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
        • Else - Actions
          • Unit - Create 1 Skeletal Mage for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
      • Custom script: call RemoveLocation( udg_BA_Point )
      • Set VariableSet BA_Last_Dying_Unit = No unit

The attached map requires the latest patch to open.
 

Attachments

  • Custom Black Arrow 1.w3m
    19.9 KB · Views: 5
Last edited:
Level 2
Joined
Nov 27, 2021
Messages
10
I recommend posting your triggers before we jump to the solutions listed below. I'll also see if I can get it working consistently in a test map.

Alternate solutions:
The main issue is that the buff is removed prior to the "A unit Dies" event, so you cannot detect it then. An alternate solution would be to use a Damage Engine to detect lethal damage since you can still check for buffs at that stage. Another would be a Damage Engine to detect when a unit takes damage and then check for the buff, if found, track the unit in a Unit Group until it loses the buff or dies. If it dies then spawn a skeleton.

Edit: Okay, I finished testing and found some fixes. Here's a basic setup that seems to work 100% of the time:
  • BA Any Unit Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is Mechanical) Equal to False
    • Actions
      • Set VariableSet BA_Last_Dying_Unit = (Triggering unit)
  • BA Dummy Spawns
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Black Arrow Dummy
    • Actions
      • Set VariableSet BA_Buff_Source = (Triggering unit)
      • Set VariableSet BA_Point = (Position of BA_Buff_Source)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (BA_Last_Dying_Unit is A melee attacker) Equal to True
        • Then - Actions
          • Unit - Create 1 Skeleton Warrior for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
        • Else - Actions
          • Unit - Create 1 Skeletal Mage for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
      • Set VariableSet BA_Last_Dying_Unit = No unit
      • Custom script: call RemoveLocation( udg_BA_Point )
Note the new Condition in the death trigger and the change of Event for the spawn trigger. I classified the Dummy unit as Mechanical so it wouldn't run the death trigger. I also made it so the Dummy unit uses it's timed life from the Black Arrow ability which I set to 0.10 seconds, this way we don't have to remove it manually.

Here's a setup that solves the POTENTIAL issue where the Death event fires AFTER the Enters event. Note that in my 5 tests this never happened once:
  • BA Any Unit Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is Mechanical) Equal to False
    • Actions
      • Set VariableSet BA_Last_Dying_Unit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BA_Waiting_To_Spawn Greater than 0
        • Then - Actions
          • Set VariableSet BA_Buff_Source = (Killing unit)
          • Set VariableSet BA_Point = (Position of BA_Last_Dying_Unit)
          • Trigger - Run BA Create Skeleton <gen> (ignoring conditions)
        • Else - Actions
  • BA Dummy Spawns
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Black Arrow Dummy
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BA_Last_Dying_Unit Equal to No unit
        • Then - Actions
          • Set VariableSet BA_Waiting_To_Spawn = (BA_Waiting_To_Spawn + 1)
        • Else - Actions
          • Set VariableSet BA_Buff_Source = (Triggering unit)
          • Set VariableSet BA_Point = (Position of BA_Buff_Source)
          • Trigger - Run BA Create Skeleton <gen> (ignoring conditions)
  • BA Create Skeleton
    • Events
    • Conditions
    • Actions
      • Set VariableSet BA_Waiting_To_Spawn = (BA_Waiting_To_Spawn - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (BA_Last_Dying_Unit is A melee attacker) Equal to True
        • Then - Actions
          • Unit - Create 1 Skeleton Warrior for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
        • Else - Actions
          • Unit - Create 1 Skeletal Mage for (Owner of BA_Buff_Source) at BA_Point facing Default building facing degrees
      • Custom script: call RemoveLocation( udg_BA_Point )
      • Set VariableSet BA_Last_Dying_Unit = No unit

The attached map requires the latest patch to open.
I tested the first method and found that it works 100% without any issues.
The solutions you provided are so complete and excellent that there's no need for me to share my own triggers. I appreciate the time and effort you put into resolving my issue. My problem has been resolved. Thank you, master.
 
Top