1. Join Texturing Contest #30 now in a legendary battle of mythological creatures!
    Dismiss Notice
  2. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice
  3. Melee Mapping Contest #3 - Results are out! Congratulate the winners and check plenty of new 4v4 melee maps designed for this competition!
    Dismiss Notice
  4. The winners of our cinematic soundtrack competition have been decided! Step by the Music Contest #11 - Results to check the entries and congratulate the winners!
    Dismiss Notice
  5. Check out the Staff job openings thread.
    Dismiss Notice

[Trigger] Spell problems.

Discussion in 'Triggers & Scripts' started by TheBigMetalHandInTheSky, Sep 4, 2017.

  1. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Hello Hive.
    I am planning to submit this spell, but there are a few problems which I can't solve myself.
    (you will get credits in the spell)

    Here is the spell description.
    Captttur.PNG
    -Even though the target is supposed to be damaged for a percentage of their life, when I target the unit, instead of being damaged for 5% of their health, they are damaged for 90% of their health! The same applies to the caster; they get healed for 90% of their health.
    -I cannot figure out how to destroy the group using custom script (to avoid leaks) to which I add the target because it is indexed for MUI. I know how to destroy a regular group, but an indexed?

    Here are the codes.

    Siphon Life Configuration:
    • Siphon Life Config
      • Events
        • Map initialization
      • Conditions
      • Actions
        • -------- The duration of the spell --------
        • Set SL_Duration[1] = 6.00
        • Set SL_Duration[2] = 8.00
        • Set SL_Duration[3] = 10.00
        • -------- The damage the target receives, and the healing the caster receives (in percents). --------
        • Set SL_DamageOrHeal[1] = 0.05
        • Set SL_DamageOrHeal[2] = 0.07
        • Set SL_DamageOrHeal[3] = 0.10
        • -------- The range of the heal AoE --------
        • Set SL_AoEsize[1] = 50.00
        • Set SL_AoEsize[2] = 100.00
        • Set SL_AoEsize[3] = 150.00
        • -------- The percent of which the enemies around the dying unit are healed. --------
        • Set SL_AoeHeal[1] = 0.02
        • Set SL_AoeHeal[2] = 0.04
        • Set SL_AoeHeal[3] = 0.06


    Siphon Life Cast:
    • Siphon Life Cast
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Siphon Life
      • Actions
        • -------- I've made the spell MUI of course --------
        • Set SL_Index = (SL_Index + 1)
        • Set SL_Caster[SL_Index] = (Triggering unit)
        • Set SL_Victim[SL_Index] = (Target unit of ability being cast)
        • Set Level = (Level of Siphon Life for SL_Caster[SL_Index])
        • Unit Group - Add SL_Victim[SL_Index] to SL_Group[SL_Index]
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SL_Index Equal to 1
          • Then - Actions
            • Trigger - Turn on Siphon Life Loop <gen>
          • Else - Actions


    Siphon Life Loop:
    • Siphon Life Loop
      • Events
        • Time - Every 2.00 seconds of game time
      • Conditions
      • Actions
        • For each (Integer SL_LoopInteger) from 1 to SL_Index, do (Actions)
          • Loop - Actions
            • -------- The damage the caster does is equal to the max life of the target minus the max life multiplied by the percentage. For example, if the spell were level 1, --------
            • -------- and the target had 100 health, the formula would be 100 - (100 × 0.05), which would be 100 - 5. --------
            • Unit - Cause SL_Caster[SL_LoopInteger] to damage SL_Victim[SL_LoopInteger], dealing ((Max life of SL_Victim[SL_LoopInteger]) - ((Max life of SL_Victim[SL_LoopInteger]) x SL_DamageOrHeal[Level])) damage of attack type Spells and damage type Normal
            • Special Effect - Create a special effect attached to the origin of SL_Victim[SL_LoopInteger] using Abilities\Spells\Undead\DarkRitual\DarkRitualTarget.mdl
            • Special Effect - Destroy (Last created special effect)
            • -------- -------------------------- --------
            • -------- The same applies to the caster, except the caster receives healing, not damage. --------
            • Unit - Set life of SL_Caster[SL_LoopInteger] to ((Max life of SL_Caster[SL_LoopInteger]) + ((Max life of SL_Caster[SL_LoopInteger]) x SL_DamageOrHeal[Level]))
            • Special Effect - Create a special effect attached to the origin of SL_Caster[SL_Index] using Abilities\Spells\Items\AIma\AImaTarget.mdl
            • Special Effect - Destroy (Last created special effect)
            • Set SL_Duration[Level] = (SL_Duration[Level] - 2.00)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • SL_Duration[Level] Equal to 0.00
              • Then - Actions
                • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
                • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
                • Set SL_Index = (SL_Index - 1)
                • Set SL_LoopInteger = (SL_LoopInteger - 1)
                • Unit Group - Remove SL_Victim[SL_LoopInteger] from SL_Group[SL_LoopInteger]
              • Else - Actions


    Siphon Life Death:
    • Siphon Life Death
      • Events
        • Unit - A unit Dies
      • Conditions
        • (SL_Victim[SL_LoopInteger] is in SL_Group[SL_LoopInteger]) Equal to True
      • Actions
        • Unit Group - Pick every unit in (Units within SL_AoEsize[Level] of (Position of SL_Victim[SL_LoopInteger])) and do (Actions)
          • Loop - Actions
            • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + ((Life of (Picked unit)) x SL_AoeHeal[Level]))
            • Custom script: call DestroyGroup (udg_SL_Group[SL_Index])

     

    Attached Files:

  2. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    You deal ((Max life of SL_Victim[SL_LoopInteger]) - ((Max life of SL_Victim[SL_LoopInteger]) x SL_DamageOrHeal[Level])) damage, which is if the unit has 1000 hp:
    1000 - 1000 * 5% = 1000 * 95% = 950
    You only need to subtract it, so you only need ((Max life of SL_Victim[SL_LoopInteger]) x SL_DamageOrHeal[Level]))

    You set life to ((Max life of SL_Caster[SL_LoopInteger]) + ((Max life of SL_Caster[SL_LoopInteger]) x SL_DamageOrHeal[Level])), but you need to use current life not max life, if you want to add hp:
    ((Current life of SL_Caster[SL_LoopInteger]) + ((Max life of SL_Caster[SL_LoopInteger]) x SL_DamageOrHeal[Level]))


    You also need to store Level in an array SL_Level, because it can be different for different units.
    You should fix this first, as it will make the following problems clearer.

    The death trigger together with the unit group does not work well. You use a unit group to know, if the unit is a target, which is ok. The problem is, that you don't know which target it is (what the SL_index for of this target is), so you also don't know the Level. You can solve this by having multiple groups (bad, because you can't use arrays for this) or checking for the buff (if your spell has a buff).
    You can loop through all spells, to find the SL_index, but that is very inefficient. A better approach is to use unit indexer or hashtable to store the SL_index for the target.
    You should not use SL_LoopInteger in the death trigger, as it has no good meaning in that context.

    You can destroy unit group arrays like this: call DestroyGroup(udg_SL_Group[udg_SL_Loop_Integer])

    The configuration trigger is a bit missleading. Percentage suggests, that SL_DamageOrHeal[1] = 5 would mean 5% of hp, but 0.05 is 5%.


    Another suggestion: every 2 seconds makes the spell synchronized, I would use something smaller 0.1-0.25 and use a counter to achieve the 2 seconds interval
     
    Last edited: Sep 4, 2017
  3. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,031
    Resources:
    11
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    JASS:
    1
    Resources:
    11
    The Group Healing should be:
    ((Life of (Picked unit)) + ((Max Life of (Picked unit)) x SL_AoeHeal[Level]))​

    I would suggest using 1 permanent non-ArrayGroup to monitor affected units.
    Currently your groups will contain always only 1 target which does break the idea of a group.​
    The death event Trigger leaks 1 Location and 1 group.
    One time used groups are best handled with
    set bj_wantDestroyGroup = true​
    should be placed directly infront of the group block.
     
  4. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Oh ok. I don't know if my math was wrong, or the trigger multiplies percentages differently XD

    How would one make a counter to avoid synchronizing the spell? I thought it was not possible to do that.

    So, instead of indexing the target with SL_Index, I would do something like this,
    • Hashtable - Save SL_Index as 0 of 0 in SL_Hashtable[SL_Index]


    and instead of writing SL_Victim[SL_Index], I would write SL_Victim[Load 0 of 0 from SL_Hashtable[SL_Index]].

    Do I leave the numbers as they are, or do I change them? If I change them, I'll have to redo all the damage and healing.

    Ok, so I didn't add 'udg_'. Thanks!

    I didn't know that picking units in a range causes a leak; otherwise I would have destroyed it. Thank you!
     
  5. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,031
    Resources:
    11
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    JASS:
    1
    Resources:
    11
    An example form of such an intervalic effect.
    • Loop
      • Events
        • Time - Every 0.05 seconds of game time
      • Conditions
      • Actions
        • -------- Dur = total spell duration --------
        • -------- intervale = countdown to next lifedrain --------
        • For each (Integer Index) from 1 to SL_Index, do (Actions)
          • Loop - Actions
            • Set Dur[Index] = (Dur[Index] - 0.05)
            • Set Intervale[Index] = (Intervale[Index] - 0.05)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • Intervale[Index] Less than or equal to 0.00
              • Then - Actions
                • -------- Life Drain Action --------
                • -------- Reload intervale --------
                • Set Intervale[Index] = 2.00
              • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • Dur[Index] Less than or equal to 0.00
              • Then - Actions
                • -------- Destroy This --------
              • Else - Actions


    Edit:
    dat is a bad idea, hashtables can contain alot of data, there is no need to make them arraybased, instead you save the SL_index onto the units index.
    • Actions
      • -------- Save on Spellcast --------
      • Hashtable - Save Index as 0 of (Key (Target unit of ability being cast)) in SL_Table
      • -------- Load in death event --------
      • Set Index = (Load 0 of (Key (Triggering unit)) from SL_Table)

    Hashtables have to be created before the can be used, hmm but that would make the spell unable to trigger this death event effect multiple times for 1 unit when beeing drained multiple times but that would need some more difficult techniques.
     
    Last edited: Sep 4, 2017
  6. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Thank you, Tasyen, but I'm wondering: why would I want to avoid synchronizing the spell? Is it because I could add something in between the 0.05 seconds?
     
  7. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,031
    Resources:
    11
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    JASS:
    1
    Resources:
    11
    Different instances of this spell casted inside one timeframe: keepup the same duration and drain life at the same time even when there is x seconds casting difference between them. This feels Unfair / UnIntuitive for the user and allows exploiting the timeframe as soon you got its intervale. Which allows one to trigger the 1. drain almost instantly.

    When this timeframe is 2 seconds it means one can skip upto 1,99 seconds delay of the first drain and of the duration. With numbers below 1/4 (0,25) this does not matter much anymore, but this 1,99 seconds do matter.
     
  8. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    When you cast the spell, you would expect, that the next drain occurs in 2 seconds. When you use the event every 2 seconds and you use the spell at 59,7 seconds in the game, the next drain occurs at 60 seconds, so only 0.3 seconds after the cast. This is not what people expect to happen.
    If you use every 0.1 seconds with a counter, you have an accuracy of 0.1 seconds, so it could take 1.9-2.1 seconds and no one will notice if it is not exactly 2 seconds. Using timers in JASS you can achieve exactly 2 seconds, but 0.1 seconds accuracy is good enough for noone to care.

    What you did is good. I did not mean to change it.
    Right now you have SL_Index as a unique id and you can get a lot of values from that id. In fact if you know the id, you also know, target, level (if you make it indexed like the others), caster, ...
    The problem is in your death trigger, that you only know the killed unit. You do not know the level, because you only know the level, if you also know the id.
    I suggested, that you store for each unit, which SL_Index it has.
    You have:
    SL_Index -> target (if you have SL_Index you know target = SL_Victim[SL_Index])
    You don't have
    target -> SL_Index (if you only have the target, for example in your death trigger, you don't know which SL_Index it has, so you also cannot find out the level)
    You can add the target -> SL_Index relation using a hashtable.

    One question:
    Does the spell stack, i.e two of the spells are cast on the same unit and both deal damage.
    And if they stack and the unit dies, should it heal 2 times?

    If they stack, the whole target -> SL_Index thing makes no sense.
     
  9. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Considering that now, the spell does stack. If it requires to redo the whole darn trigger, then no.


    How would I do that? Do I just save the Index in a hashtable and load it when I index the killed unit?

    Update: I've edited some things in all of the triggers except config.
    Here are the new triggers.

    • Siphon Life Cast
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Siphon Life
      • Actions
        • -------- I've made the spell MUI of course --------
        • Set SL_Index = (SL_Index + 1)
        • Set SL_Caster[SL_Index] = (Triggering unit)
        • Set SL_Victim[SL_Index] = (Target unit of ability being cast)
        • Set Level = (Level of Siphon Life for SL_Caster[SL_Index])
        • Set SL_Interval[SL_Index] = 2.00
        • Unit Group - Add SL_Victim[SL_Index] to SL_Group[SL_Index]
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SL_Index Equal to 1
          • Then - Actions
            • Trigger - Turn on Siphon Life Loop <gen>
          • Else - Actions


    • Siphon Life Loop
      • Events
        • Time - Every 0.05 seconds of game time
      • Conditions
      • Actions
        • For each (Integer SL_LoopInteger) from 1 to SL_Index, do (Actions)
          • Loop - Actions
            • Set SL_Duration[Level] = (SL_Duration[Level] - 0.05)
            • Set SL_Interval[SL_LoopInteger] = (SL_Interval[SL_LoopInteger] - 0.05)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • SL_Interval[SL_LoopInteger] Less than or equal to 0.00
              • Then - Actions
                • Special Effect - Create a special effect attached to the origin of SL_Victim[SL_LoopInteger] using Abilities\Spells\Undead\DarkRitual\DarkRitualTarget.mdl
                • Special Effect - Destroy (Last created special effect)
                • Unit - Cause SL_Caster[SL_LoopInteger] to damage SL_Victim[SL_LoopInteger], dealing ((Life of SL_Victim[SL_LoopInteger]) x SL_DamageOrHeal[Level]) damage of attack type Spells and damage type Normal
                • Special Effect - Create a special effect attached to the origin of SL_Caster[SL_Index] using Abilities\Spells\Items\AIma\AImaTarget.mdl
                • Special Effect - Destroy (Last created special effect)
                • Unit - Set life of SL_Caster[SL_LoopInteger] to ((Life of SL_Caster[SL_LoopInteger]) + ((Life of SL_Caster[SL_LoopInteger]) x SL_DamageOrHeal[SL_LoopInteger]))
                • Set SL_Interval[SL_LoopInteger] = 2.00
              • Else - Actions
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • SL_Duration[SL_LoopInteger] Less than or equal to 0.00
                  • Then - Actions
                    • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
                    • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
                    • Set SL_Index = (SL_Index - 1)
                    • Set SL_LoopInteger = (SL_LoopInteger - 1)
                    • Unit Group - Remove SL_Victim[SL_LoopInteger] from SL_Group[SL_LoopInteger]
                  • Else - Actions


    • Siphon Life Death
      • Events
        • Unit - A unit Dies
      • Conditions
        • (SL_Victim[SL_LoopInteger] is in SL_Group[SL_LoopInteger]) Equal to True
      • Actions
        • Custom script: set bj_wantDestroyGroup = true
        • Unit Group - Pick every unit in (Units within SL_AoEsize[Level] of (Position of SL_Victim[SL_Index]) matching (((Picked unit) belongs to an ally of (Owner of SL_Caster[SL_Index])) Equal to True)) and do (Actions)
          • Loop - Actions
            • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
            • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + ((Life of (Picked unit)) x SL_AoeHeal[Level]))
            • Custom script: call DestroyGroup (udg_SL_Group[udg_SL_Index])
     
    Last edited: Sep 4, 2017
  10. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    You still need to use SL_Level[] instead of Level. You need to store the level for every single spell cast to make it MUI.

    It does not require to redo the whole trigger. In the Death trigger you have to do:
    For each (Integer SL_LoopInteger) from 1 to SL_Index, do (Actions)
    you find out of which spells the target has died:
    if ( SL_Victim[SL_LoopInteger] == (Dying Unit))
    now you know SL_Victim[SL_LoopInteger] is your dying unit and you can do that area heal (avoid leaks) and also deindex this spell instance.

    After the loop you remove the unit from the group. As Tasyen said you should use one permanent group instead of an array.

    • Siphon Life Death
      • Events
        • Unit - A unit Dies
      • Conditions
        • ((Triggering unit) is in SL_Group) Equal to True
      • Actions
        • For each (Integer SL_LoopInteger) from 1 to SL_Index, do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Triggering unit) Equal to SL_Victim[SL_LoopInteger]
              • Then - Actions
                • -------- Do Area Heal. You can use SL_LoopInteger --------
                • -------- ... --------
                • -------- Dynamic Indexing: Recycling --------
                • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
                • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
                • Set SL_Level[SL_LoopInteger] = SL_Level[SL_Index]
                • Set SL_Interval[SL_LoopInteger] = SL_Interval[SL_Index]
                • Set SL_Index = (SL_Index - 1)
                • Set SL_LoopInteger = (SL_LoopInteger - 1)
              • Else - Actions
        • Unit Group - Remove (Triggering unit) from SL_Group
     
    Last edited: Sep 4, 2017
  11. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Ok, thank you! I'll post the code to check if all the errors are gone.

    I'll post the code tomorrow: a family member is using the computer right now and I have school the next day x_x

    UPDATE: The codes now

    • Siphon Life Config
      • Events
        • Map initialization
      • Conditions
      • Actions
        • -------- The duration of the spell --------
        • Set SL_Duration[1] = 6.00
        • Set SL_Duration[2] = 8.00
        • Set SL_Duration[3] = 10.00
        • -------- The damage the target receives, and the healing the caster receives (in percents). --------
        • Set SL_DamageOrHeal[1] = 0.05
        • Set SL_DamageOrHeal[2] = 0.07
        • Set SL_DamageOrHeal[3] = 0.10
        • -------- The range of the heal AoE --------
        • Set SL_AoEsize[1] = 50.00
        • Set SL_AoEsize[2] = 100.00
        • Set SL_AoEsize[3] = 150.00
        • -------- The percent of which the enemies around the dying unit are healed. --------
        • Set SL_AoeHeal[1] = 0.02
        • Set SL_AoeHeal[2] = 0.04
        • Set SL_AoeHeal[3] = 0.06


    • Siphon Life Cast
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Siphon Life
      • Actions
        • -------- I've made the spell MUI of course --------
        • Set SL_Index = (SL_Index + 1)
        • Set SL_Caster[SL_Index] = (Triggering unit)
        • Set SL_Victim[SL_Index] = (Target unit of ability being cast)
        • Set SL_Level[SL_Index] = (Level of Siphon Life for SL_Caster[SL_Index])
        • Set SL_Interval[SL_Index] = 2.00
        • Unit Group - Add SL_Victim[SL_Index] to SL_Group
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SL_Index Equal to 1
          • Then - Actions
            • Trigger - Turn on Siphon Life Loop <gen>
          • Else - Actions


    • Siphon Life Loop
      • Events
        • Time - Every 0.05 seconds of game time
      • Conditions
      • Actions
        • For each (Integer SL_LoopInteger) from 1 to SL_Index, do (Actions)
          • Loop - Actions
            • Set SL_Duration[SL_Level[SL_Index]] = (SL_Duration[SL_Level[SL_Index]] - 0.05)
            • Set SL_Interval[SL_LoopInteger] = (SL_Interval[SL_LoopInteger] - 0.05)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • SL_Interval[SL_LoopInteger] Less than or equal to 0.00
              • Then - Actions
                • Special Effect - Create a special effect attached to the origin of SL_Victim[SL_LoopInteger] using Abilities\Spells\Undead\DarkRitual\DarkRitualTarget.mdl
                • Special Effect - Destroy (Last created special effect)
                • Unit - Cause SL_Caster[SL_LoopInteger] to damage SL_Victim[SL_LoopInteger], dealing ((Life of SL_Victim[SL_LoopInteger]) x SL_DamageOrHeal[SL_Level[SL_LoopInteger]]) damage of attack type Spells and damage type Normal
                • Special Effect - Create a special effect attached to the origin of SL_Caster[SL_Index] using Abilities\Spells\Items\AIma\AImaTarget.mdl
                • Special Effect - Destroy (Last created special effect)
                • Unit - Set life of SL_Caster[SL_LoopInteger] to ((Life of SL_Caster[SL_LoopInteger]) + ((Life of SL_Caster[SL_LoopInteger]) x SL_DamageOrHeal[SL_Level[SL_LoopInteger]]))
                • Set SL_Interval[SL_LoopInteger] = 2.00
              • Else - Actions
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • SL_Duration[SL_LoopInteger] Less than or equal to 0.00
                  • Then - Actions
                    • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
                    • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
                    • Set SL_Level[SL_LoopInteger] = SL_Level[SL_Index]
                    • Set SL_Interval[SL_LoopInteger] = SL_Interval[SL_Index]
                    • Set SL_Index = (SL_Index - 1)
                    • Set SL_LoopInteger = (SL_LoopInteger - 1)
                    • Unit Group - Remove SL_Victim[SL_LoopInteger] from SL_Group
                  • Else - Actions


    • Siphon Life Death
      • Events
        • Unit - A unit Dies
      • Conditions
        • ((Triggering unit) is in SL_Group) Equal to True
      • Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to SL_Victim[SL_LoopInteger]
          • Then - Actions
            • Custom script: set bj_wantDestroyGroup = true
            • Unit Group - Pick every unit in (Units within SL_AoEsize[SL_Level[SL_LoopInteger]] of (Center of (Playable map area)) matching (((Picked unit) belongs to an ally of (Owner of SL_Caster[SL_LoopInteger])) Equal to True)) and do (Actions)
      • Loop - Actions
        • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
        • Special Effect - Destroy (Last created special effect)
        • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + ((Life of (Picked unit)) x SL_DamageOrHeal[SL_Level[SL_Index]]))
        • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
        • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
        • Set SL_Level[SL_LoopInteger] = SL_Level[SL_Index]
        • Set SL_Interval[SL_LoopInteger] = SL_Interval[SL_Index]
        • Set SL_Index = (SL_Index - 1)
        • Set SL_LoopInteger = (SL_LoopInteger - 1)
          • Loop - Actions
            • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
            • Special Effect - Destroy (Last created special effect)
            • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + ((Life of (Picked unit)) x SL_DamageOrHeal[SL_Level[SL_Index]]))
            • Set SL_Caster[SL_LoopInteger] = SL_Caster[SL_Index]
            • Set SL_Victim[SL_LoopInteger] = SL_Victim[SL_Index]
            • Set SL_Level[SL_LoopInteger] = SL_Level[SL_Index]
            • Set SL_Interval[SL_LoopInteger] = SL_Interval[SL_Index]
            • Set SL_Index = (SL_Index - 1)
            • Set SL_LoopInteger = (SL_LoopInteger - 1)
          • Else - Actions
            • Unit Group - Remove (Triggering unit) from SL_Group
            • Custom script: call DestroyGroup (udg_SL_Group)

    UPDATE 2: I found an error. I'll be right back.
    UPDATE 3: Well, all of a sudden, the target dies. That's not supposed to happen.
    UPDATE 4: Fixed update 3!
     
    Last edited: Sep 5, 2017
  12. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Sorry for double posting, I just didn't want to do a 6th update, and Hive doesn't alert you when I edit a post.

    Everything is fine except:
    When I cast the ability twice, nothing happens. I think it has to do with resetting the indices.
    The AoE heal does not do anything.
     
  13. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    You need to set SL_Duration in the cast trigger.
    You also have to do the usual stuff with it when you recycle.

    The death trigger looks weird. The loops are messed up.
    You should never use SL_LoopInteger outside of the loop.

    I posted the death trigger above, and this is how you should do it as well.
    First you use the loop and determine for which of the spell instances the victim has died. For these spell indexes you do area heal and some special effects, whatever you want.
    You also recycle this spell index.
    After the loop you remove the dying unit from the unit group.
     
    Last edited: Sep 5, 2017
  14. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    What do you mean by that? Do I index it with SL_Level and SL_Index?

    Is it your third post? If not, where is it? I did what the third post said, and it still does not work.

    Do you mean that I have to create another spell index?

    This is frustrating; at least we're almost done. :)

    With that, I'm going to bed.
     
  15. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    The whole dynamic indexing thing is to store multiple spell instances. SL_Index is the number of currently active spell instances.
    the numbers from 1 to SL_Index are the indeces of the spell instances.

    Data that is stored for every spell instance is indexed.
    In this case every spell instance has a caster (SL_Caster), target (SL_Victim), level (SL_Level), duration (SL_Duration) and a counter (SL_Interval).
    All of these variables are arrays.
    All of them must be set, when a new spell instance is created (cast) and all of them must be recycled, when the spell instance is destroyed (death trigger and effect expires by duration)
    You currently do not set SL_Duration in the cast trigger and you also do not recycle it.

    I think the real problem is, that you use SL_Duration for two things at the moment. That's probably why you did not understand what I mean. You use it in your configuration trigger and in the loop trigger. You need two Duration variables. One for configuration and one for each spell instance, so you know when the effect expires.

    My death trigger example: [Trigger] - Spell problems.
    In the death trigger all you know is that a unit died, that is in the group, but you don't by which spell indices it was affected. Using the loop and the condition will give you the spell instances the unit was affected.

    I think it would be easier, if you could send me the map. Without the triggers it's hard to explain.
     
  16. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Here is the file.
     

    Attached Files:

  17. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,277
    Resources:
    0
    Resources:
    0
    Comments are in the map. I made some changes, so I can test better (loner duration, more aoe, less cooldown & mana cost)
     

    Attached Files:

  18. TheBigMetalHandInTheSky

    TheBigMetalHandInTheSky

    Joined:
    Jan 14, 2017
    Messages:
    74
    Resources:
    0
    Resources:
    0
    Thank you for your hard work. I will submit this spell now. Close the thread if you'd like.