1. The Melee Mapping Contest #4: 2v2 - Results are out! Step by to congratulate the winners!
    Dismiss Notice
  2. We're hosting the 15th Mini-Mapping Contest with YouTuber Abelhawk! The contestants are to create a custom map that uses the hidden content within Warcraft 3 or is inspired by any of the many secrets within the game.
    Dismiss Notice
  3. The 20th iteration of the Terraining Contest is upon us! Join and create exquisite Water Structures for it.
    Dismiss Notice
  4. Check out the Staff job openings thread.
    Dismiss Notice

[Trigger] Deal AoE damage per second trigger with waits. Is this spell MUI?

Discussion in 'Triggers & Scripts' started by Fakuspakus, Mar 17, 2019.

  1. Fakuspakus

    Fakuspakus

    Joined:
    Dec 25, 2018
    Messages:
    75
    Resources:
    0
    Resources:
    0
    This trigger doesn't work properly, when units are inside AoE range they take damage, but if they go out and come back to it they are not affected.
    Did I miss out on something?
    • Smoke
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Smoke
      • Actions
        • Custom script: local unit udg_Caster
        • Custom script: local location udg_SmokePoint
        • Set Caster = (Triggering unit)
        • Set SmokePoint = (Target point of ability being cast)
        • Set SmokeDMG = ((40.00 x (Real((Level of Smoke for Caster)))) + ((Real((Agility of Caster (Include bonuses)))) / 2.00))
        • Unit - Create 1 Dummy for (Owner of Caster) at SmokePoint facing Default building facing degrees
        • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
        • Unit - Add Smoke1 to (Last created unit)
        • Unit - Set level of Smoke1 for (Last created unit) to (Level of Smoke for Caster)
        • Unit - Order (Last created unit) to Human Dragonhawk Rider - Cloud SmokePoint
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Wait 1.00 seconds
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Wait 1.00 seconds
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Wait 1.00 seconds
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Wait 1.00 seconds
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Wait 1.00 seconds
        • Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True)))
        • Unit Group - Pick every unit in SmokeGroup and do (Actions)
          • Loop - Actions
            • Unit - Cause (Last created unit) to damage (Picked unit), dealing SmokeDMG damage of attack type Spells and damage type Normal
        • Custom script: call DestroyGroup(udg_SmokeGroup)
        • Custom script: call RemoveLocation(udg_SmokePoint)
        • Custom script: set udg_Caster = null
        • Custom script: set udg_SmokePoint = null
     
  2. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    321
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    Se Pyrogasms post in this thread to see why this solution isn't good.

    Try using:
    • Unit Group - Remove all units from SmokeGroup

    Instead of:
    • Custom script: call DestroyGroup(udg_SmokeGroup)


    If you destory the group, you have to create a new group every time you want to pick the units in range. It's easier to just clear the group instead. If you ever want to make SmokeGroup a local, you can just destroy it and null it at the end of the trigger. It doesn't need to be a local variable for the spell to be MUI, though.

    But the spell is currently not MUI, since you are using Last Created Unit, and that variable (bj_lastCreatedUnit) changes every time a new instance of the spell is cast, since a new unit is created. Sure, the spell will still work, however, the unit dealing the damage will be the wrong one. If you don't mind that, I guess there is no issue.
     
    Last edited: Mar 19, 2019
  3. Fakuspakus

    Fakuspakus

    Joined:
    Dec 25, 2018
    Messages:
    75
    Resources:
    0
    Resources:
    0
    Then should I make dummy a local unit too to make it MUI?
     
  4. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    321
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    That will not work, because a For Group loop uses a separate function, so the local will be out of scope inside the group loop.
     
  5. Fakuspakus

    Fakuspakus

    Joined:
    Dec 25, 2018
    Messages:
    75
    Resources:
    0
    Resources:
    0
    So the only way to make it MUI is indexing?
     
  6. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    321
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    For this simple application, I recommend you use a system like this:

    [GUI-friendly] Timer System

    If you want, I can show you what your spell would look like with that system.

    PS: Using waits can be pretty bad, since in a multiplayer game they have an innacuracy of like, 10%-20% for 1-second waits, iirc. They also don't stop when the game is paused, so one could pause the game for 6 seconds and deal all the damage instantaneously.

    PSS: If you still want to use waits, you can do something like this:
    - Save (Last Created Unit) to a local variable (localUnit).
    - Create a new global variable (UNIT)
    - Whenever you are about to deal damage: Set UNIT = localUnit
    - In the For Group loop actions, use UNIT instead of (Last Created Unit)

    Please keep in mind though, that dealing damage generates an Event. So if you use a Damage Detection System and you use this global UNIT variable in any other trigger, there is a chance that the actions fired by the damage event will change the value of the global UNIT variable.
     
    Last edited: Mar 17, 2019
  7. Fakuspakus

    Fakuspakus

    Joined:
    Dec 25, 2018
    Messages:
    75
    Resources:
    0
    Resources:
    0
    If you could I would be thankful, only way I could do it is by indexing but I also have an idea to spawn dummy, set its base damage to lvlofability+Agi of caster do periodic event every 1 sec and order dummy to attack every unit in group, am I overcomplicating this too much?
     
  8. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    321
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    • Casting
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to TestAbility
      • Actions
        • Set GTS_TimeOut = 1.00
        • Set GTS_Trigger = Periodic <gen>
        • Trigger - Run GTS Main <gen> (checking conditions)
        • Hashtable - Save Handle Of(Triggering unit) as 0 of GTS_CustomValue in GTS_Hashtable
        • Hashtable - Save Handle Of(Target point of ability being cast) as 1 of GTS_CustomValue in GTS_Hashtable


    • Periodic
      • Events
      • Conditions
      • Actions
        • Set TempGroup = (Units within 350.00 of (Load 1 of GTS_CustomValue in GTS_Hashtable))
        • Unit Group - Pick every unit in TempGroup and do (Actions)
          • Loop - Actions
            • Set TempUnit = (Load 0 of GTS_CustomValue in GTS_Hashtable)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • ((Owner of TempUnit) is an ally of (Owner of (Picked unit))) Equal to False
                • ((Picked unit) is alive) Equal to True
              • Then - Actions
                • Set TempReal = ((40.00 x (Real((Level of TestAbility for TempUnit)))) + ((Real((Agility of TempUnit (Include bonuses)))) / 2.00))
                • Unit - Cause (Load 0 of GTS_CustomValue in GTS_Hashtable) to damage (Picked unit), dealing TempReal damage of attack type Spells and damage type Normal
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Other\AcidBomb\BottleMissile.mdl
                • Special Effect - Destroy (Last created special effect)
              • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • GTS_ExecutionCounter Equal to 6
          • Then - Actions
            • Set GTS_DestroyTimer = True
            • Custom script: call RemoveLocation(LoadLocationHandle(udg_GTS_Hashtable, udg_GTS_CustomValue, 1))
          • Else - Actions


    Making the dummy attack the units in the group won't achieve anything over having the dummy damage them through a trigger, and its more complicated :S
     

    Attached Files:

  9. Fakuspakus

    Fakuspakus

    Joined:
    Dec 25, 2018
    Messages:
    75
    Resources:
    0
    Resources:
    0
    Works like a charm so far, thanks a lot.
     
  10. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,391
    Resources:
    0
    Resources:
    0
    I see that the final solution in this thread doesn't use this method but as a followup to this suggestion to help the OP learn a little more: this change wouldn't have affected anything other than actually making you leak more groups. The Set SmokeGroup = (Units within 350.00 of SmokePoint matching ((((Matching unit) belongs to an ally of (Owner of (Last created unit))) Equal to False) and (((Matching unit) is alive) Equal to True))) line already creates a new group and assigns the variable to it every time (so it did need to be destroyed afterward).
     
  11. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    321
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    Yeah that's true, it's been a while since I've used GUI. I forgot the reason I don't even use GUI enumerations is that they all leak a group handle by not nulling the local group they create. The reason the code in the OP wasn't working originally was probably due to Last Created Unit changing into a unit of an ally of the player.