• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Chaos Ability - How to "catch" unit when transformed?

Status
Not open for further replies.
Level 5
Joined
Jun 25, 2005
Messages
92
I'm trying to make a Mechanical Animal ability that uses Chaos to transform the animal into the unit I want. The Chaos transformation transforms a summoned unit, in response to a "unit being summoned" event. That all works fine, but when the unit is transformed, I also want to give it several abilities, but I can't use the "summoned unit" reference anymore, when Chaos transforms the unit.

Q: How can I store store the transformed unit so that it can be given abilities?


I tried or considered, but it didn't work out:
- storing the point of the summoned unit, then make a unit group matching criteria within range of that point and give them the abilities
- check for units entering the playable map area and give them the abilities, if they match
- just making it manual to have the abilities added

I also don't want to make additional unit types with and without the abilities and have them spawn instead, because there are too many different unit types that can be spawned and it would be cumbersome to make them.
 
Level 11
Joined
Nov 23, 2013
Messages
665
Store it in a variable?
  • Chaos
    • Events
      • Unit - A unit Spawns a Summoned Unit
    • Conditions
      • (Unit-type of (Summoned unit)) Equal <Whatever you need>
    • Actions
      • Set ChaosUnit = (Summoned unit)
      • Unit - Add Chaos to ChaosUnit
      • Unit - Add <Whatever ability you need> to ChaosUnit
Thus variable ChaosUnit will always refer to the unit that was summoned, even after Chaos was given to it.
Of course, if several units can be summoned this way, be aware that ChaosUnit is likely to point to the wrong summoned unit. If so, you will have to make your trigger MUI.
Does this help?
 
Level 13
Joined
May 10, 2009
Messages
868
What Sieben suggested should suffice your needs. However, I'm adding to their post that the Chaos ability fires the "Unit - A unit Is issued an order targeting a point" event, and the triggering unit is told to execute the stunned order (851973). The unit will still have the Chaos ability during that time, and it gets automatically removed by the game afterwards.
  • Set Order var
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: set udg_Order_Stunned = 851973
  • Detect Transformation
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to Order_Stunned
      • (Level of Chaos for (Triggering unit)) Greater than 0
    • Actions
      • Game - Display to (All players) the text: Transformed
Note: Since I'm not free to compare any integer order in GUI, I was forced to create an order variable (which is the same as the integer data type), and set its value to 851973 when the game starts.
 
Level 5
Joined
Jun 25, 2005
Messages
92
I had already tried storing it in a variable. It didn't work.

This is the trigger right now:

  • Events
    • Unit - A unit Spawns a summoned unit
  • Conditions
    • ((Summoned unit) is Undead) Equal to False
  • Actions
    • Set TempUnit = (Summoned unit)
    • Set TempPoint = (Position of (Summoned unit))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Unit-type of (Summoning unit)) Equal to Acolyte
      • Then - Actions
        • Unit - Add Convert Cultist (Chaos) (Villagers) to (Summoned unit)
        • Unit - Set level of Convert Cultist (Chaos) (Villagers) for (Summoned unit) to (Random integer number between 1 and 18)
      • Else - Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • Or - Any (Conditions) are true
          • Conditions
            • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
            • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
      • Then - Actions
        • Unit - Add Convert Cultist (Chaos) (Soldiers) to (Summoned unit)
        • Unit - Set level of Convert Cultist (Chaos) (Soldiers) for (Summoned unit) to (Random integer number between 1 and 10)
      • Else - Actions
    • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
    • Special Effect - Destroy (Last created special effect)
    • -------- part that doesn't work yet --------
    • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnit
    • Unit - Add Assume Identity to TempUnit
    • Unit - Set TempUnit acquisition range to 10.00
    • Custom script: call RemoveLocation(udg_TempPoint)
There's also a slight lag the first time a player uses one of the abilities triggering this. I'd also like to know why that is.
 
Last edited:
Level 11
Joined
Nov 23, 2013
Messages
665
I did a quick check and yeah, what I suggested doesn't really work. It seems that transforming a unit with chaos is not totally instant; which means that adding an ability to said unit will be useless, because that unit will be replaced with the new unit type, without the ability.
What I did to make it work was just adding a Wait 0.00 second action after giving chaos ability and before giving new abilities. Using a wait is not a nice and clean option, but it worked.

Or perhaps you can use triggers BloodSoul suggested: detecting transformation, and once it's done, add new abilities.
 
Level 5
Joined
Jun 25, 2005
Messages
92
I tried BloodSoul's solution, but it doesn't work either for me. I get the trigger to fire after checking for Chaos, but it doesn't store the transformed unit either. I also tried to add a wait in game time for 0.00s then, but it didn't work for BloodSoul's solution, at least.

(I created an Order variable called Order_Stunned_ChaosTransf beforehand.)
  • Set Variables MapInit
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: set udg_Order_Stunned_ChaosTransf = 851973
Works:
  • ConvertCultist ChaosTransform
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
      • ((Summoned unit) is Undead) Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
          • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
          • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
    • Actions
      • Set TempUnit = (Summoned unit)
      • Set TempPoint = (Position of (Summoned unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Villagers) to (Summoned unit)
          • Unit - Set level of Convert Cultist (Chaos) (Villagers) for (Summoned unit) to (Random integer number between 1 and 18)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
              • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Soldiers) to (Summoned unit)
          • Unit - Set level of Convert Cultist (Chaos) (Soldiers) for (Summoned unit) to (Random integer number between 1 and 10)
        • Else - Actions
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempPoint)
Doesn't work at the end, even if I remove the conditions in the if-then-else:
  • ConvertCultist GiveAbilities
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to Order_Stunned_ChaosTransf
    • Actions
      • Set TempUnit = (Ordered unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Level of Convert Cultist (Chaos) (Villagers) for TempUnit) Greater than 0
              • (Level of Convert Cultist (Chaos) (Soldiers) for TempUnit) Greater than 0
        • Then - Actions
          • -------- part that doesn't work --------
          • Game - Display to (All players) the text: Debug
          • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnit
          • Unit - Add Assume Identity to TempUnit
          • Unit - Set TempUnit acquisition range to 10.00
        • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint)
Note that it does print "Debug", and that this does work:
  • Events
    • Map initialization
  • Conditions
  • Actions
    • Unit - Add Spawned Unit (Prevent ZombieSpread) to <some preplaced unit>
    • Unit - Add Assume Identity to <some preplaced unit>
    • Unit - Set <some preplaced unit> acquisition range to 10.00
So, the problem still is that the transformed unit isn't stored.
 
Last edited:
Level 5
Joined
Jun 25, 2005
Messages
92
I also tried just adding a wait, but it doesn't work for me, and since it works for you, I am probably doing something wrong:

  • ConvertCultist ChaosTransform Wait
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
      • ((Summoned unit) is Undead) Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
          • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
          • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
    • Actions
      • Set TempUnit = (Summoned unit)
      • Set TempPoint = (Position of (Summoned unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Villagers) to (Summoned unit)
          • Unit - Set level of Convert Cultist (Chaos) (Villagers) for (Summoned unit) to (Random integer number between 1 and 18)
          • Wait 0.00 game-time seconds
          • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnit
          • Unit - Add Assume Identity to TempUnit
          • Unit - Set TempUnit acquisition range to 10.00
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
              • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Soldiers) to (Summoned unit)
          • Unit - Set level of Convert Cultist (Chaos) (Soldiers) for (Summoned unit) to (Random integer number between 1 and 10)
          • Wait 0.00 game-time seconds
          • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnit
          • Unit - Add Assume Identity to TempUnit
          • Unit - Set TempUnit acquisition range to 10.00
        • Else - Actions
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempPoint)
I also don't want to use waits.
 
Level 11
Joined
Nov 23, 2013
Messages
665
It works for me with a normal Wait, not Wait game-time.
If you need to use Wait game-time, you may set it to 0.01 second (which will become in fact ~0.25 second i think), then it should work.
Using waits is not recommended though, they're inaccurate and you might get issues if several units use the same summoning spell within a short duration. But it's all I can think of right now.
 
Last edited:
Level 5
Joined
Jun 25, 2005
Messages
92
It now fully works, if I use normal waits, but I don't want to use waits for the reasons you stated.
 
Level 11
Joined
Nov 23, 2013
Messages
665
To avoid wait-related issues, make your trigger MUI, by using arrays.
Here's how to do it (I based it on your trigger, only I simplified it a bit):
  • Chaos
    • Events
      • Unit - A unit Spawns a Summoned Unit
    • Conditions
      • ((Triggering unit) is Undead) Equal FALSE
    • Actions
      • Set ChaosIndex01 = (ChaosIndex01 + 1)
      • Set TempUnit[ChaosIndex01] = (Summoned unit)
      • Unit - Add Convert Cultist (Chaos) (Villagers) to TempUnit[ChaosIndex01]
      • Wait 0.01 game-time seconds
      • Set ChaosIndex02 = (ChaosIndex02 + 1)
      • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnit[ChaosIndex02]
      • Unit - Add Assume Identity to TempUnit
      • Unit - Set TempUnit acquisition range to 10.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ChaosIndex01 Equal ChaosIndex02
        • Then - Actions
          • Set ChaosIndex01 = 0
          • Set ChaosIndex02 = 0
        • Else - Actions
ChaosIndex01 and ChaosIndex02 are integer variables.
TempUnit is an array (if you don't know how to create it, open the variables window, modify your existing TempUnit and hit the box called "Array")

I tried it and it seems to work, even when the summoning spell is used several times within a short time.
It's still not perfect, because there will still be a short time (~0.25 second) before additional abilities are actually added, but if it's not a problem to you, then that could do the trick.
 
Level 5
Joined
Jun 25, 2005
Messages
92
It fully works and is now MUI. Thank you very much!

Solution:
  • ConvertCultist ChaosTransform Wait MUI
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
      • ((Summoned unit) is Undead) Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
          • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
          • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
    • Actions
      • Set ChaosIndex01 = (ChaosIndex01 + 1)
      • Set TempUnitArray[ChaosIndex01] = (Summoned unit)
      • Set TempPoint = (Position of (Summoned unit))
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
      • Special Effect - Destroy (Last created special effect)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Summoning unit)) Equal to Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Villagers) to TempUnitArray[ChaosIndex01]
          • Unit - Set level of Convert Cultist (Chaos) (Villagers) for TempUnitArray[ChaosIndex01] to (Random integer number between 1 and 18)
          • Wait 0.01 game-time seconds
          • Set ChaosIndex02 = (ChaosIndex02 + 1)
          • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnitArray[ChaosIndex02]
          • Unit - Add Assume Identity to TempUnitArray[ChaosIndex02]
          • Unit - Set TempUnitArray[ChaosIndex02] acquisition range to 10.00
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ChaosIndex01 Equal to ChaosIndex02
            • Then - Actions
              • Set ChaosIndex01 = 0
              • Set ChaosIndex02 = 0
            • Else - Actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Unit-type of (Summoning unit)) Equal to Zealous Acolyte
              • (Unit-type of (Summoning unit)) Equal to Arch-Acolyte
        • Then - Actions
          • Unit - Add Convert Cultist (Chaos) (Soldiers) to TempUnitArray[ChaosIndex01]
          • Unit - Set level of Convert Cultist (Chaos) (Soldiers) for TempUnitArray[ChaosIndex01] to (Random integer number between 1 and 10)
          • Wait 0.01 game-time seconds
          • Set ChaosIndex02 = (ChaosIndex02 + 1)
          • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnitArray[ChaosIndex02]
          • Unit - Add Assume Identity to TempUnitArray[ChaosIndex02]
          • Unit - Set TempUnitArray[ChaosIndex02] acquisition range to 10.00
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ChaosIndex01 Equal to ChaosIndex02
            • Then - Actions
              • Set ChaosIndex01 = 0
              • Set ChaosIndex02 = 0
            • Else - Actions
        • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint)

I assume instead of TempUnit you meant the TempUnit (array) with ChaosIndex02 as an index when the abilities are added:
  • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnitArray[ChaosIndex02]
  • Unit - Add Assume Identity to TempUnitArray[ChaosIndex02]
  • Unit - Set TempUnitArray[ChaosIndex02] acquisition range to 10.00
 
Level 13
Joined
May 10, 2009
Messages
868
Well, I was just adding some extra info. The real problem is that in my trigger the event fires when the unit still has its old unit type. Then, you were trying add those abilities, and it ended up losing them when being transformed completely. We don't need to make things harder. You just need to make those abilities permanent:
JASS:
call UnitMakeAbilityPermanent(unit, true, ability)
Then, your units won't lose those specific abilities when turning into another unit type.
 
Level 11
Joined
Nov 23, 2013
Messages
665
I assume instead of TempUnit you meant the TempUnit (array) with ChaosIndex02 as an index when the abilities are added:
  • Unit - Add Spawned Unit (Prevent ZombieSpread) to TempUnitArray[ChaosIndex02]
  • Unit - Add Assume Identity to TempUnitArray[ChaosIndex02]
  • Unit - Set TempUnitArray[ChaosIndex02] acquisition range to 10.00
That's right! I forgot to add the array part [] while copying-pasting.
Glad it's all working fine for you! :cgrin:

Well, I was just adding some extra info. The real problem is that in my trigger the event fires when the unit still has its old unit type. Then, you were trying add those abilities, and it ended up losing them when being transformed completely. We don't need to make things harder. You just need to make those abilities permanent:
JASS:
call UnitMakeAbilityPermanent(unit, true, ability)
Then, your units won't lose those specific abilities when turning into another unit type.
Hey, this is quite useful, I didn't know that trick. I'm not familiar at all with jass. Is there a way to make an ability permanent in GUI? If not, can it be done with your code in a custom script?
 
Level 5
Joined
Jun 25, 2005
Messages
92
Cool, I didn't know you can make abilities persist when changing unit types. Both that and knowing that Chaos fires the "Unit - A unit Is issued an order targeting a point" event is useful. Thank you!
 
Level 13
Joined
May 10, 2009
Messages
868
That's right! I forgot to add the array part [] while copying-pasting.
Glad it's all working fine for you! :cgrin:


Hey, this is quite useful, I didn't know that trick. I'm not familiar at all with jass. Is there a way to make an ability permanent in GUI? If not, can it be done with your code in a custom script?
Yes, something like this - in case you don't want to use ability raw code directly:
  • Set Ability = Firebolt (Neutral Hostile)
  • Unit - Add Ability to (Triggering unit)
  • Custom script: call UnitMakeAbilityPermanent(GetTriggerUnit(), true, udg_Ability)
or
JASS:
call UnitAddAbility(GetTriggerUnit(), 'ACfb') // ACfb = Firebolt raw data - Press Ctrl + D in object editor in order to see each object's raw data
call UnitMakeAbilityPermanent(GetTriggerUnit(), true, 'ACfb')
 
Status
Not open for further replies.
Top