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

[Spell] Maledict Counting HP Lost.

Status
Not open for further replies.
Level 9
Joined
Jul 7, 2011
Messages
275
Hello everyone.

I'm here asking for help, for I finish of do the Maledict skill.

I already do I think similar the damage part (not bonus): Enemies lose 5, 10, 15, 20 hp / sec.

  • [Events
  • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
  • Unit Group - Pick every unit in Maledict_Enemies_Units[1] and do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Maledict_Skill for unit_maledict) Equal to 1
          • ((Picked unit) has buff Maledict ) Equal to True
        • Then - Actions
          • Unit - Cause unit_maledict to damage (Picked unit), dealing 5.00 damage of attack type Chaos and damage type Normal
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Maledict_Skill for unit_maledict) Equal to 2
          • ((Picked unit) has buff Maledict ) Equal to True
        • Then - Actions
          • Unit - Cause unit_maledict to damage (Picked unit), dealing 10.00 damage of attack type Chaos and damage type Normal
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Maledict_Skill for unit_maledict) Equal to 3
          • ((Picked unit) has buff Maledict ) Equal to True
        • Then - Actions
          • Unit - Cause unit_maledict to damage (Picked unit), dealing 15.00 damage of attack type Chaos and damage type Normal
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Maledict_Skill for unit_maledict) Equal to 4
          • ((Picked unit) has buff Maledict ) Equal to True
        • Then - Actions
          • Unit - Cause unit_maledict to damage (Picked unit), dealing 20.00 damage of attack type Chaos and damage type Normal
        • Else - Actions

But now I wish to do the bonus damage part, which every 100 HP lost adds 10/20/30/40 damage. Problem is that I do not know the logic of making the Editor count with buff, when enemies taken more than 100 damage, etc for add this new damage.

Maledict that I'm doing will not be exactly of Dota. The ability will work with non hero units, and will leave an effect buff.

  • Events
    • Unit - A unit Learns a skill
  • Conditions
    • (Learned Hero Skill) Equal to Maledic
  • Actions
    • Set Maledict_Skill = Maledict
    • Unit - Create 1 Maledict Dummy for (Owner of (Learning Hero)) at (Random point in (Playable map area)) facing Default building facing degrees
    • Set Maledict_Dummy[1] = (Last created unit)

  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • (Ability being cast) Equal to Maledict_Skill
  • Actions
    • Unit - Move Maledict_Dummy[1] instantly to (Target point of ability being cast)
    • Unit Group - Pick every unit in (Units within 150.00 of (Position of Maledict_Dummy[1]) matching (((Owner of (Matching unit)) is an enemy of (Owner of Maledict_Dummy[1])) Equal to True)) and do (Actions)
      • Loop - Actions
        • Set Maledict_Taken_Cast = (Picked unit)
        • Unit Group - Add Maledict_Taken_Cast to Maledict_Enemies_Units[1]
    • Wait 12.00 seconds
    • Unit Group - Remove Maledict_Taken_Cast from Maledict_Enemies_Units[1]

  • Events
    • Unit - A unit enters (Playable map area)
  • Conditions
    • (Unit-type of (Entering unit)) Equal to Witch Doctor
  • Actions
    • Set unit_maledict = (Entering unit)
 
Level 13
Joined
Oct 12, 2016
Messages
769
Alright. So first, can there be more than 1 caster for Maledict?
  • If you want this to be MUI (Multi-Unit Instanceable), then this will be complicated.
  • If there is only 1 unit per player with Maledict, then we need to make the variable "unit_maledict" an array for multiple player numbers.

Second, if it is 1 caster per player, then you need an integer variable array for the damage count. We'll call it "maledict_damage[x]" where [x] is the array for the player number.

Third, we'll need to remove memory leaks with a temporary point. Memory leaks are a pain, but if you don't remove them, you'll lag your map up a lot.
For this, you'll need 2 temporary variables:
  • TempPoint for point removal
  • TempGroup for unit group removal.
More information on memory leaks here: Things That Leak

Now, you've got the right idea for using dummy units and a periodic timer. We just have to refine it.
I can make an example after work (since I need something like this too :D)
 
Last edited:
Level 9
Joined
Jul 7, 2011
Messages
275
Thanks for the information on multiple units. And I think the leak will not happen because the cooldown of the skill is longer than duration, after 12 seconds, removes the units of the variable Maledict_Enemies_Units [1].
 
I would suggest using unit Indexer to create this spell and also limit the spell to 1 affection on each 1 unit at the same time with overwritting old if affected twice.
An Unit Indexer provides you an unique Index for each unit existing allowing easy unit oriented data attachment.​
That will simple down alot.

Now when you use Unit Indexer you need 1 group containing all affected Units, for each unit save its buffer, dps, remaining pulses and damage taken.
For the damage taken thing you would need an any unit takes damage trigger or create an trigger to which you add new events for all units beeing cursed make sure you do not register a unit twice (when registering a specific unit multiple times it will trigger multiple times which is unwanted).
 
Level 13
Joined
Oct 12, 2016
Messages
769
I've got the beginnings of a Maledict spell for 1 unit per player. It's missing that damage bonus, but that's doable with the unit indexer Tasyen suggested.
I do recommend a 2-trigger structure like this to not lag up a game so much with a continuous periodic event.
You also want to remove units from unit groups who are dead or no longer affected by the debuff in the periodic event, and without relying on a wait action:

Trigger 1:
  • Maledict Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Maledict
    • Actions
      • Set MaledictIntCheck = 0
      • Set MaledictLevel[(Player number of (Owner of (Triggering unit)))] = (Level of (Ability being cast) for (Triggering unit))
      • Set MaledictCaster[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempGroup = (Units within 500.00 of TempPoint)
      • Unit Group - Pick every unit in TempGroup 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
              • ((Unit-type of (Picked unit)) is Mechanical) Equal to False
              • ((Picked unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True
            • Then - Actions
              • Unit Group - Add (Picked unit) to MaledictGroup[(Player number of (Owner of (Triggering unit)))]
            • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Custom script: call DestroyGroup(udg_TempGroup)
      • Trigger - Turn on Maledict Effect <gen>
Trigger 2: (turned off at start)
  • Maledict Effect
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer TempInt) from 1 to PlayerCount, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in MaledictGroup[TempInt] and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) has buff Maledict Debuff) Equal to True
                  • ((Picked unit) is alive) Equal to True
                • Then - Actions
                  • Unit - Cause MaledictCaster[TempInt] to damage (Picked unit), dealing ((Real(MaledictLevel[TempInt])) x 10.00) damage of attack type Spells and damage type Fire
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from MaledictGroup[TempInt]
          • Set MaledictIntCheck = (MaledictIntCheck + (Number of units in MaledictGroup[TempInt]))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MaledictIntCheck Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
The spell used to deliver the debuff can vary greatly, depending on if you want it point blank or in a targeted area.
 
Last edited:
Level 9
Joined
Jul 7, 2011
Messages
275
Wark I have remade some triggers, similar to what you posted here. But I did not understand some variables, I'll quote them here: MaledictIntCheck, TempInt, PlayerCount.
As I think you have good knowledge of Trigger, if you want to explain the variables and also how I will use "Unit Indexer" to do the part of counting hp lost and apply the bonus damage the units hit by the skill.

  • Maledict
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Maledict_Skill
    • Actions
      • Set MaledictIntCheck = 0
      • Set Maledict_Skill_Level[(Player number of (Owner of (Casting unit)))] = (Level of Maledict_Skill for (Casting unit))
      • Set MaledictCaster[(Player number of (Owner of (Casting unit)))] = (Casting unit)
      • Set MaledictTempPoint = (Position of (Casting unit))
      • Set MaledictTempGroup = (Units within 500.00 of MaledictTempPoint)
      • Unit - Move Maledict_Dummy[1] instantly to (Target point of ability being cast)
      • Unit Group - Pick every unit in MaledictTempGroup 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
              • ((Unit-type of (Picked unit)) is Mechanical) Equal to False
              • ((Picked unit) belongs to an enemy of (Owner of (Casting unit))) Equal to True
            • Then - Actions
              • Unit Group - Add (Picked unit) to Maledict_Group[(Player number of (Owner of (Casting unit)))]
            • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Custom script: call DestroyGroup(udg_TempGroup)
      • Trigger - Turn on Maledict Damage <gen>

  • Maledict Damage
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Maledict_TempInteger) from 1 to Maledict_PlayerCount, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in Maledict_Group[Maledict_TempInteger] 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) has buff Maledict ) Equal to True
                  • (Level of Maledict_Skill for MaledictCaster[Maledict_TempInteger]) Equal to 1
                • Then - Actions
                  • Unit - Cause MaledictCaster[Maledict_TempInteger] to damage (Picked unit), dealing 5.00 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from Maledict_Group[Maledict_TempInteger]
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) has buff Maledict ) Equal to True
                  • (Level of Maledict_Skill for MaledictCaster[Maledict_TempInteger]) Equal to 2
                • Then - Actions
                  • Unit - Cause MaledictCaster[Maledict_TempInteger] to damage (Picked unit), dealing 10.00 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from Maledict_Group[Maledict_TempInteger]
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) has buff Maledict ) Equal to True
                  • (Level of Maledict_Skill for MaledictCaster[Maledict_TempInteger]) Equal to 3
                • Then - Actions
                  • Unit - Cause MaledictCaster[Maledict_TempInteger] to damage (Picked unit), dealing 15.00 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from Maledict_Group[Maledict_TempInteger]
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) has buff Maledict ) Equal to True
                  • (Level of Maledict_Skill for MaledictCaster[Maledict_TempInteger]) Equal to 4
                • Then - Actions
                  • Unit - Cause MaledictCaster[Maledict_TempInteger] to damage (Picked unit), dealing 20.00 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from Maledict_Group[Maledict_TempInteger]
              • Set MaledictIntCheck = (MaledictIntCheck + (Number of units in Maledict_Group[Maledict_TempInteger]))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MaledictIntCheck Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
 
Level 13
Joined
Oct 12, 2016
Messages
769
The player count's mostly for if more than 1 player can use Maledict. Basically, player count is the highest player number available in your map.
"TempInt" is just a temporary integer used in the loop. It increments temp int by +1 each time it goes through the loop. It's faster than using the "integer A" or "integer B" loops, since it's a separate specified variable.

Basically, the loop's going through each maledict group for each separate player and doing separate damage based on ability levels for each player.
 
Level 9
Joined
Jul 7, 2011
Messages
275
My post more near above I posted before closing the Editor, it warned that I remember that the custom script was not correct (written wrong for language?).

Then I'm going to revise Unit Indexer again, I'm going to try to find some functions, etc. to try to communicate to World Editor that every 100 hp lost, the unit takes extra damage.
 
Last edited:
you try to remove udg_TempPoint but it should be: udg_MaledictTempPoint
For the group it is the same.
udg_TempGroup -> udg_MaledictTempGroup

One could create damage events for each unit affect by that spell.
Kinda like that
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • ((Picked unit) is in Maledict_DamageGroup) Equal to False
    • Then - Actions
      • Trigger - Add to Maledict TakeDamage <gen> the event (Unit - (Picked unit) Takes damage)
      • Unit Group - Add (Picked unit) to Maledict_DamageGroup
    • Else - Actions
  • Maledict TakeDamage
    • Events
    • Conditions
      • ((Triggering unit) is in Maledict_Affected) Equal to True
    • Actions
      • Set UDex = (Custom value of (Triggering unit))
      • Set Maledict_DamageTaken[UDex] = (Maledict_DamageTaken[UDex] + (Damage taken))
or import a damage detection System aka damage engine and use it's provided any unit takes damage event.
 
Last edited:
Level 9
Joined
Jul 7, 2011
Messages
275
I tried to make a comparator, every 100 hp lost, take x extra damage and it did not work as also the structure of @Wark that showed me.

  • Maledict
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Maledict_Skill
    • Actions
      • Set MaledictIntCheck = 0
      • Set Maledict_Skill_Level[(Player number of (Owner of (Casting unit)))] = (Level of Maledict_Skill for (Casting unit))
      • Set MaledictCaster[(Player number of (Owner of (Casting unit)))] = (Casting unit)
      • Set MaledictTempPoint = (Position of (Casting unit))
      • Set MaledictTempGroup = (Units within 500.00 of MaledictTempPoint)
      • Unit - Move Maledict_Dummy[1] instantly to (Target point of ability being cast)
      • Trigger - Turn on Maledict Damage HP Couting <gen>
      • Trigger - Turn on Maledict Damage Extra <gen>
      • Unit Group - Pick every unit in MaledictTempGroup 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
              • ((Unit-type of (Picked unit)) is Mechanical) Equal to False
              • ((Picked unit) belongs to an enemy of (Owner of (Casting unit))) Equal to True
            • Then - Actions
              • Unit Group - Add (Picked unit) to Maledict_Group[(Player number of (Owner of (Casting unit)))]
              • Trigger - Add to Maledict Damage HP Couting <gen> the event (Unit - (Picked unit) Takes damage)
            • Else - Actions
      • Custom script: call RemoveLocation(udg_MaledictTempPoint)
      • Custom script: call DestroyGroup(udg_MaledictTempGroup)
      • Trigger - Turn on Maledict Damage <gen>

  • Maledict Damage Extra
    • Events
      • Time - Every 4.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Maledict_TempInteger) from 1 to Maledict_PlayerCount, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in Maledict_Group[Maledict_TempInteger] 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) has buff Maledict ) Equal to True
                • Then - Actions
                  • Unit - Cause MaledictCaster[Maledict_TempInteger] to damage (Picked unit), dealing Maledict_Damage_HP damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • Unit Group - Remove (Picked unit) from Maledict_Group[Maledict_TempInteger]
  • Maledict Damage HP Couting
    • Events
    • Conditions
      • ((Triggering unit) has buff Maledict ) Equal to True
    • Actions
      • Set UDex = (Custom value of (Triggering unit))
      • Set MaledictDamageTaken[UDex] = (MaledictDamageTaken[UDex] + (Damage taken))
      • Set MaledictDamageHPInteger = (Integer(MaledictDamageTaken[UDex]))
      • For each (Integer A) from 100 to MaledictDamageHPInteger, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • MaledictDamageTaken[UDexGen] Greater than or equal to 100.00
            • Then - Actions
              • Set Maledict_Damage_HP = (Maledict_Damage_HP + ((Real((Level of Maledict_Skill for MaledictCaster[Maledict_PlayerCount]))) x 10.00))
            • Else - Actions
 
ArraySize of Maledict_Group? An group needs to exist before it can contain units with add/Remove Unit/Group (change arraysize to the amount of players of your map inside variable editor to let world editor autogenerate one for each player)
Also you should not use UDexGen it has a complet different usage then UDex.


Your intention to use integer instead of reals is right, but that loop looks wrong. I recomment using an step approach.
-> divide the old value and the new value by the step, then calc the step difference by newStep - oldStep, if that differstep is bigger then 0 increase the damage * differStep (use integer). In your case step is 100.

Maledict_Damage_HP also needs to be saved onto the damaged unit, which breaks the current MPI approach.

You have to make sure that you do not register an unit multiple times to the damage detection trigger.
 
Status
Not open for further replies.
Top