• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

How to make a DOT using Array

Status
Not open for further replies.
Level 5
Joined
Aug 17, 2014
Messages
106
So, I have tried multiple attempts at creating a spell essentially that function exactly like Envenomed Weapons, but scales with agility. My current issue is that if my attacker attacks a second target after applying the dot to the primary target then the primary target stops taking damage. I understand why this happens it is because the loop I have created will only affect a single target at a time. I have looked up some tutorials on arrays, but not fully understand how to apply it in this scenario. I just want my character to be able to auto-attack a few targets and apply the dot to each one individually.
 
Level 5
Joined
Aug 17, 2014
Messages
106
Index targets hit, not sources of damage. You’ll have to search through the list of targets hit to avoid duplicates (instead refresh the damage). Post your code.
Not entirely sure what you mean by index targets. To be honest i'm a total noob at this. My code is probably awful, I was just testing out different thing to see what worked how.
Nature Arrow Effect
Events
Game - DamageEvent becomes Equal to 1.00
Conditions
Or - Any (Conditions) are true
Conditions
((Attacked unit) has buff Nature Arrow Poison (Non-stacking)) Equal to True
((Attacked unit) has buff Nature Arrow Poison (Stacking)) Equal to True
Actions
Countdown Timer - Start NatureArrow_Timer as a One-shot timer that will expire in 3.00 seconds
Set DamageEventSource = (Damage source)
Set DamageEventTarget = (Attacked unit)
Set ArrayInteger = (ArrayInteger + 1)
Unit - Set the custom value of (Attacked unit) to ArrayInteger
Set ArrayTarget[(Custom value of DamageEventTarget)] = (Attacked unit)
Set Damagething = (0.67 x (Real((Agility of DamageEventSource (Include bonuses)))))
Unit - Set mana of DamageEventSource to ((Mana of DamageEventSource) - 3.00)
For each (Integer A) from 1 to ArrayInteger, do (Actions)
Loop - Actions
Trigger - Turn on Nature Arrow Loop <gen>



Following that the loop is just a loop that deals damage to the target every second
 
Level 9
Joined
Jul 30, 2018
Messages
445
If using unit indexing is not a necessity, you could just adjust the damage for each unit with basically one line of code:
  • Scaling Damage
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Envenomed Spears for (Attacking unit)) Greater than 0
        • Then - Actions
          • Ability - Set Ability: (Unit: (Attacking unit)'s Ability with Ability Code: Envenomed Spears)'s Real Level Field: Damage per Second ('Poi1') of Level: 0 to (Real((Agility of (Attacking unit) (Include bonuses))))
        • Else - Actions
 
Level 42
Joined
Feb 27, 2007
Messages
5,327
@Sabe, I'm curious if that will retroactively affect all active instances of damage or only instances created after the field is changed. Either way it's probably a better solution than triggering the effect if it works.
  • "Attacked Unit" has no relevance here (only in 'unit is attacked' events which you should never ever use). Use DamageEventTarget instead.
  • Why are you checking if the attacked unit has the buff? You should check instead that the damage source has the ability and enough mana.
  • For that matter, what DDS are you using? There's no reason you should have to set DamageEventTarget and DamageEventSource yourself. They should be set automatically by the system.
  • Don't use custom value like this for spells; if any two spells that use custom value affect the same unit then one or both of them will break by overwriting the CV. Instead you want to use a unit indexer system, which automatically assigns a unique number to each unit's CV. You then use this assigned value as an index for parallel arrays: Set DPS[Custom Value of (DamageEventTarget)] = <whatever> for example.
  • Why are you turning on the trigger in a loop? That literally does nothing; once the trigger is already on, turning it on again serves no purpose.
  • The usage of a timer as you have done completely invalidates any attempt at a MUI solution, and in fact will probably break even multiple instances of the poison on different units. You will need to go with a dynamic indexing approach here.
  • Events
    • Game - DamageEvent becomes Equal to 1.00
  • Conditions
    • (Level of NATURE_ARROWS_ABILITY for DamageEventSource) greater than 0
    • (Current mana of DamageEventSource) greater than or equal to 3.00
    • -------- any other check to make sure that the ability is actually 'on' if it's not a permanent effect should be done here --------
  • Actions
    • Set New = 0
    • For each integer NA_Loop from 1 to NA_Index do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (then actions) else do (else actions)
          • If - Conditions
            • NA_Target[NA_Loop] equal to DamageEventTarget
            • NA_Source[NA_Loop] equal to DamageEventSource
          • Then - Actions
            • Set New = NA_Loop
            • Custom script: exitwhen true
          • Else - Actions
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • New equal to 0
      • Then - Actions
        • Set NA_Index = NA_Index + 1
        • Set New = NA_Index
        • Set NA_Target[New] = DamageEventTarget
        • Set NA_Source[New] = DamageEventSource
      • Else - Actions
    • Unit - Set mana of NA_Source[New] = ((Current mana of NA_Source[New]) - 3.00)
    • Set DmgTot = (5.00 x (Agility of NA_Source[New]))
    • Set Dur = 3.00
    • Set NA_Duration[New] = Integer(Dur / TIMER_PERIOD) //this is an integer variable; total duration divided by timer period is how many total ticks of the timer it should run for
    • Set NA_DPS[New] = ((DmgTot/Dur) x TIMER_PERIOD) //multiplied by timer period because it will be dealt every TIMER_PERIOD seconds (think about it)
    • If (All conditions are true) then do (then actions) else do (else actions)
      • If - Conditions
        • NA_Index equal to 1
      • Then - Actions
        • Trigger - Turn on NA Loop Trigger <gen>
      • Else - Actions
  • Events
    • Time - Every TIMER_PERIOD seconds of game-time //set timer period's default value in the variable editor or add this event with a trigger on map init after the variable has been set
  • Conditions
  • Actions
    • For each integer NA_Loop from 1 to NA_Index do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (then actions) else do (else actions)
          • If - Conditions
            • NA_Duration[NA_Loop] less than or equal to 0
            • (NA_Target[NA_Loop] has buff NATURE_ARROWS_BUFF_NONSTACKING) equal to false
            • (NA_Target[NA_Loop] has buff NATURE_ARROWS_BUFF_STACKING) equal to false
          • Then - Actions
            • Set NA_Target[NA_Loop] = NA_Target[NA_Index]
            • Set NA_Source[NA_Loop] = NA_Source[NA_Index]
            • Set NA_Duration[NA_Loop] = NA_Duration[NA_Index]
            • Set NA_DPS[NA_Loop] = NA_DPS[NA_Index]
            • Set NA_Index = NA_Index - 1
            • Set NA_Loop = NA_Loop - 1
          • Else - Actions
            • Unit - Cause NA_Source[NA_Loop] to damage NA_Target[NA_Loop] dealing NA_DPS[NA_Loop] damage of attack type spells and damage type normal
            • Set NA_Duration[NA_Loop] = NA_Duration[NA_Loop] - 1
 
Level 5
Joined
Aug 17, 2014
Messages
106
If using unit indexing is not a necessity, you could just adjust the damage for each unit with basically one line of code:
  • Scaling Damage
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Envenomed Spears for (Attacking unit)) Greater than 0
        • Then - Actions
          • Ability - Set Ability: (Unit: (Attacking unit)'s Ability with Ability Code: Envenomed Spears)'s Real Level Field: Damage per Second ('Poi1') of Level: 0 to (Real((Agility of (Attacking unit) (Include bonuses))))
        • Else - Actions
I had attempted this before with several different spells and I think those actions don't work as intended yet
 
Level 5
Joined
Aug 17, 2014
Messages
106
@Sabe, I'm curious if that will retroactively affect all active instances of damage or only instances created after the field is changed. Either way it's probably a better solution than triggering the effect if it works.
  • "Attacked Unit" has no relevance here (only in 'unit is attacked' events which you should never ever use). Use DamageEventTarget instead.
  • Why are you checking if the attacked unit has the buff? You should check instead that the damage source has the ability and enough mana.
  • For that matter, what DDS are you using? There's no reason you should have to set DamageEventTarget and DamageEventSource yourself. They should be set automatically by the system.
  • Don't use custom value like this for spells; if any two spells that use custom value affect the same unit then one or both of them will break by overwriting the CV. Instead you want to use a unit indexer system, which automatically assigns a unique number to each unit's CV. You then use this assigned value as an index for parallel arrays: Set DPS[Custom Value of (DamageEventTarget)] = <whatever> for example.
  • Why are you turning on the trigger in a loop? That literally does nothing; once the trigger is already on, turning it on again serves no purpose.
  • The usage of a timer as you have done completely invalidates any attempt at a MUI solution, and in fact will probably break even multiple instances of the poison on different units. You will need to go with a dynamic indexing approach here.
  • Events
    • Game - DamageEvent becomes Equal to 1.00
  • Conditions
    • (Level of NATURE_ARROWS_ABILITY for DamageEventSource) greater than 0
    • (Current mana of DamageEventSource) greater than or equal to 3.00
    • -------- any other check to make sure that the ability is actually 'on' if it's not a permanent effect should be done here --------
  • Actions
    • Set New = 0
    • For each integer NA_Loop from 1 to NA_Index do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (then actions) else do (else actions)
          • If - Conditions
            • NA_Target[NA_Loop] equal to DamageEventTarget
            • NA_Source[NA_Loop] equal to DamageEventSource
          • Then - Actions
            • Set New = NA_Loop
            • Custom script: exitwhen true
          • Else - Actions
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • New equal to 0
      • Then - Actions
        • Set NA_Index = NA_Index + 1
        • Set New = NA_Index
        • Set NA_Target[New] = DamageEventTarget
        • Set NA_Source[New] = DamageEventSource
      • Else - Actions
    • Unit - Set mana of NA_Source[New] = ((Current mana of NA_Source[New]) - 3.00)
    • Set DmgTot = (5.00 x (Agility of NA_Source[New]))
    • Set Dur = 3.00
    • Set NA_Duration[New] = Integer(Dur / TIMER_PERIOD) //this is an integer variable; total duration divided by timer period is how many total ticks of the timer it should run for
    • Set NA_DPS[New] = ((DmgTot/Dur) x TIMER_PERIOD) //multiplied by timer period because it will be dealt every TIMER_PERIOD seconds (think about it)
    • If (All conditions are true) then do (then actions) else do (else actions)
      • If - Conditions
        • NA_Index equal to 1
      • Then - Actions
        • Trigger - Turn on NA Loop Trigger <gen>
      • Else - Actions
  • Events
    • Time - Every TIMER_PERIOD seconds of game-time //set timer period's default value in the variable editor or add this event with a trigger on map init after the variable has been set
  • Conditions
  • Actions
    • For each integer NA_Loop from 1 to NA_Index do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (then actions) else do (else actions)
          • If - Conditions
            • NA_Duration[NA_Loop] less than or equal to 0
            • (NA_Target[NA_Loop] has buff NATURE_ARROWS_BUFF_NONSTACKING) equal to false
            • (NA_Target[NA_Loop] has buff NATURE_ARROWS_BUFF_STACKING) equal to false
          • Then - Actions
            • Set NA_Target[NA_Loop] = NA_Target[NA_Index]
            • Set NA_Source[NA_Loop] = NA_Source[NA_Index]
            • Set NA_Duration[NA_Loop] = NA_Duration[NA_Index]
            • Set NA_DPS[NA_Loop] = NA_DPS[NA_Index]
            • Set NA_Index = NA_Index - 1
            • Set NA_Loop = NA_Loop - 1
          • Else - Actions
            • Unit - Cause NA_Source[NA_Loop] to damage NA_Target[NA_Loop] dealing NA_DPS[NA_Loop] damage of attack type spells and damage type normal
            • Set NA_Duration[NA_Loop] = NA_Duration[NA_Loop] - 1

I highly appreciate all the feedback. I'm going to implement all this much later after work and school. Did not know what a Unit Indexer was, but not that makes sense and now understand why my old systems were not working properly! Very much appreciated!
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
Just to keep in mind for future reference.
For any DoT-type spells, you're gonna have to decide either
1. Stacking
OR
2. Refreshing

For example, your ability is that, each time you hit an enemy unit, you will apply a Poison on them dealing 30 damage per second.

STACKING EXAMPLE
If you hit the enemy unit 3 times, you would apply 90 damage per second (each having individual timer).
Let's say you're hitting at a rate of 1 hit per second, then, at the 1st second, the unit will receive 30 damage, at 2nd second, the unit will receive 60 damage, the 3rd second, the unit will receive 90 damage, the 4th second the unit will receive 60 damage, the 5th second the unit will receive 30 damage, and at the 6th second, all timers have finished their duration.

REFRESHING EXAMPLE
Whenever you hit an enemy unit, the TIMER will be refreshed, but the damage would stay the same (30 damage per second).
So, you're still hitting the unit at a rate of 1 hit per second, then, at the 1st second, the unit will receive 30 damage, at 2nd second, the unit will receive 30 damage too (but note that the timer has been refreshed from 2s to 3s) - and it goes on and on until the timer/duration reaches 0s.

There's also batshit technique where you would combine them both, mind you, this is for psychopath.

COMBINED EXAMPLE
Not only the damage stacks each hit, but each timer will have its duration refreshed upon taking a hit - so you could have your 1st instance to have the same duration as your 10th instance as long as your unit keep attacking the unit before the 1st instance timer runs out.

So, decide what's the best for your DoT spells wayyy before you start developing them.
 
Level 9
Joined
Jul 30, 2018
Messages
445
I had attempted this before with several different spells and I think those actions don't work as intended yet

They work just fine. The only thing to note is that the level is 0-indexed, meaning that level 0 on the trigger = level 1 in the ability, level 1 on the trigger = level 2 in the ability, etc. As someone who has played around with the editor since pretty much the release of the game back in 2003, I highly suggest using these new natives. Never before has stat scaling abilities been this easy to make.
 
Level 5
Joined
Aug 17, 2014
Messages
106
They work just fine. The only thing to note is that the level is 0-indexed, meaning that level 0 on the trigger = level 1 in the ability, level 1 on the trigger = level 2 in the ability, etc. As someone who has played around with the editor since pretty much the release of the game back in 2003, I highly suggest using these new natives. Never before has stat scaling abilities been this easy to make.
Hmmm, you know I did not know that and perhaps I was doing it incorrectly before. If it works out I'll let you know, and yeah those definitely can be game changing in terms of convenience.
 
Level 5
Joined
Aug 17, 2014
Messages
106
They work just fine. The only thing to note is that the level is 0-indexed, meaning that level 0 on the trigger = level 1 in the ability, level 1 on the trigger = level 2 in the ability, etc. As someone who has played around with the editor since pretty much the release of the game back in 2003, I highly suggest using these new natives. Never before has stat scaling abilities been this easy to make.
It did not seem to work for me. Check it out maybe I did something wrong. This was just me testing the functions. I wanted to to set the bonus armor from the item spell Bonus Armor to 50 whenever any action was performed.

  • BearForm Armor
    • Events
      • Unit - A unit Is issued an order targeting an object
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Aspect of the Bear
    • Actions
      • Ability - Set Ability: (Unit: (Triggering unit)'s Ability with Ability Code: Bear Form Armor (Shapeshifter))'s Integer Level Field: Defense Bonus ('Idef') of Level: 0 to 50
 
Level 9
Joined
Jul 30, 2018
Messages
445
Some abilities that give stat boosts and such might require a refresh. Try lowering the level of the ability and then increasing it again straight away. Or disabling and then re-enabling it again.
 
Level 5
Joined
Aug 17, 2014
Messages
106
Some abilities that give stat boosts and such might require a refresh. Try lowering the level of the ability and then increasing it again straight away. Or disabling and then re-enabling it again.
Ok I'll try that out it was giving me similar issues to I h devotion aura
 
Status
Not open for further replies.
Top