• 🏆 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] Saving Damaged Unit into a Unit Group

Status
Not open for further replies.
Level 13
Joined
Jun 20, 2014
Messages
479
Hi, it has been a while since I last posted here. I made this approach that when I damage a unit it will be saved on a unit group to avoid unwanted damage. I've achieved that but there is a problem. The units we're saved on a global unit group, as a result other missile will not deal damage. I've written this using indexing but it has the same problem as the current one. I need desperate help. Thanks

Here are the triggers:


  • Shadow Blade Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set DraugrHashtable = (Last created hashtable)
      • Set R1_Ability = Shadow Blade (Raven)
      • Set R1_AttackType = Pierce
      • Set R1_DamageType = Normal
      • Set R1_AoE[1] = 100.00
      • Set R1_AoE[2] = 100.00
      • Set R1_AoE[3] = 100.00
      • Set R1_AoE[4] = 100.00
      • Set R1_AoE[5] = 100.00
      • Set R1_AoE[6] = 100.00
      • Set R1_Gap[1] = 15.00
      • Set R1_Gap[2] = 15.00
      • Set R1_Gap[3] = 15.00
      • Set R1_Gap[4] = 15.00
      • Set R1_Gap[5] = 15.00
      • Set R1_Gap[6] = 15.00
      • Set R1_BladeCount[1] = 3
      • Set R1_BladeCount[2] = 3
      • Set R1_BladeCount[3] = 3
      • Set R1_BladeCount[4] = 3
      • Set R1_BladeCount[5] = 3
      • Set R1_BladeCount[6] = 3
      • Set R1_Absolute[1] = 0.00
      • Set R1_Absolute[2] = 0.00
      • Set R1_Absolute[3] = 0.00
      • Set R1_Absolute[4] = 0.00
      • Set R1_Absolute[5] = 0.00
      • Set R1_Absolute[6] = 0.00
      • Set R1_Vitality[1] = 0.00
      • Set R1_Vitality[2] = 0.00
      • Set R1_Vitality[3] = 0.00
      • Set R1_Vitality[4] = 0.00
      • Set R1_Vitality[5] = 0.00
      • Set R1_Vitality[6] = 0.00
      • Set R1_Wisdom[1] = 0.00
      • Set R1_Wisdom[2] = 0.00
      • Set R1_Wisdom[3] = 0.00
      • Set R1_Wisdom[4] = 0.00
      • Set R1_Wisdom[5] = 0.00
      • Set R1_Wisdom[6] = 0.00
      • Set R1_Power[1] = 100.00
      • Set R1_Power[2] = 110.00
      • Set R1_Power[3] = 120.00
      • Set R1_Power[4] = 130.00
      • Set R1_Power[5] = 140.00
      • Set R1_Power[6] = 150.00
      • Set R1_MDistance[1] = 700.00
      • Set R1_MDistance[2] = 700.00
      • Set R1_MDistance[3] = 700.00
      • Set R1_MDistance[4] = 700.00
      • Set R1_MDistance[5] = 700.00
      • Set R1_MDistance[6] = 700.00
      • Set R1_Delay[1] = 0.80
      • Set R1_Delay[2] = 0.80
      • Set R1_Delay[3] = 0.80
      • Set R1_Delay[4] = 0.80
      • Set R1_Delay[5] = 0.80
      • Set R1_Delay[6] = 0.80
      • Set R1_BladeModel = Abilities\Weapons\SentinelMissile\SentinelMissile.mdl
      • Set R1_ShadowModel = Abilities\Weapons\AvengerMissile\AvengerMissile.mdl
      • Set R1_EndModel = Abilities\Spells\Undead\CarrionSwarm\CarrionSwarmDamage.mdl
      • Set R1_Hit = Abilities\Spells\Undead\DeathandDecay\DeathandDecayTarget.mdl
  • Shadow Blade Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to R1_Ability
    • Actions
      • Set R1_Caster = (Triggering unit)
      • Set R1_Level = (Level of R1_Ability for R1_Caster)
      • Set R1_Player = (Triggering player)
      • -------- - --------
      • Set R1_TempVit = ((Real((Strength of R1_Caster (Include bonuses)))) x (R1_Vitality[R1_Level] x 0.01))
      • Set R1_TempPow = ((Real((Agility of R1_Caster (Include bonuses)))) x (R1_Power[R1_Level] x 0.01))
      • Set R1_TempWisdom = ((Real((Intelligence of R1_Caster (Include bonuses)))) x (R1_Wisdom[R1_Level] x 0.01))
      • Set R1_Damage = ((R1_TempVit + R1_TempPow) + (R1_TempWisdom + R1_Absolute[R1_Level]))
      • -------- - --------
      • Set R1_Point1 = (Position of R1_Caster)
      • Set R1_Point2 = (Target point of ability being cast)
      • Set R1_StartAngle = (Angle from R1_Point1 to R1_Point2)
      • -------- - --------
      • Custom script: call RemoveLocation(udg_R1_Point2)
      • -------- - --------
      • For each (Integer R1_Looper) from 1 to (R1_BladeCount[R1_Level] / 2), do (Actions)
        • Loop - Actions
          • Set R1_StartAngle = (R1_StartAngle - R1_Gap[R1_Level])
      • -------- - --------
      • For each (Integer R1_Looper) from 1 to R1_BladeCount[R1_Level], do (Actions)
        • Loop - Actions
          • -------- - --------
          • Set R1_CDistance = 0.00
          • Set R1_Speed = (R1_MDistance[R1_Level] / (R1_Delay[R1_Level] / 0.03))
          • Set R1_IsDead = False
          • Set R1_Forward = True
          • Set R1_Angle = R1_StartAngle
          • -------- - --------
          • Unit - Create 1 Missle Dummy for R1_Player at R1_Point1 facing R1_Angle degrees
          • Set R1_Missle = (Last created unit)
          • Set R1_MissleHandle = (Last created unit)
          • -------- - --------
          • Animation - Change R1_Missle's vertex coloring to (0.00%, 0.00%, 0.00%) with 0.00% transparency
          • Animation - Change R1_Missle flying height to 100.00 at 0.00
          • Special Effect - Create a special effect attached to the origin of R1_Missle using R1_BladeModel
          • Set R1_Blade = (Last created special effect)
          • Special Effect - Create a special effect attached to the origin of R1_Missle using R1_ShadowModel
          • Set R1_Shadow = (Last created special effect)
          • -------- - --------
          • Unit Group - Add R1_Missle to R1_MissleGroup
          • -------- - --------
          • Hashtable - Save Handle OfR1_Caster as (Key R1_MissleHandle) of 1 in DraugrHashtable
          • Hashtable - Save R1_Level as (Key R1_MissleHandle) of 2 in DraugrHashtable
          • Hashtable - Save Handle OfR1_Player as (Key R1_MissleHandle) of 3 in DraugrHashtable
          • Hashtable - Save R1_Damage as (Key R1_MissleHandle) of 4 in DraugrHashtable
          • Hashtable - Save R1_Angle as (Key R1_MissleHandle) of 5 in DraugrHashtable
          • Hashtable - Save R1_CDistance as (Key R1_MissleHandle) of 6 in DraugrHashtable
          • Hashtable - Save R1_Speed as (Key R1_MissleHandle) of 7 in DraugrHashtable
          • Hashtable - Save R1_IsDead as (Key R1_MissleHandle) of 8 in DraugrHashtable
          • Hashtable - Save R1_Forward as (Key R1_MissleHandle) of 9 in DraugrHashtable
          • Hashtable - Save Handle OfR1_Blade as (Key R1_MissleHandle) of 10 in DraugrHashtable
          • Hashtable - Save Handle OfR1_Shadow as (Key R1_MissleHandle) of 11 in DraugrHashtable
          • Unit Group - Remove all units from R1_Group
          • Hashtable - Save Handle OfR1_Group as (Key R1_MissleHandle) of 13 in DraugrHashtable
          • Set R1_StartAngle = (R1_StartAngle + R1_Gap[R1_Level])
      • Custom script: call RemoveLocation(udg_R1_Point1)
      • -------- - --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Shadow Blade Effect <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Shadow Blade Effect <gen>
        • Else - Actions
  • Shadow Blade Effect
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in R1_MissleGroup and do (Actions)
        • Loop - Actions
          • -------- - --------
          • Set R1_MissleHandle = (Picked unit)
          • Set R1_Missle = (Picked unit)
          • -------- - --------
          • Set R1_Caster = (Load (Key R1_MissleHandle) of 1 in DraugrHashtable)
          • Set R1_Level = (Load (Key R1_MissleHandle) of 2 from DraugrHashtable)
          • Set R1_Player = (Load (Key R1_MissleHandle) of 3 in DraugrHashtable)
          • Set R1_Damage = (Load (Key R1_MissleHandle) of 4 from DraugrHashtable)
          • Set R1_Angle = (Load (Key R1_MissleHandle) of 5 from DraugrHashtable)
          • Set R1_CDistance = (Load (Key R1_MissleHandle) of 6 from DraugrHashtable)
          • Set R1_Speed = (Load (Key R1_MissleHandle) of 7 from DraugrHashtable)
          • Set R1_IsDead = (Load (Key R1_MissleHandle) of 8 from DraugrHashtable)
          • Set R1_Forward = (Load (Key R1_MissleHandle) of 9 from DraugrHashtable)
          • -------- - --------
          • -------- check if dead --------
          • -------- - --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • R1_IsDead Equal to False
              • (R1_Caster is alive) Equal to True
            • Then - Actions
              • -------- - --------
              • -------- adjust angle --------
              • -------- - --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • R1_Forward Equal to False
                • Then - Actions
                  • Set R1_Point1 = (Position of R1_Caster)
                  • Set R1_Point2 = (Position of R1_Missle)
                  • Set R1_Angle = (Angle from R1_Point2 to R1_Point1)
                  • Set R1_DynamicDistance = (Distance between R1_Point1 and R1_Point2)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • R1_DynamicDistance Less than 50.00
                    • Then - Actions
                      • Set R1_IsDead = True
                    • Else - Actions
                  • Hashtable - Save R1_Angle as (Key R1_MissleHandle) of 5 in DraugrHashtable
                  • Hashtable - Save R1_Speed as (Key R1_MissleHandle) of 7 in DraugrHashtable
                  • Custom script: call RemoveLocation(udg_R1_Point1)
                  • Custom script: call RemoveLocation(udg_R1_Point2)
                • Else - Actions
              • -------- - --------
              • -------- adjust distance --------
              • -------- - --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • R1_Forward Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • R1_CDistance Less than R1_MDistance[R1_Level]
                    • Then - Actions
                      • Set R1_CDistance = (R1_CDistance + R1_Speed)
                    • Else - Actions
                      • Unit Group - Remove all units from R1_Group
                      • Hashtable - Save Handle OfR1_Group as (Key R1_MissleHandle) of 13 in DraugrHashtable
                      • Set R1_Forward = False
                      • Set R1_CDistance = 0.00
                • Else - Actions
              • -------- - --------
              • -------- move missle --------
              • -------- - --------
              • Set R1_Point1 = (Position of R1_Missle)
              • Set R1_TempGroup = (Units within R1_AoE[R1_Level] of R1_Point1)
              • Set R1_Group = (Load (Key R1_MissleHandle) of 13 in DraugrHashtable)
              • Unit Group - Pick every unit in R1_TempGroup and do (Actions)
                • Loop - Actions
                  • Set R1_Picked = (Picked unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (R1_Picked is A structure) Equal to False
                      • (R1_Picked is Magic Immune) Equal to False
                      • (R1_Picked is alive) Equal to True
                      • (R1_Picked belongs to an enemy of R1_Player) Equal to True
                      • (R1_Picked is Mechanical) Equal to False
                      • (R1_Picked is in R1_Group) Equal to False
                    • Then - Actions
                      • Special Effect - Create a special effect attached to the origin of R1_Picked using R1_Hit
                      • Special Effect - Destroy (Last created special effect)
                      • Unit - Cause R1_Caster to damage R1_Picked, dealing R1_Damage damage of attack type R1_AttackType and damage type R1_DamageType
                      • Unit Group - Add R1_Picked to R1_Group
                    • Else - Actions
                      • Set R1_Picked = No unit
              • Hashtable - Save Handle OfR1_Group as (Key R1_MissleHandle) of 13 in DraugrHashtable
              • Set R1_Point2 = (R1_Point1 offset by R1_Speed towards R1_Angle degrees)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Terrain pathing at R1_Point2 of type Walkability is off) Equal to False
                  • ((Playable map area) contains R1_Point2) Equal to True
                • Then - Actions
                  • -------- - --------
                  • Custom script: call SetUnitY(udg_R1_Missle, GetLocationY(udg_R1_Point2))
                  • Custom script: call SetUnitX(udg_R1_Missle, GetLocationX(udg_R1_Point2))
                  • -------- - --------
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • R1_Forward Equal to True
                    • Then - Actions
                      • Set R1_Forward = False
                    • Else - Actions
                      • Set R1_IsDead = True
              • Custom script: call RemoveLocation(udg_R1_Point1)
              • Custom script: call RemoveLocation(udg_R1_Point2)
              • -------- - --------
              • Hashtable - Save R1_IsDead as (Key R1_MissleHandle) of 8 in DraugrHashtable
              • Hashtable - Save R1_CDistance as (Key R1_MissleHandle) of 6 in DraugrHashtable
              • Hashtable - Save R1_Forward as (Key R1_MissleHandle) of 9 in DraugrHashtable
              • -------- - --------
            • Else - Actions
              • Unit - Add a 0.01 second Generic expiration timer to R1_Missle
              • Set R1_Point1 = (Position of R1_Missle)
              • Special Effect - Create a special effect at R1_Point1 using R1_EndModel
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call RemoveLocation(udg_R1_Point1)
              • -------- - --------
              • Set R1_Blade = (Load (Key R1_MissleHandle) of 10 in DraugrHashtable)
              • Special Effect - Destroy R1_Blade
              • Set R1_Shadow = (Load (Key R1_MissleHandle) of 11 in DraugrHashtable)
              • Special Effect - Destroy R1_Shadow
              • -------- - --------
              • Unit Group - Remove R1_Missle from R1_MissleGroup
              • -------- - --------
              • Hashtable - Clear all child hashtables of child (Key R1_MissleHandle) in DraugrHashtable
              • -------- - --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (R1_MissleGroup is empty) Equal to True
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions


I've also attached a test map containing the ability. Oh, by the way the ability is a "Rake" type spell (throws projectile to damage enemies then return to the caster damaging units in its path). Also, Power = agility.
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,389
I'm not sure if I get the question right, but if you want to damage a unit by this ability only once (either by sending the missile forward or when it gets back) all you need to do is check if picked unit is in the "already damaged" unit group.

If that is not the case, I would advise using indexing technique and using a unit group array. Basically you would check the following:
My_Index = Instance of the spell
If(unit is in My_Group[My_Instance] == false) then damage unit and add unit to My_Group[My_Instance] else do nothing as the unit was already damaged by this instace


Edit:
Also, I see you're using hashtables. I advise using arrays and indexing technique for "every 0.03 second" loops.
 
Level 13
Joined
Jun 20, 2014
Messages
479
thanks you for the response. yes, that is almost it however indexed groups offer the same result. i think my problem with indexed group is the right way to dispose it. do you just overwrite it with the new group or destroy it then overwrite it? my guess is just overwrite it.
 
Level 25
Joined
Sep 26, 2009
Messages
2,389
Groups are like special effects in the sense that if you don't destroy them when you're done with them, then they leak memory.

When instance of spell ends, you remove everything that may leak and then deindex it (= overwrite that instance with the last instance).
Do note that it is important HOW you create a unit group.

For example:
If you do this:
  • Unit Group - Add unit to My_UnitGroup
But My_UnitGroup was destroyed (or not initialized), then you "add unit to null" which means you never add the unit anywhere, hence if you later check the same unit again for "Unit is in My_UnitGroup == true", then it will always fail the check and allow your trigger to damage the unit again.

However the "Unit Group - Add unit to unit group" actions is not the same as this:
  • Set My_UnitGroup = (Units in.... )
This action first creates the unit group and add the picked units inside it. If you use this action in the loop trigger, it won't resolve your problem, as you will be overwriting that one variable with new unit group each time you fire the trigger.

Imo the best option is this:
  • Custom script: if My_UnitGroup == null then
  • Custom script: My_UnitGroup = CreateGroup()
  • Custom script: endif
Use this when you start the spell. This checks if the unit group == null (meaning it was not created) and if so, you create the unit group.
Then you just use the "Unit Group - Add unit to unit group".
Of course, this is just for one unit group. You will need to remake it to make it work for arrays instead.
 
Level 13
Joined
Jun 20, 2014
Messages
479
wow! i didnt know that. thank you for enlightening me

Edit: somehow its giving me an error when i use My_UnitGroup = CreateGroup()... should i write it like "set My_UnitGroup = CreateGroup()"? this one gives no errors. "udg_My_UnitGroup=CreateGroup" also creates an error
 
Status
Not open for further replies.
Top