• 🏆 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] "The damage is credited to the last caster"

Status
Not open for further replies.
Level 12
Joined
May 16, 2020
Messages
660
Hi guys,

I'm trying to copy dota 2's Orchid spell: Orchid Malevolence

Silences the target unit for 5 seconds. At the end of the silence, 30% of the damage received while silenced is inflicted as bonus magical damage.
  • Does not directly amplify damage as it is dealt, but rather saves all damage values and deals 30% of it 5 seconds after cast.
  • The damage is applied as soon as the debuff expires. Dispelling the debuff, however, skips the damage entirely.
    • Recasting Soul Burn on the same target refreshes the duration.
    • Doing this delays the damage further, and gives more time to deal damage to the target.
    • The damage is credited to the last caster of Soul Burn on the target.

However, this part of the description is giving me troubles:

  • The damage is credited to the last caster of Soul Burn on the target.

I'm guessing this will require a group, to connect the target to the caster. And if a new caster casts the ability on the same unit, to remap the target to the new caster and remove its connection to the old caster. But I don't know how to adjust the below trigger for this (if it's even possible with this structure that is).

Can anyone please help?

Starting the trigger:
  • Orchid Malevolence
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Orchid Malevolence (Effect)
    • Actions
      • Set VariableSet Orchid_Index = (Orchid_Index + 1)
      • Set VariableSet Orchid_Target[Orchid_Index] = (Target unit of ability being cast)
      • Set VariableSet Orchid_Caster[Orchid_Index] = (Triggering unit)
      • Set VariableSet Orchid_Counter[Orchid_Index] = 0
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Orchid_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start Orchid_Timer as a Repeating timer that will expire in 0.10 seconds
          • Trigger - Turn on Orchid Malevolence Damage <gen>
          • Trigger - Turn on Orchid Malevolence Loop <gen>
        • Else - Actions
Summing up the damage that a unit takes:
  • Orchid Malevolence Damage
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Soul Burn (Item)) Equal to True
    • Actions
      • Set VariableSet Orchid_CV = (Custom value of DamageEventTarget)
      • Set VariableSet Orchid_DamageTaken[Orchid_CV] = (Orchid_DamageTaken[Orchid_CV] + DamageEventAmount)
Trigger duration ends, or the spell is dispelled (which cases no damage). Note that I added the reset for "damage taken" here, and not inside the first trigger. This ensures that prolonguing the spell can cause even more damage once the silence runs out:
  • Orchid Malevolence Loop
    • Events
      • Time - Orchid_Timer expires
    • Conditions
    • Actions
      • For each (Integer Orchid_Integer) from 1 to Orchid_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet Orchid_Counter[Orchid_Integer] = (Orchid_Counter[Orchid_Integer] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • Orchid_Counter[Orchid_Integer] Greater than or equal to 50
                  • (Orchid_Target[Orchid_Integer] has buff Soul Burn (Item)) Equal to False
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Orchid_Target[Orchid_Integer] has buff Soul Burn (Item)) Equal to True
                • Then - Actions
                  • Set VariableSet Orchid_CV = (Custom value of Orchid_Target[Orchid_Integer])
                  • Unit - Cause Orchid_Caster[Orchid_Integer] to damage Orchid_Target[Orchid_Integer], dealing (0.30 x Orchid_DamageTaken[Orchid_CV]) damage of attack type Spells and damage type Magic
                • Else - Actions
              • Set VariableSet Orchid_DamageTaken[Orchid_CV] = 0.00
              • -------- --------
              • Set VariableSet Orchid_Target[Orchid_Integer] = Orchid_Target[Orchid_Index]
              • Set VariableSet Orchid_Counter[Orchid_Integer] = Orchid_Counter[Orchid_Index]
              • -------- --------
              • Set VariableSet Orchid_Index = (Orchid_Index - 1)
              • Set VariableSet Orchid_Integer = (Orchid_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Orchid_Index Equal to 0
                • Then - Actions
                  • Countdown Timer - Pause Orchid_Timer
                  • Trigger - Turn off Orchid Malevolence Damage <gen>
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
 
Last edited:
Level 24
Joined
Jun 26, 2020
Messages
1,850
If you wanna achieve that, don't create a instance every time is casted the spell, do the instance always depend of the target, and for that you need a linked list, like this:
In this way every time the spell is casted the data is overwritten
  • Orchid Malevolence
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Orchid Malevolence (Effect)
    • Actions
      • Set VariableSet Orchid_CV = (Custom value of (Target unit of ability being cast))
      • Set VariableSet Orchid_Target[Orchid_CV] = (Target unit of ability being cast)) or you can just use the reverse function of the unit indexer you are using
      • Set VariableSet Orchid_Caster[Orchid_CV] = (Triggering unit)
      • Set VariableSet Orchid_Counter[Orchid_CV] = 0
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Orchid_Added[Orchid_CV] Equal to False
        • Then - Actions
          • Set VariableSet Orchid_Added[Orchid_CV] = True
          • Set VariableSet Orchid_Next[Orchid_CV] = 0
          • Set VariableSet Orchid_Prev[Orchid_CV] = Orchid_Prev[0]
          • Set VariableSet Orchid_Next[Orchid_Prev[Orchid_CV]] = Orchid_CV
          • Set VariableSet Orchid_Prev[0] = Orchid_CV
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Orchid Malevolence Loop <gen> is on) Equal to False
        • Then - Actions
          • Countdown Timer - Start Orchid_Timer as a Repeating timer that will expire in 0.10 seconds
          • Trigger - Turn on Orchid Malevolence Damage <gen>
          • Trigger - Turn on Orchid Malevolence Loop <gen>
        • Else - Actions
This remains equal
  • Orchid Malevolence Damage
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Soul Burn (Item)) Equal to True
    • Actions
      • Set VariableSet Orchid_CV = (Custom value of DamageEventTarget)
      • Set VariableSet Orchid_DamageTaken[Orchid_CV] = (Orchid_DamageTaken[Orchid_CV] + DamageEventAmount)
And finally this
  • Orchid Malevolence Loop
    • Events
      • Time - Orchid_Timer expires
    • Conditions
    • Actions
      • Set VariableSet Orchid_Integer = Orchid_Next[0]
      • Custom script: loop
      • Custom script: exitwhen udg_Orchid_Integer == 0
      • Set VariableSet Orchid_Counter[Orchid_Integer] = (Orchid_Counter[Orchid_Integer] + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • Orchid_Counter[Orchid_Integer] Greater than or equal to 50
              • (Orchid_Target[Orchid_Integer] has buff Soul Burn (Item)) Equal to False
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Orchid_Target[Orchid_Integer] has buff Soul Burn (Item)) Equal to True
            • Then - Actions
              • Unit - Cause Orchid_Caster[Orchid_Integer] to damage Orchid_Target[Orchid_Integer], dealing (0.30 x Orchid_DamageTaken[Orchid_Integer]) damage of attack type Spells and damage type Magic
            • Else - Actions
          • Set VariableSet Orchid_DamageTaken[Orchid_Integer] = 0.00
          • -------- --------
          • Set VariableSet Orchid_Added[Orchid_Integer] = False
          • Set VariableSet Orchid_Next[Orchid_Prev[Orchid_Integer]] = Orchid_Next[Orchid_Integer]
          • Set VariableSet Orchid_Prev[Orchid_Next[Orchid_Integer]] = Orchid_Prev[Orchid_Integer]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Orchid_Next[0] Equal to 0
            • Then - Actions
              • Countdown Timer - Pause Orchid_Timer
              • Trigger - Turn off Orchid Malevolence Damage <gen>
              • Trigger - Turn off (This trigger)
            • Else - Actions
        • Else - Actions
      • Set VariableSet Orchid_Integer = Orchid_Next[Orchid_Integer]
      • Custom script: endloop
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,496
Based on the description of Orchid's mechanics you can use a Unit Indexer or Hashtable to handle this.

Unit Indexing example:

Whenever a unit becomes the target of Orchid you simply reset the Orchid variables and add the target to a Unit Group (if it's not already in it):
  • Set cv = Custom value of Target unit of ability being cast
  • Set Orchid_Source[cv] = Casting Unit
  • Set Orchid_DamageTaken[cv] = 0.00
  • Set Orchid_Duration[cv] = 5.00
  • If Target Unit is in Orchid_Group = False, Add Target Unit to Orchid_Group

Then in your timer trigger you do pretty much the same thing that you're doing now, but instead of a For Loop to enumerate over the units, you use Pick Every Unit in Orchid_Group and use cv (custom value of picked unit) as the index. Don't forget to remove the units from the Unit Group when they lose the buff.

These types of effects are simple because they don't stack and only the most recent cast takes precedence. This is where Unit Indexing far outclasses the more complex methods.
 
Last edited:
Status
Not open for further replies.
Top