Damage System

Level 5
Joined
Feb 22, 2025
Messages
78
Created a spell - Summon Sindragosa:
-----------------------------------------------------------------------
  • SS Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Summon Sindragosa
    • Actions
      • Set SS_Caster = (Triggering unit)
      • Set SS_Target_Point = (Target point of ability being cast)
      • Set SS_Spawn_Point = ((Position of SS_Caster) offset by (-300.00, 0.00))
      • Unit - Create 1 Sindragosa for (Owner of SS_Caster) at SS_Spawn_Point facing SS_Target_Point
      • Set SS_Sindragosa = (Last created unit)
      • Unit - Turn collision for SS_Sindragosa Off.
      • Animation - Change SS_Sindragosa flying height to 650.00 at 0.00
      • Animation - Play SS_Sindragosa's birth animation
      • Countdown Timer - Start SS_Delay_Timer as a One-shot timer that will expire in 1.30 seconds
      • Set SS_Delay_Timer = (Last started timer)
      • Hashtable - Create a hashtable
      • Set SS_Hashtable = (Last created hashtable)
      • Hashtable - Save Handle OfSS_Sindragosa as (Key SS_Caster.) of 0 in SS_Hashtable.
      • Hashtable - Save Handle OfSS_Caster as (Key SS_Sindragosa.) of 1 in SS_Hashtable.
      • Hashtable - Save Handle OfSS_Target_Point as (Key SS_Caster.) of 2 in SS_Hashtable.
      • Custom script: call RemoveLocation( udg_SS_Spawn_Point)
  • SS Delay
    • Events
      • Time - SS_Delay_Timer expires
    • Conditions
      • (Load (Key SS_Caster.) of 0 in SS_Hashtable.) Not equal to No unit
    • Actions
      • Set SS_Sindragosa = (Load (Key SS_Caster.) of 0 in SS_Hashtable.)
      • Set SS_Caster = (Load (Key SS_Sindragosa.) of 1 in SS_Hashtable.)
      • Set SS_Target_Point = (Load (Key SS_Caster.) of 2 in SS_Hashtable.)
      • Animation - Reset SS_Sindragosa's animation
      • Trigger - Turn on SS Move <gen>
      • Trigger - Turn on SS SFX <gen>
  • SS Move
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
      • (Load (Key SS_Caster.) of 0 in SS_Hashtable.) Not equal to No unit
    • Actions
      • Set SS_Current_Position = (Position of SS_Sindragosa)
      • Set SS_Direction = (Angle from SS_Current_Position to SS_Target_Point)
      • Set SS_Move_Offset = (SS_Current_Position offset by 25.00 towards SS_Direction degrees.)
      • Unit - Move SS_Sindragosa instantly to SS_Move_Offset
      • Set SS_Damage_Offset = (SS_Move_Offset offset by 300.00 towards SS_Direction degrees.)
      • Set SS_DMG_Group = (Units within 200.00 of SS_Damage_Offset matching ((((Matching unit) belongs to an enemy of (Owner of SS_Caster).) Equal to True) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) is hidden) Equal to False))).)
      • Unit Group - Pick every unit in SS_DMG_Group and do (Actions)
        • Loop - Actions
          • Unit - Cause SS_Caster to damage (Picked unit), dealing 50.00 damage of attack type Spells and damage type Normal
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between SS_Move_Offset and SS_Target_Point) Less than 25.00
        • Then - Actions
          • Trigger - Turn off (This trigger)
          • Trigger - Turn off SS SFX <gen>
          • Custom script: call RemoveLocation( udg_SS_Move_Offset)
          • Custom script: call RemoveLocation( udg_SS_Damage_Offset)
          • Custom script: call RemoveLocation( udg_SS_Target_Point)
          • Hashtable - Clear SS_Hashtable
          • Animation - Play SS_Sindragosa's death animation
          • Wait 2.00 seconds
          • Unit - Remove SS_Sindragosa from the game
        • Else - Actions
      • Custom script: call RemoveLocation( udg_SS_Current_Position)
      • Custom script: call DestroyGroup( udg_SS_DMG_Group)
  • SS SFX
    • Events
      • Time - Every 0.33 seconds of game time
    • Conditions
    • Actions
      • Special Effect - Create a special effect at SS_Damage_Offset using Sfx_Arthas_LichKing_Sindragosa_Splat.mdx
      • Set SS_Frost = (Last created special effect)
      • Special Effect - Set Scale of SS_Frost to 0.30
      • Special Effect - Set Time Scale of SS_Frost to 0.50
      • Special Effect - Destroy SS_Frost
-------------------------------------
Now, I'm wondering is there a way to damage units in SS_DMG_Group just once when they get hit by the frost breath and they continue to recieve damage if they stand in the frost splat while it lasts ? Can't think of a simple way of doing this...
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
1) Your Hashtable isn't doing anything. You can delete it and just check the SS Variables directly. If you want the triggers to be MUI then you'll want to use something like Dynamic Indexing, it's a good fit for this type of spell.

2) To prevent units from being hit more than once you can use a separate Unit Group which is cleared at the start of the cast and maintained throughout. This is your "hit group" which will be checked in the Conditions when trying to damage a unit:
  • If - Conditions
    • ((Picked unit) is in Already_Hit_Group) Equal to False
  • Then - Actions
    • Unit - Cause SS_Caster to damage (Picked unit)...
    • Unit Group - Add (Picked unit) to Already_Hit_Group
I attached an example map that shows off Dynamic Indexing for a triggered Shockwave. Here are the triggers:
  • Custom Shockwave Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Custom Shockwave
    • Actions
      • -------- Increase the Index (spell instances) by 1: --------
      • Set SW_Index = (SW_Index + 1)
      • -------- --------
      • -------- Set the Caster: --------
      • Set SW_Caster[SW_Index] = (Triggering unit)
      • -------- --------
      • -------- Set the Points: --------
      • Set SW_Point[SW_Index] = (Position of SW_Caster[SW_Index])
      • Set SW_Point[0] = (Target point of ability being cast)
      • -------- --------
      • -------- ======================================== --------
      • -------- CONFIGURE Ability Settings: --------
      • Set SW_Damage[SW_Index] = (75.00 x (Real((Level of (Ability being cast) for SW_Caster[SW_Index]))))
      • Set SW_Duration = 1.00
      • Set SW_Distance[SW_Index] = 1000.00
      • Set SW_AreaOfEffect[SW_Index] = 200.00
      • Set SW_DamageType[SW_Index] = Magic
      • Set SW_AttackType[SW_Index] = Spells
      • Set SW_Height[SW_Index] = 60.00
      • -------- --------
      • -------- Set and scale the Missile's Special Effect art: --------
      • Special Effect - Create a special effect at SW_Point[SW_Index] using Abilities\Spells\Orc\Shockwave\ShockwaveMissile.mdl
      • Special Effect - Set Scale of (Last created special effect) to 1.00
      • -------- ======================================== --------
      • -------- --------
      • -------- Apply some final settings (order is important): --------
      • Set SW_CasterPlayer[SW_Index] = (Owner of SW_Caster[SW_Index])
      • Custom script: set udg_SW_HitGroup[udg_SW_Index] = CreateGroup()
      • Set SW_Interval = (SW_Duration / 0.02)
      • Set SW_Speed[SW_Index] = (SW_Distance[SW_Index] / SW_Interval)
      • Set SW_DistanceNeeded[SW_Index] = (SW_Distance[SW_Index] - 0.01)
      • Set SW_CasterPlayer[SW_Index] = (Owner of SW_Caster[SW_Index])
      • Set SW_Angle[SW_Index] = (Angle from SW_Point[SW_Index] to SW_Point[0])
      • Set SW_Distance[SW_Index] = 0.00
      • Set SW_Missile[SW_Index] = (Last created special effect)
      • Special Effect - Set Yaw of SW_Missile[SW_Index] to: (Radians(SW_Angle[SW_Index]))
      • Special Effect - Set Height of SW_Missile[SW_Index] to: ((Position - Z of SW_Missile[SW_Index].) + SW_Height[SW_Index])
      • Custom script: call RemoveLocation (udg_SW_Point[0])
      • -------- --------
      • -------- Start the Timer which will continuously move all of the active Shockwaves (if it's currently off): --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • SW_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start SW_Timer as a Repeating timer that will expire in 0.02 seconds
        • Else - Actions
  • Custom Shockwave Timer
    • Events
      • Time - SW_Timer expires
    • Conditions
    • Actions
      • For each (Integer SW_Loop) from 1 to SW_Index, do (Actions)
        • Loop - Actions
          • -------- Increase distance traveled and move the Shockwave Special Effect: --------
          • Set SW_Distance[SW_Loop] = (SW_Distance[SW_Loop] + SW_Speed[SW_Loop])
          • Set SW_Point[0] = (SW_Point[SW_Loop] offset by SW_Distance[SW_Loop] towards SW_Angle[SW_Loop] degrees.)
          • Custom script: set udg_SW_Z = GetLocationZ(udg_SW_Point[0])
          • Special Effect - Set Position of SW_Missile[SW_Loop] to x: (X of SW_Point[0]), y: (Y of SW_Point[0]), z: (SW_Z + SW_Height[SW_Loop])
          • -------- --------
          • -------- Search for enemy units around the Shockwave: --------
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within SW_AreaOfEffect[SW_Loop] of SW_Point[0].) and do (Actions)
            • Loop - Actions
              • Set SW_Target = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (SW_Target belongs to an enemy of SW_CasterPlayer[SW_Loop].) Equal to True
                  • (SW_Target is alive) Equal to True
                  • (SW_Target is A ground unit) Equal to True
                  • (SW_Target is Magic Immune) Equal to False
                  • (SW_Target is invulnerable) Equal to False
                  • (SW_Target is in SW_HitGroup[SW_Loop].) Equal to False
                • Then - Actions
                  • Unit Group - Add SW_Target to SW_HitGroup[SW_Loop]
                  • Unit - Cause SW_Caster[SW_Loop] to damage SW_Target, dealing SW_Damage[SW_Loop] damage of attack type SW_AttackType[SW_Loop] and damage type SW_DamageType[SW_Loop]
                • Else - Actions
          • Custom script: call RemoveLocation (udg_SW_Point[0])
          • -------- --------
          • -------- Check if the Shockwave has reached it's maximum distance: --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SW_Distance[SW_Loop] Greater than or equal to SW_DistanceNeeded[SW_Loop]
            • Then - Actions
              • -------- If you want something to happen when the Missile ends then put those Actions right here: --------
              • -------- --------
              • -------- Destroy the Missile, Missile Point, and Hit Group: --------
              • Special Effect - Destroy SW_Missile[SW_Loop]
              • Custom script: call RemoveLocation (udg_SW_Point[udg_SW_Loop])
              • Custom script: call DestroyGroup (udg_SW_HitGroup[udg_SW_Loop])
              • -------- --------
              • -------- Then swap this spell instance with the last spell instance (if any): --------
              • Set SW_Caster[SW_Loop] = SW_Caster[SW_Index]
              • Set SW_CasterPlayer[SW_Loop] = SW_CasterPlayer[SW_Index]
              • Set SW_Point[SW_Loop] = SW_Point[SW_Index]
              • Set SW_Angle[SW_Loop] = SW_Angle[SW_Index]
              • Set SW_AreaOfEffect[SW_Loop] = SW_AreaOfEffect[SW_Index]
              • Set SW_Missile[SW_Loop] = SW_Missile[SW_Index]
              • Set SW_Speed[SW_Loop] = SW_Speed[SW_Index]
              • Set SW_Height[SW_Loop] = SW_Height[SW_Index]
              • Set SW_Distance[SW_Loop] = SW_Distance[SW_Index]
              • Set SW_DistanceNeeded[SW_Loop] = SW_DistanceNeeded[SW_Index]
              • Set SW_Damage[SW_Loop] = SW_Damage[SW_Index]
              • Set SW_DamageType[SW_Loop] = SW_DamageType[SW_Index]
              • Set SW_AttackType[SW_Loop] = SW_AttackType[SW_Index]
              • Set SW_AreaOfEffect[SW_Loop] = SW_AreaOfEffect[SW_Index]
              • Set SW_HitGroup[SW_Loop] = SW_HitGroup[SW_Index]
              • -------- --------
              • -------- Then push the For Loop back one cycle while removing the last instance (technically the current one): --------
              • Set SW_Index = (SW_Index - 1)
              • Set SW_Loop = (SW_Loop - 1)
              • -------- --------
              • -------- SW_Index will be back to 0 once the last instance is removed, meaning we can end all of this for now: --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SW_Index Equal to 0
                • Then - Actions
                  • Countdown Timer - Pause SW_Timer
                • Else - Actions
            • Else - Actions
 

Attachments

  • Custom Shockwave Fixed1.w3x
    25.6 KB · Views: 2
Last edited:
Level 5
Joined
Feb 22, 2025
Messages
78
1) Your Hashtable isn't doing anything. You can delete it and just check the SS Variables directly. If you want the triggers to be MUI then you'll want to use something like Dynamic Indexing, it's a good fit for this type of spell.

2) To prevent units from being hit more than once you can use a separate Unit Group which is cleared at the start of the cast and maintained throughout. This is your "hit group" which will be checked in the Conditions when trying to damage a unit:
  • If - Conditions
    • ((Picked unit) is in Already_Hit_Group) Equal to False
  • Then - Actions
    • Unit - Cause SS_Caster to damage (Picked unit)...
    • Unit Group - Add (Picked unit) to Already_Hit_Group
I attached an example map that shows off Dynamic Indexing for a triggered Shockwave.
Thanks! I'll go over it and see what I can apply :goblin_boom:(tommorow, since it's 3am and my brain is :goblin_boom:, I'll post tomorrow what I'd manage to do)
 
Last edited:
Top