• 🏆 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!

[Trigger] Help with Damage over Time triggered spell.

Status
Not open for further replies.
Level 4
Joined
Oct 9, 2009
Messages
50
Hello. I've been coming to these forums and this website ever since I began using the World Editor. Thanks to some of the brilliant members and extensive searching, you wonderful people have answered countless questions before I've even had to ask.

However, I believe I've hit my first "I'm stumped, can't figure it out, don't see anything that could fix it" moment.

I've tried learning JASS and it's very hard, I have mild comprehension problems. I've been using the basic GUI and Triggers to create spells and abilities, and it's worked so far. The ability that is breaking the mold however, is a Damage Over Time + Self Heal for damage done.

Basically, I -want- the Spell to strike one enemy, stun him, deal periodic damage equal to twice the caster's Intellect every .99 seconds, and heal the caster for the same amount. After a lot of failed toying around with the Shadow Strike spell, I decided to try and make the damage applied in intervals. This is what I have so far.
Code:
Hatred Feeds on Terror
    Events
        Unit - A unit Finishes casting an ability
    Conditions
        (Ability being cast) Equal to He Feeds On Your Terror 
    Actions
        Set TerrorCaster = (Casting unit)
        Set TerrorTarget = (Target unit of ability being cast)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                (((Target unit of ability being cast) is A structure) Equal to False) and (((Target unit of ability being cast) is Mechanical) Equal to False)
            Then - Actions
                Unit - Set life of TerrorCaster to ((Life of TerrorCaster) + (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
                Unit - Cause TerrorCaster to damage TerrorTarget, dealing (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))) damage of attack type Spells and damage type Normal
                Wait 0.99 seconds
                Unit - Cause TerrorCaster to damage TerrorTarget, dealing (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))) damage of attack type Spells and damage type Normal
                Unit - Set life of TerrorCaster to ((Life of TerrorCaster) + (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
                Wait 0.99 seconds
                Unit - Cause TerrorCaster to damage TerrorTarget, dealing (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))) damage of attack type Spells and damage type Normal
                Unit - Set life of TerrorCaster to ((Life of TerrorCaster) + (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
            Else - Actions
                Do nothing
Notes:
-I've based the spell on Storm Bolt, removed damage, made it into a single-rank ability, and left it at a 3 second stun.
-Everything works except the damage done to the Target. It recovers life for the casting unit at .99 second intervals doing 2xCasting Hero's INT stat. It -doesn't- damage the target.
-It is intended to be a level 6 ultimate ability. Could it be a problem with the Damage Type - Normal function?
-This ability has been tested on Heroes and Non-hero units, none of which were magic immune.
-I read that (Target unit of Ability being cast) doesn't persist through Wait commands, so I set both the casting unit and the cast-upon unit to their own variables.

Also: Will eventually try and figure out how to add Floating Combat Text that reads correct values. Is that possible?

Thank you for any assistance that is able to be offered.
 
Level 6
Joined
Mar 22, 2009
Messages
276
Maybe as an ultimate ability you can use
  • Unit - Set life of TerrorTarget to ((Life of TerrorTarget) - (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
to damage the target that ignores armor and magic reductions.

HINT:
using wait function is not good in DmgOverTime. better use a loop system for DoT.
remove the Do Nothing line in else action, it will make your trigger running slow.

  • Main Spell
    • Events
      • Unit - Starts the effect of an ability
    • Conditions
      • Ability being cast is equal to He Feeds in Your Terror
    • Actions
      • Set i = 0
      • Set TerrorCaster = (Casting unit)
      • Set TerrorTarget = (Target unit of ability being cast)
      • Unit Group - Add TerrorTarget to DoTGroup
  • DoT
    • Events
      • Time - Every 0.99 seconds of game time
    • Conditions
      • ((DoTGroup) is empty) Equal to False
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • i less than or equal to 3
        • Then - Actions
          • Unit - Set life of TerrorCaster to ((Life of TerrorCaster) + (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
          • Unit - Set life of TerrorTarget to ((Life of TerrorTarget) - (Real(((Intelligence of TerrorCaster (Include bonuses)) x 2))))
          • Set i = i + 1
          • Else - Actions
            • Unit Group - Remove TerrorTarget to DoTGroup
i = integer
DoTGroup = unit group
NOTE: its not yet MUI
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,240
This is how I do DoT thingies:

  • Add to burn group
    • Events
    • Conditions
    • Actions
      • ...something happens here...
      • Unit Group - Add (unit) to Burn_Group
      • Special Effect - Create a special effect attached to the chest of (unit) using Environment\NightElfBuildingFire\ElfLargeBuildingFire2.mdl
      • Hashtable - Save Handle Of(Last created special effect) as (Key eff1) of (Key (unit)) in DoT_Hash
      • -------- ------------------------------ --------
      • Hashtable - Save 4.00 as (Key time) of (Key (Picked unit)) in DoT_Hash
      • Hashtable - Save (1.00 + (Real((Level of Spell for unit that casts the spell)))) as (Key dmg) of (Key (unit)) in DoT_Hash
      • Hashtable - Save Handle Of <casting unit> as (Key caster) of (Key (unit)) in DoT_Hash
      • -------- ------------------------------ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Burn <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Burn <gen>
          • Else - Actions

I create a burn effect on the unit, and save a handle of the effect to a hashtable, along with the duration of the burn effect, the casting unit and damage it does. Then turn on the DoT trigger.

  • Burn
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Burn_Group and do (Actions)
        • Loop - Actions
          • Set Temp_Unit_1 = (Picked unit)
          • Set Temp_Real_1 = (Load (Key time) of (Key (Picked unit)) from DoT_Hash)
          • -------- ------------------------------ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Temp_Real_1 Greater than 0.00
            • Then - Actions
              • Set Temp_Unit_2 = (Load (Key caster) of (Key (Picked unit)) in DoT_Hash)
              • -------- ------------------------------ --------
              • Unit - Cause Temp_Unit_2 to damage Temp_Unit_1, dealing (Load (Key dmg) of (Key (Picked unit)) from DoT_Hash) damage of attack type Spells and damage type Normal
              • -------- ------------------------------ --------
              • Set Temp_Real_1 = (Temp_Real_1 - 0.03)
              • -------- ------------------------------ --------
              • Hashtable - Save Temp_Real_1 as (Key time) of (Key (Picked unit)) in DoT_Hash
              • -------- ------------------------------ --------
            • Else - Actions
              • Set Temp_Effect = (Load (Key eff1) of (Key (Picked unit)) in DoT_Hash)
              • Special Effect - Destroy Temp_Effect
              • -------- ------------------------------ --------
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in DoT_Hash
              • -------- ------------------------------ --------
              • Unit Group - Remove (Picked unit) from Burn_Group
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Burn_Group is empty) Equal to True
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
I apply the damage and reduce the timer with each loop. When the timer hits 0, the unit has burned for the set duration, and the effect gets destroyed, burning stops. 0.03 seconds might be a bit too low time for a trigger like this.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,522
You can use my system if you want.

JASS:
library dotStack
    private struct dotDat
        unit source
        unit target
        integer dps
        integer length
        string fx
        method onCreate takes nothing returns nothing
            set this.source=null
            set this.target=null
            set this.dps=0
            set this.dps=1
            set this.fx=""
        endmethod
    endstruct
    
    globals
        private constant real REPEATTIME=.5 //How often the periodic damage runs. DPS will automatically update.
        private dotDat array dotDB
        private integer dbIndex=-1
        private timer time=CreateTimer()
    endglobals
    
    private function p takes nothing returns nothing
        local dotDat tempDat
        local integer index=0
        local effect fx
        loop
            exitwhen index>dbIndex
            set tempDat=dotDB[index]
            set fx=AddSpecialEffect(tempDat.fx,GetUnitX(tempDat.target),GetUnitY(tempDat.target))
            call DestroyEffect(fx)
            call UnitDamageTarget(tempDat.source,tempDat.target,tempDat.dps*REPEATTIME,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set tempDat.length=tempDat.length-1
            if tempDat.length<1 or GetWidgetLife(tempDat.target)<1 then
                call tempDat.destroy()
                set dotDB[index]=dotDB[dbIndex]
                set dbIndex=dbIndex-1
                if dbIndex==-1 then
                    call PauseTimer(time)
                endif
            endif
            set index=index+1
        endloop
    endfunction
        
    function addDot takes unit source, unit target, integer dps, integer length, string fx returns nothing
        local dotDat tempDat=dotDat.create()
        set tempDat.source=source
        set tempDat.target=target
        set tempDat.dps=dps
        set tempDat.length=length
        set tempDat.fx=fx
        set dbIndex=dbIndex+1
        set dotDB[dbIndex]=tempDat
        if dbIndex==0 then
            call TimerStart(time,REPEATTIME,true,function p)
        endif
    endfunction
endlibrary

And heres an example of how I use it for some ability:

JASS:
    private function a takes nothing returns nothing
        local integer base=GetRandomInt(1,70)
        call UnitDamageTarget(GetSpellAbilityUnit(),GetSpellTargetUnit(),base,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
        call addDot(GetSpellAbilityUnit(),GetSpellTargetUnit(),1,70-base,"Abilities\\Weapons\\Bolt\\BoltImpact.mdl")
    endfunction

Basically says damage a unit for random number from 1-70, then 1 damage per second for 70 minus that random number seconds.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
he wants both a dot and a heal in the same time each 0.99 second if you guys didn't read it so clearly. Basiclly I could advert paladons Dot system but that wont heal the unit.

Damage target don't fail it's tests but you made it with waits. Sorry to tell you this but it's very bad.

You need atleast two triggers if you don't wanna JASS it.

Also don't use Set HP as damage cause then you wont get bounty so damage target it is.

Easiest is to use Makers version and add a small line of healing which will be Set HP +
 
Level 6
Joined
Mar 20, 2008
Messages
208
This is a jass version of it.

JASS:
function Trig_dummytrigger_Actions takes nothing returns nothing
       local unit u = GetTriggerUnit()     //The casting unit
       local unit z = GetSpellTargetUnit() //The targeted unit
       local integer i = 2 //Set this to the duration
       local integer intdamage = 2*GetHeroInt(u,true) 

//set GetHeroInt's true to false to exclude bonus int
//base the spell off of storm bolt, have it deal the initial damage and stun

//This is to make sure the initial damage doesn't overlap with the DoT
       call TriggerSleepAction(1) 

       loop 
            //GetUnitStates checks the target's life per iteration
            exitwhen i == 3 or GetUnitState(z,UNIT_STATE_LIFE) < 1
                //Damages the target with the intdamage variable
                call UnitDamageTarget(u,z,intdamage,true, false, ATTACK_TYPE_MAGIC,DAMAGE_TYPE_DEATH,WEAPON_TYPE_WHOKNOWS)
                //Heals the caster
               call SetUnitState(u,UNIT_STATE_LIFE, (GetUnitState(u,UNIT_STATE_LIFE) + intdamage))

            call TriggerSleepAction(1) //Waits 1 second
            set i = i +1
       endloop


       //clears out leaks
       set u = null
       set z = null

endfunction
 
Status
Not open for further replies.
Top