• 🏆 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] Help with a DoT ability

Status
Not open for further replies.
Level 8
Joined
Mar 15, 2007
Messages
230
I'm having trouble with a DoT ability. The way it's supposed to work is that after channeling the ability for a few seconds, a dummy unit is created at the target location that casts a version of Thunderclap, and the units affected are supposed to take damage over time from the caster for as long as they have the buff. Well, the damage over time is the part of the ability that isn't working.

Here are my triggers:
  • Get Condemn Point
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Condemn (Inquisitor)
    • Actions
      • Set VariableSet UDexNew = (Custom value of (Casting unit))
      • Set VariableSet Condemn_Point[UDexNew] = (Target point of ability being cast)
  • Condemn Damage
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Condemn (Inquisitor)
    • Actions
      • Set VariableSet UDexNew = (Custom value of (Casting unit))
      • Unit - Create 1 Condemn Dummy for (Owner of (Casting unit)) at Condemn_Point[UDexNew] facing Default building facing degrees
      • Unit - Set level of Condemn dummy (Inquisitor) for (Last created unit) to (Level of Condemn (Inquisitor) for (Casting unit))
      • Unit - Order (Last created unit) to Human Mountain King - Thunder Clap.
      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Pick every unit in Condemn_Group and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) belongs to an enemy of (Owner of (Casting unit)).) Equal to True
              • ((Picked unit) is A structure) Equal to False
              • ((Picked unit) is alive) Equal to True
              • ((Picked unit) is hidden) Equal to False
            • Then - Actions
              • Set VariableSet UDex = (Custom value of (Picked unit))
              • Set VariableSet Chosen_Caster[UDex] = (Casting unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is in Condemn_Group.) Equal to False
                • Then - Actions
                  • Unit Group - Add (Picked unit) to Condemn_Group
                • Else - Actions
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Condemn DoT <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Condemn DoT <gen>
        • Else - Actions
      • Custom script: call RemoveLocation (udg_Condemn_Point[udg_UDexNew])
  • Condemn DoT
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Condemn_Group and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) has buff Condemn (Inquisitor)) Equal to True
            • Then - Actions
              • Set VariableSet UDex = (Custom value of (Picked unit))
              • Unit - Cause Condemn_Caster[UDex] to damage (Picked unit), dealing (2.00 x (Real((Level of Condemn (Inquisitor) for Condemn_Caster[UDex])))) damage of attack type Spells and damage type Normal
            • Else - Actions
              • Unit Group - Remove (Picked unit) from Condemn_Group.
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in Condemn_Group) Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
 
Level 3
Joined
Mar 18, 2020
Messages
20
I can't verify if everything else is correct but it's generally good practice to destroy repeatedly picked unit groups after each reference, even if it is a consistent unit group with units only being added or removed. I believe this trigger may leak any time there are no units in udg_Condemn_Group.
 
Level 12
Joined
Feb 5, 2018
Messages
521
I might be blind, but I can't actually see where you set the unit group. Set variable Condemn_Group = xxx

Therefore if the unit group is never set to anything the unit group is empty. Which means it cannot damage any units.
  • empty.gif
    joinbottom.gif
    set.gif
    Set VariableSet Condemn_Point[UDexNew] = (Target point of ability being cast)
empty.gif
join.gif
set.gif
Set VariableSet UDexNew = (Custom value of (Casting unit))
empty.gif
join.gif
set.gif
Set VariableSet UDexNew = (Custom value of (Casting unit))
set.gif
Set VariableSet UDex = (Custom value of (Picked unit))
empty.gif
line.gif
empty.gif
empty.gif
line.gif
join.gif
set.gif
Set VariableSet Chosen_Caster[UDex] = (Casting unit)
join.gif
set.gif
Set VariableSet UDex = (Custom value of (Picked unit))

These are all the six (6) variables I found in your trigger.
 
Level 8
Joined
Mar 15, 2007
Messages
230
You are not blind, DoomBlade. I forgot to set the value of the unit group. I also used the wrong variable (Chosen_Caster instead of Condemn_Caster). I fixed these things, and the DoT is STILL not working. I'm not sure what the problem is.
 
Level 14
Joined
Nov 17, 2010
Messages
1,265
Are the triggers posted the most up to date triggers? If so you are trying to pick every unit in condemn group and if they are not in the group you try to add them. The problem is there will be no picked units at all if there aren’t any in the condemn group. You need to pick every unit within a certain range and then run through your conditions in your if,then,else statement. If they match all the conditions and aren’t in the group you will add them to the group now.

Basically you just have to change the pick every unit in condemn group to pick every unit within x range of condemn point in your Condemn Damage trigger
 
Level 8
Joined
Mar 15, 2007
Messages
230
Ok, here are my updated triggers:
  • Get Condemn Point
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Condemn (Inquisitor)
    • Actions
      • Set VariableSet UDexNew = (Custom value of (Casting unit))
      • Set VariableSet Condemn_Point[UDexNew] = (Target point of ability being cast)
  • Condemn Damage
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Condemn (Inquisitor)
    • Actions
      • Set VariableSet UDexNew = (Custom value of (Casting unit))
      • Unit - Create 1 Condemn Dummy for (Owner of (Casting unit)) at Condemn_Point[UDexNew] facing Default building facing degrees
      • Unit - Set level of Condemn dummy (Inquisitor) for (Last created unit) to (Level of Condemn (Inquisitor) for (Casting unit))
      • Unit - Order (Last created unit) to Human Mountain King - Thunder Clap.
      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Pick every unit in (Units within 300.00 of Condemn_Point[UDexNew].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) belongs to an enemy of (Owner of (Casting unit)).) Equal to True
              • ((Picked unit) is A structure) Equal to False
              • ((Picked unit) is alive) Equal to True
              • ((Picked unit) is hidden) Equal to False
            • Then - Actions
              • Set VariableSet UDex = (Custom value of (Picked unit))
              • Set VariableSet Condemn_Caster[UDex] = (Casting unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is in Condemn_Group.) Equal to False
                • Then - Actions
                  • Unit Group - Add (Picked unit) to Condemn_Group
                • Else - Actions
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Condemn DoT <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Condemn DoT <gen>
        • Else - Actions
      • Custom script: call RemoveLocation (udg_Condemn_Point[udg_UDexNew])
  • Condemn DoT
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Condemn_Group and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) has buff Condemn (Inquisitor)) Equal to True
            • Then - Actions
              • Set VariableSet UDex = (Custom value of (Picked unit))
              • Unit - Cause Condemn_Caster[UDex] to damage (Picked unit), dealing (2.00 x (Real((Level of Condemn (Inquisitor) for Condemn_Caster[UDex])))) damage of attack type Spells and damage type Normal
            • Else - Actions
              • Unit Group - Remove (Picked unit) from Condemn_Group.
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in Condemn_Group) Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
 
Level 14
Joined
Nov 17, 2010
Messages
1,265
All I can see is that maybe you need to give your dummy the condemn ability, unless you already give it the ability in the object editor.

And you have to make sure the enemies are indeed receiving the condemn buff.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,537
Use Triggering Unit instead of Casting Unit if that's the issue. Triggering Unit won't get lost as it's treated like a local variable. You can also reference "Triggering Player" instead of "Owner of casting unit", it's more efficient and works just the same. I don't think this will fix it though, but it's worth a shot.

Anyway, create some Text Messages to debug it. In your Condemn DoT trigger add a Display Text Message above/below "Turn Off This Trigger" that says something like "Timer Off". And create a Text Message above/below "Cause Damage" so you can see if it it's trying to deal damage every 1.00 second. Another message next to "Remove picked unit from Condemn Group" would be useful as well.

Remember that buffs aren't applied immediately, but your timer IS turned on immediately. Meaning that there's a chance that your DoT Timer will remove the units from the Condemn Group right away since they might not have the buff.
 
Level 8
Joined
Mar 15, 2007
Messages
230
Use Triggering Unit instead of Casting Unit if that's the issue...
Remember that buffs aren't applied immediately, but your timer IS turned on immediately. Meaning that there's a chance that your DoT Timer will remove the units from the Condemn Group right away since they might not have the buff.
Alright so I modified the Condemn Damage trigger and now it the DoT is working. I had suspected that the units were being removed from the unit group just before the buff was applied, but I wasn't sure. I added a slight delay before the timer is turned on, and now it is working. I also did as you suggested, Uncle and I changed "casting unit" to "triggering unit".
  • Condemn Damage
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Condemn (Inquisitor)
    • Actions
      • Set VariableSet UDexNew = (Custom value of (Casting unit))
      • Unit - Create 1 Condemn Dummy for (Owner of (Casting unit)) at Condemn_Point[UDexNew] facing Default building facing degrees
      • Unit - Set level of Condemn dummy (Inquisitor) for (Last created unit) to (Level of Condemn (Inquisitor) for (Casting unit))
      • Unit - Order (Last created unit) to Human Mountain King - Thunder Clap.
      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Pick every unit in (Units within 300.00 of Condemn_Point[UDexNew].) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True
              • ((Picked unit) is A structure) Equal to False
              • ((Picked unit) is alive) Equal to True
              • ((Picked unit) is hidden) Equal to False
            • Then - Actions
              • Set VariableSet UDex = (Custom value of (Picked unit))
              • Set VariableSet Condemn_Caster[UDex] = (Triggering unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is in Condemn_Group.) Equal to False
                • Then - Actions
                  • Unit Group - Add (Picked unit) to Condemn_Group
                • Else - Actions
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Condemn DoT <gen> is on) Equal to False
        • Then - Actions
          • Wait 0.20 seconds
          • Trigger - Turn on Condemn DoT <gen>
        • Else - Actions
      • Custom script: call RemoveLocation (udg_Condemn_Point[udg_UDexNew])
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,537
You're still using Casting unit/owner of casting unit a few times throughout the trigger, but it's not a big deal as it's a very small/probably negligible optimization.

So the only problem left is that you're doing this after a 0.20 second wait:
  • Custom script: call RemoveLocation (udg_Condemn_Point[udg_UDexNew])
Which means that UDexNew can change during that time and remove the wrong point (a non-existent point in some cases) creating a Memory Leak.

Solution:
Move the RemoveLocation Action above the If Then Else statement, so it happens before the 0.20 second Wait but AFTER the Pick Every Unit function.
 
Status
Not open for further replies.
Top