• 🏆 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] Remorseless Winter

Status
Not open for further replies.
Level 9
Joined
Dec 16, 2017
Messages
343
Hello guys, i am struggling to make this spell work like it should, it's the same as Death Knight spell from wow, Remorseless Winter it's supposed to do damage every 0.50 seconds for 8 times, so it's a duration of 4 seconds, but sometimes it works, sometimes it doesn't, i don't understand..and other problem i have, is that the position from where units are picked, doesn't change after the caster, it stays the same for the whole duration of the spell, so if the caster moves, it will still damage the last position he had in this 0.50 interval or more, instead of moving after him..Also, for the remorseless effect, i used endurance aura and added to the caster, because i can't trigger this buff Remorseless Winter🥶 with a dummy or with an special effect.
  • Remorseless Winter Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Remorseless Winter (Death Knight FROST)
    • Actions
      • Set RW_Index = (RW_Index + 1)
      • Set RW_Caster[RW_Index] = (Triggering unit)
      • Set RW_Position[RW_Index] = (Position of RW_Caster[RW_Index])
      • Set RW_Counter[RW_Index] = 0.00
      • Set RW_Damage[RW_Index] = (25.00 + (25.00 x (Real((Level of (Ability being cast) for RW_Caster[RW_Index])))))
      • Unit - Add |r Remorseless Winter Effect to RW_Caster[RW_Index]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RW_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on Remorseless Winter Loop <gen>
        • Else - Actions
  • Remorseless Winter Loop
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer RW_LoopIndex) from 1 to RW_Index, do (Actions)
        • Loop - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within 350.00 of RW_Position[RW_LoopIndex]) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is A structure) Equal to False
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) belongs to an enemy of (Owner of RW_Caster[RW_LoopIndex])) Equal to True
                • Then - Actions
                  • Unit - Cause RW_Caster[RW_LoopIndex] to damage (Picked unit), dealing RW_Damage[RW_LoopIndex] damage of attack type Normal and damage type Cold
                  • Special Effect - Create a special effect attached to the chest of (Picked unit) using IceBolt.mdx
                  • Set RW_SFX3[RW_LoopIndex] = (Last created special effect)
                  • Special Effect - Destroy RW_SFX3[RW_LoopIndex]
                  • Set RW_Counter[RW_LoopIndex] = (RW_Counter[RW_LoopIndex] + 1.00)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • RW_Counter[RW_LoopIndex] Greater than or equal to 8.00
                    • Then - Actions
                      • Unit - Remove |r Remorseless Winter Effect from RW_Caster[RW_LoopIndex]
                      • Set RW_Caster[RW_LoopIndex] = RW_Caster[RW_Index]
                      • Set RW_Position[RW_LoopIndex] = RW_Position[RW_Index]
                      • Set RW_Counter[RW_LoopIndex] = RW_Counter[RW_Index]
                      • Set RW_Index = (RW_Index - 1)
                      • Set RW_LoopIndex = (RW_LoopIndex - 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • RW_Index Equal to 0
                        • Then - Actions
                          • Trigger - Turn off (This trigger)
                        • Else - Actions
                    • Else - Actions
                • Else - Actions
 
Last edited:
Level 27
Joined
May 18, 2018
Messages
397
First, I think you have a problem with your indexes, but it's just something I thought I saw so I'll need to check it in the editor to be completely sure.

  • Set RW_Counter[RW_Index] = 0.00
In my opinion it would be better to use time instead of counter (just my opinion, I am used to doing it that way but it is not something that is really relevant).

  • Set RW_Position[RW_Index] = (Position of RW_Caster[RW_Index])
You have set the location of the caster only at the beginning, but have not done so for the rest of the loop. So the position variable remains the same as the starting location, and this is the reason why the area of damage does not follow the hero.

Also, you need to completely clear locations or they will become a leak.
 
Last edited:
Level 24
Joined
Feb 9, 2009
Messages
1,787
As Riki explained you're location is the issue.
But one nitpick from me too!

Change this in the loop segment:
  • Special Effect - Create a special effect attached to the chest of (Picked unit) using IceBolt.mdx
  • Set RW_SFX3[RW_LoopIndex] = (Last created special effect)
  • Special Effect - Destroy RW_SFX3[RW_LoopIndex]
To this:
  • Special Effect - Create a special effect attached to the chest of (Picked unit) using IceBolt.mdx
  • Special Effect - Destroy (Last created special effect.)
You're destroying it right away so it doesn't need a variable.

Also, for the remorseless effect, i used endurance aura and added to the caster, because i can't trigger this buff Remorseless Winter🥶 with a dummy or with an special effect.

Now with that free variable "RW_SFX3[RW_LoopIndex]" create the effect at the start of the ability cast at the position of the caster.
Like:
  • CAST TRIGGER:
  • Special Effect - Create a special effect attached to the chest of (Picked unit) using disobedientpeppermintmist.mdx
  • Set RW_SFX3[RW_Index] = (Last created special effect)
And during the loop just refer to it and use:
  • Special Effect - Set Position of RW_SFX3[RW_LoopIndex] to x: (X of RW_Point[1]), y: (Y of RW_Point[1]), z: ((Position - Z of RW_SFX3[RW_LoopIndex].) + (Current flying height of RW_Caster[RW_Index]))
And destroy it and shuffle it back in when the spell ends like:
  • Special Effect - Destroy RW_SFX3[RW_LoopIndex]
  • Set RW_SFX3[RW_LoopIndex] = RW_SFX3[RW_Index]
 
Last edited:
Level 27
Joined
May 18, 2018
Messages
397
Try this, I also included a test map so you can see it better in the editor. Updated triggers and test map in the post below


  • Remorseless Winter
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Remorseless Winter
    • Actions
      • Set RW_Index = (RW_Index + 1)
      • Set RW_Off[RW_Index] = False
      • Set RW_Caster[RW_Index] = (Casting unit)
      • Set RW_Damage[RW_Index] = (25.00 x (Real((Level of Remorseless Winter for RW_Caster[RW_Index]))))
      • Special Effect - Create a special effect attached to the origin of RW_Caster[RW_Index] using war3mapImported\RemorselessWinter.mdx
      • Set RW_SFX[RW_Index] = (Last created special effect)
      • Set RW_Time[RW_Index] = 4.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RW_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on Remorseless Winter Loop <gen>
        • Else - Actions
  • Remorseless Winter Loop
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer RW_Loop) from 1 to RW_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RW_Off[RW_Loop] Equal to False
            • Then - Actions
              • Set RW_Time[RW_Loop] = (RW_Time[RW_Loop] - 0.50)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RW_Time[RW_Loop] Greater than or equal to 0.00
                  • (RW_Caster[RW_Loop] is alive) Equal to True
                • Then - Actions
                  • Set RW_Position[RW_Loop] = (Position of RW_Caster[RW_Loop])
                  • Set RW_Group[RW_Loop] = (Units within 350.00 of RW_Position[RW_Loop])
                  • Unit Group - Pick every unit in RW_Group[RW_Loop] and do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) is alive) Equal to True
                          • ((Picked unit) belongs to an enemy of (Owner of RW_Caster[RW_Loop])) Equal to True
                        • Then - Actions
                          • Unit - Cause RW_Caster[RW_Loop] to damage (Picked unit), dealing RW_Damage[RW_Loop] damage of attack type Spells and damage type Normal
                          • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\LichMissile\LichMissile.mdl
                          • Special Effect - Destroy (Last created special effect)
                        • Else - Actions
                  • Custom script: call RemoveLocation(udg_RW_Position[udg_RW_Loop])
                  • Custom script: call DestroyGroup(udg_RW_Group[udg_RW_Loop])
                • Else - Actions
                  • Set RW_Off[RW_Loop] = True
                  • Set RW_Caster[RW_Loop] = No unit
                  • Set RW_Damage[RW_Loop] = 0.00
                  • Set RW_Time[RW_Loop] = 0.00
                  • Special Effect - Destroy RW_SFX[RW_Loop]
                  • Custom script: set udg_RW_SFX[udg_RW_Loop] = null
                  • Set RW_Index = (RW_Index - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • RW_Index Equal to 0
                    • Then - Actions
                      • Trigger - Turn off (This trigger)
                    • Else - Actions
            • Else - Actions
 
Last edited:
Level 24
Joined
Feb 9, 2009
Messages
1,787
  • Else - Actions
    • Set RW_Off[RW_Loop] = True
    • Set RW_Caster[RW_Loop] = No unit
    • Set RW_Damage[RW_Loop] = 0.00
    • Set RW_Time[RW_Loop] = 0.00
    • Special Effect - Destroy RW_SFX[RW_Loop]
    • Custom script: set udg_RW_SFX[udg_RW_Loop] = null
    • Set RW_Index = (RW_Index - 1)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • RW_Index Equal to 0
      • Then - Actions
        • Trigger - Turn off (This trigger)
      • Else - Actions
  • Else - Actions

This end bit needs to be changed to deindex the variables, as it stands it's not MUI.
Change it to this:
  • Special Effect - Destroy RW_SFX[RW_Loop]
  • Custom script: set udg_RW_SFX[udg_RW_Loop] = null
  • Set VariableSet RW_Caster[RW_Loop] = RW_Caster[RW_Index]
  • Set VariableSet RW_Damage[RW_Loop] = RW_Damage[RW_Index]
  • Set VariableSet RW_Time[RW_Loop] = RW_Time[RW_Index]
  • Set VariableSet RW_SFX[RW_Loop] = RW_SFX[RW_Index]
  • Set VariableSet RW_Index = (RW_Index - 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • RW_Index Equal to 0
    • Then - Actions
      • Trigger - Turn off (This trigger)
    • Else - Actions
Also I'd remove RW_Off[RW_Loop] too.
 
Level 27
Joined
May 18, 2018
Messages
397
This end bit needs to be changed to deindex the variables, as it stands it's not MUI.
Oh yeah, I figured it out now. Usually I used to do it using a double index to make it completely MUI but I forgot to do it that way in this example, and I also think your idea makes more sense.

You never finish learning in WE lol.

Also I'd remove RW_Off[RW_Loop] too.
Yes, I think it can be removed. It is not necessary for this spell but I included it anyway.

EDIT:
Here are the updated triggers and test map.

  • Remorseless Winter
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Remorseless Winter
    • Actions
      • Set RW_Index = (RW_Index + 1)
      • Set RW_Caster[RW_Index] = (Casting unit)
      • Set RW_Damage[RW_Index] = (25.00 x (Real((Level of Remorseless Winter for RW_Caster[RW_Index]))))
      • Special Effect - Create a special effect attached to the origin of RW_Caster[RW_Index] using war3mapImported\RemorselessWinter.mdx
      • Set RW_SFX[RW_Index] = (Last created special effect)
      • Set RW_Time[RW_Index] = 4.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RW_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on Remorseless Winter Loop <gen>
        • Else - Actions
  • Remorseless Winter Loop
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer RW_Loop) from 1 to RW_Index, do (Actions)
        • Loop - Actions
          • Set RW_Time[RW_Loop] = (RW_Time[RW_Loop] - 0.50)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RW_Time[RW_Loop] Greater than or equal to 0.00
              • (RW_Caster[RW_Loop] is alive) Equal to True
            • Then - Actions
              • Set RW_Position[RW_Loop] = (Position of RW_Caster[RW_Loop])
              • Set RW_Group[RW_Loop] = (Units within 350.00 of RW_Position[RW_Loop])
              • Unit Group - Pick every unit in RW_Group[RW_Loop] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Picked unit) is alive) Equal to True
                      • ((Picked unit) belongs to an enemy of (Owner of RW_Caster[RW_Loop])) Equal to True
                    • Then - Actions
                      • Unit - Cause RW_Caster[RW_Loop] to damage (Picked unit), dealing RW_Damage[RW_Loop] damage of attack type Spells and damage type Normal
                      • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\LichMissile\LichMissile.mdl
                      • Special Effect - Destroy (Last created special effect)
                    • Else - Actions
              • Custom script: call RemoveLocation(udg_RW_Position[udg_RW_Loop])
              • Custom script: call DestroyGroup(udg_RW_Group[udg_RW_Loop])
            • Else - Actions
              • Special Effect - Destroy RW_SFX[RW_Loop]
              • Set RW_Caster[RW_Loop] = RW_Caster[RW_Index]
              • Set RW_Damage[RW_Loop] = RW_Damage[RW_Index]
              • Set RW_SFX[RW_Loop] = RW_SFX[RW_Index]
              • Set RW_Time[RW_Loop] = RW_Time[RW_Index]
              • Set RW_Index = (RW_Index - 1)
              • Set RW_Loop = (RW_Loop - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RW_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
 

Attachments

  • test 2.w3x
    53.3 KB · Views: 14
Last edited:
Level 27
Joined
May 18, 2018
Messages
397
Thanks a lot for the help!
At the end for the indexing, shouldn't it also have rw_position[rw_loop]= rw_position[rw_index] ? I am asking just so i don't make a mistake.
No, the position and group variables do not need to be modified like this, because their values change (and then are removed) constantly each time the loop is executed, so it is not necessary.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,516
Don't rely on Reals for tracking the Duration. There can be floating point precision errors which lead to cases where your Real's value is slightly off. This will make the spell last longer than it should. For example, you might expect the Real to equal 0 after subtracting 0.50 from it but in reality it ends up as something like 0.0000001.

Integers don't have this issue:
  • Set Variable Ticks[Loop] = Ticks[Loop] + 1
  • If Ticks[Loop] <= 8 then proceed...
 
Status
Not open for further replies.
Top