• 🏆 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] Vengeful Spirit

Status
Not open for further replies.
Level 3
Joined
Mar 15, 2020
Messages
48
The idea for this spell is as follows: hero casts a target unit ability on an enemy unit, it creates a unit and it uses a leveled Orc Batrider - Unstable Concoction on it.

So far, so good. However, with the hero's ultimate ability it'll create one extra spirit per level to charge at a random enemy unit in the area if there is one nearby.

I've managed to make it work to some extent, but as it stands now the extra spirits sometimes seek out the same target and fail to execute their order correctly, forcing them to expire after the expiration timer is up.

  • W Vengeful Spirit
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Vengeful Spirit (Rothin)
    • Actions
      • Set VariableSet tempPoint = (Position of (Triggering unit))
      • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
      • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Target unit of ability being cast)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Soul Conduit (Rothin) for (Triggering unit)) Greater than 0
        • Then - Actions
          • Set VariableSet VengefulSpirit_Count = (Level of Soul Conduit (Rothin) for (Triggering unit))
          • Set VariableSet VengefulSpirit_Group = (Random VengefulSpirit_Count units from (Units within 900.00 of tempPoint matching ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True) and (((Matching unit) is alive) Equal to True)).))
          • Unit Group - Pick every unit in (Random VengefulSpirit_Count units from VengefulSpirit_Group) and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
              • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
              • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
              • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Picked unit)
        • Else - Actions
      • Custom script: call RemoveLocation (udg_tempPoint )
      • Custom script: call DestroyGroup (udg_VengefulSpirit_Group )
I'm looking to make it so that if say 20 units are nearby and the Soul Conduit's level is 10, it'll create 10 extra spirits and randomly select individual targets to charge, excluding the unit initially targeted.
 
Last edited:
Level 20
Joined
Aug 13, 2013
Messages
1,696
There's no group traversal going on here, you should use Unit Group - Loop GUI action and replace 'random unit' with picked unit inside of it. You may also exclude dead units to be filtered in the enumeration.

EDIT:

And you can also ignore a separated action for the target as it's already included in the group.

EDIT:

It looks like you've edited your script and matches the first paragraph I've just mentioned earlier.
Now do the part which requires you to remove the actions you just made for the targeted unit.
Oh, the target should be excluded from the enumeration instead.
(Matching Unit) not equal to (Targeted Unit) so just ignore the strikethrough.
In this way, the ability could also work without Soul Conduit ability leveled.

EDIT:

Also use the unit group variable you've just created inside the 'Pick Every' GUI function.
So it should be 'Unit Group - Pick every unit in VengefulSpirit_Group...' and move the destroy group custom script inside the 'if - then' block.
 
Last edited:
Level 3
Joined
Mar 15, 2020
Messages
48
Much appreciated for the quick response! It's definitely a lot smoother now. This is what my setup is looking like now.

  • W Vengeful Spirit
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Vengeful Spirit (Rothin)
    • Actions
      • Set VariableSet tempPoint = (Position of (Triggering unit))
      • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
      • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Target unit of ability being cast)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Soul Conduit (Rothin) for (Triggering unit)) Greater than 0
        • Then - Actions
          • Set VariableSet VengefulSpirit_Count = (Level of Soul Conduit (Rothin) for (Triggering unit))
          • Set VariableSet VengefulSpirit_Group = (Random VengefulSpirit_Count units from (Units within 900.00 of tempPoint matching ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((Matching unit) Not equal to (Targe
          • Unit Group - Pick every unit in VengefulSpirit_Group and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
              • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
              • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
              • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Picked unit)
          • Custom script: call DestroyGroup (udg_VengefulSpirit_Group )
        • Else - Actions
      • Custom script: call RemoveLocation (udg_tempPoint )
When Soul Conduit is at level 10 this should target 11 units in total when including the main target. So I placed down 11 Acolytes and tested it out but only 10 get damaged.
They're all enemies of the caster and alive.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Display the value of VengefulSpirit_Count in-game just to ensure: If 10 is printed out, it looks like the target is already counted by the function and the total count is decreased by the matching condition or with something else. If that's so you may need to separate the unit groups into two. One for the filtration and the other for randomization, to establish the filters before randomizing it.

EDIT:

(Demo)
Set Group_Filtration = Units within X range of point with matching conditions.
Set Group_Randomization = Random Y count from Group_Filtration.
Pick every unit in Group_Randomization and do multiple actions...
call DestroyGroup(udg_Group_Filtration)
call DestroyGroup(udg_Group_Randomization)

Note that only do this if the variable VengefulSpirit_Count displays a correct value which is 10.
In case you don't know the GUI function for displaying text: it is 'Game - Text Message'
Find this action and do string to integer conversion to display VengefulSpirit_Count value in-game.

Otherwise, if the problem persists, it might be something else that would require me
to test & debug this function whenever I have my available time to face the editor.
 
Last edited:
Level 3
Joined
Mar 15, 2020
Messages
48
As you predicted the shown integer number is indeed 10. I followed your suggestion but the problem persists.

I made an observation, though I'm not entirely sure how accurate it is; it seems like the main target of the ability sometimes gets selected despite being filtered out by the conditions.
Occasionally a second Vengeful Spirit would linger until its expiration timer killed it off where the target was/is, dealing no damage. It would explain the message showing the right number whilst only 10 units being hit, as one is rendered useless by something. (At least that's the theory that makes sense to me)

  • W Vengeful Spirit Copy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Vengeful Spirit (Rothin)
    • Actions
      • Set VariableSet tempPoint = (Position of (Triggering unit))
      • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
      • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Target unit of ability being cast)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Soul Conduit (Rothin) for (Triggering unit)) Greater than 0
        • Then - Actions
          • Set VariableSet VengefulSpirit_Count = (Level of Soul Conduit (Rothin) for (Triggering unit))
          • Set VariableSet VengefulSpirit_GroupFiltration = (Random VengefulSpirit_Count units from (Units within 900.00 of tempPoint matching ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((Matching unit) Not equal to (Targe
          • Set VariableSet VengefulSpirit_Group = (Random VengefulSpirit_Count units from VengefulSpirit_GroupFiltration)
          • Game - Display to (All players) the text: (String(VengefulSpirit_Count))
          • Unit Group - Pick every unit in VengefulSpirit_Group and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
              • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
              • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
              • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Picked unit)
          • Custom script: call DestroyGroup (udg_VengefulSpirit_Group )
          • Custom script: call DestroyGroup (udg_VengefulSpirit_GroupFiltration )
        • Else - Actions
      • Custom script: call RemoveLocation (udg_tempPoint )
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
It should work.
random-unit-count-in-unit-group-png.358513
  • Test
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Finger of Death (Archimonde)
    • Actions
      • Set Count = 0
      • Set Target = (Target unit of ability being cast)
      • Set Target_Point = (Position of Target)
      • Special Effect - Create a special effect at Target_Point using Abilities\Weapons\DemolisherFireMissile\DemolisherFireMissile.mdl
      • Special Effect - Destroy (Last created special effect)
      • Set Group_Filtration = (Units within 500.00 of Target_Point matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((Matching unit) Not equal to Target))))
      • Set Group_Randomization = (Random 10 units from Group_Filtration)
      • Unit Group - Pick every unit in Group_Randomization and do (Actions)
        • Loop - Actions
          • Set Count = (Count + 1)
          • Set Picked_Point = (Position of (Picked unit))
          • Special Effect - Create a special effect at Picked_Point using Abilities\Weapons\DemolisherFireMissile\DemolisherFireMissile.mdl
          • Special Effect - Destroy (Last created special effect)
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 100.00 damage of attack type Spells and damage type Normal
          • Game - Display to (All players) the text: (String(Count))
          • Custom script: call RemoveLocation(udg_Picked_Point)
      • Custom script: call DestroyGroup(udg_Group_Filtration)
      • Custom script: call DestroyGroup(udg_Group_Randomization)
      • Custom script: call RemoveLocation(udg_Target_Point)
Make sure to adapt this script into yours first. After that, I would suspect there's something wrong on your end or
just a glitch made by unknown. I don't know if it's because of the recent patch screwing something or else. But
we'll dive into another solution in that case.
 
Level 3
Joined
Mar 15, 2020
Messages
48
  • W Vengeful Spirit Copy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Vengeful Spirit (Rothin)
    • Actions
      • Set VariableSet VengefulSpirit_Count = 0
      • Set VariableSet tempTarget = (Target unit of ability being cast)
      • Set VariableSet tempPoint = (Position of (Triggering unit))
      • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
      • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction tempTarget
      • Set VariableSet Group_Filtration = (Units within 900.00 of tempPoint matching ((((Matching unit) belongs to an enemy of (Triggering player).) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((Matching unit) Not equal to tempTarget))).)
      • Set VariableSet Group_Randomization = (Random (Level of Soul Conduit (Rothin) for (Triggering unit)) units from Group_Filtration)
      • Unit Group - Pick every unit in Group_Randomization and do (Actions)
        • Loop - Actions
          • Set VariableSet VengefulSpirit_Count = (VengefulSpirit_Count + 1)
          • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
          • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
          • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
          • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Picked unit)
          • Game - Display to (All players) the text: (String(VengefulSpirit_Count))
      • Custom script: call DestroyGroup(udg_Group_Randomization)
      • Custom script: call DestroyGroup(udg_Group_Filtration)
      • Custom script: call RemoveLocation(udg_tempPoint)
It seems to be working now. Would I be wrong in assuming this is MUI, and if it isn't, how do I rectify that? :D

awdasd.png
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
It's already MUI as it's just an 'instant' spell that doesn't hold: data that should be instantiated per unit/cast to prevent data conflict.
What you should do next is to remove the debug things inside the script such as: 'Game - Text Message' and 'Count' variable there.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
One last thing I didn't noticed, don't remove this significant condition:
  • (Level of Soul Conduit (Rothin) for (Triggering unit)) Greater than 0
Put it after this action:
  • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction tempTarget
Then put the group filtration part up to destroy group custom scripts inside its 'then' block.
It's important to prevent execution of redundant things while Soul Conduit ability level is 0.

EDIT:

After doing that, you're truly welcome.
 
Last edited:
Level 3
Joined
Mar 15, 2020
Messages
48
  • W Vengeful Spirit Copy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Vengeful Spirit (Rothin)
    • Actions
      • Set VariableSet tempTarget = (Target unit of ability being cast)
      • Set VariableSet tempPoint = (Position of (Triggering unit))
      • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
      • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction tempTarget
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Soul Conduit (Rothin) for (Triggering unit)) Greater than 0
        • Then - Actions
          • Set VariableSet Group_Filtration = (Units within 900.00 of tempPoint matching ((((Matching unit) belongs to an enemy of (Triggering player).) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((Matching unit) Not equal to tempTarget))).)
          • Set VariableSet Group_Randomization = (Random (Level of Soul Conduit (Rothin) for (Triggering unit)) units from Group_Filtration)
          • Unit Group - Pick every unit in Group_Randomization and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Volatile Spirit for (Owner of (Triggering unit)) at tempPoint facing (Facing of (Triggering unit)) degrees
              • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
              • Unit - Set level of Vengeful Spirit (Dummy) for (Last created unit) to (Level of Vengeful Spirit (Rothin) for (Triggering unit))
              • Unit - Order (Last created unit) to Orc Batrider - Unstable Concoction (Picked unit)
          • Custom script: call DestroyGroup(udg_Group_Randomization)
          • Custom script: call DestroyGroup(udg_Group_Filtration)
        • Else - Actions
      • Custom script: call RemoveLocation(udg_tempPoint)
Like this, you mean?
 
Level 3
Joined
Mar 15, 2020
Messages
48
Alrighty then, cheers once again. I'll throw some more reputation your way once I'm able. I learned quite a lot this time around.
 
Status
Not open for further replies.
Top