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

[Solved] Spell Leak

Status
Not open for further replies.
Level 9
Joined
Apr 23, 2011
Messages
460
I can tell this spell doesn't work, and I need it fixed if possible. I didn't make this spell one of my co Creators did. I'm not good at spells, so if anyone could improve this spell it would be most helpful. :)

  • Nerubian Sacrifice
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Nerubian Sacrifice
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 300.00 of (Position of (Casting unit)) matching (((Owner of (Picked unit)) is an ally of (Owner of (Casting unit))) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Invulnerable
      • Wait ((Real((Level of (Ability being cast) for (Casting unit)))) x 10.00) seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 300.00 of (Position of (Casting unit)) matching (((Owner of (Picked unit)) is an ally of (Owner of (Casting unit))) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Vulnerable
      • Unit - Set life of (Casting unit) to ((Max life of (Casting unit)) / 4.00)
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
It doesn't work because you used "casting unit" behind a wait.
Waits will remove all values, aside from "triggering unit/player".

But even then, I fear your spell will not work.
The reason is simple: a unit within 300 range becomes invulnerable. 10 seconds later, the unit is not in range anymore (units can move...) and will never become vulnerable again.

Sometimes it's also adviced to use "game time" seconds.

I think this will work:

  • Nerubian Sacrifice
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nerubian Sacrifice
    • Actions
      • Custom script: local group udg_tempGroup = CreateGroup()
      • Set tempLoc = (Position of (Triggering unit))
      • Set tempGroup = (Units within 300.00 of tempLoc matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True))
      • Custom script: call RemoveLocation(udg_tempLoc)
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Invulnerable
      • Wait ((Real((Level of (Ability being cast) for (Casting unit)))) x 10.00) game-time seconds
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Vulnerable
      • Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) / 4.00)
      • Custom script: call DestroyGroup(udg_tempGroup)
      • Custom script: set udg_tempGroup = null
I didn't really test it though :|
But it should be MUI with the local group.

2 variables: tempGroup (unit group) and tempLoc (point).


Also, tell your co-creator to remove location leaks as well ;) (they're the most common leaks).
 
Level 9
Joined
Apr 23, 2011
Messages
460
Would this also be ok or is it leaking a unit group?
  • Mass Taunt
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Mass Taunt
    • Actions
      • Set tempLoc = (Position of (Casting unit))
      • Set tempGroup = (Units within 500.00 of tempLoc)
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Order (Picked unit) to Attack (Casting unit)
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
It's leaking a group.
At the end of the trigger, you need to add:
  • Custom script: call DestroyGroup(udg_tempGroup)
  • Custom script: call RemoveLocation(udg_tempLoc)
That's because there are 2 ways to remove the unit group leak.
One is by setting "bj_wantDestroyGroup" to true before you use the unit group.
The other is by setting the unit group to a variable and then destroying it with "DestroyGroup".

Edit: a few seconds too late, or so it seems... (and Pharaoh is completely correct about the "Casting unit", in general you should never use "Casting unit", always use "Triggering unit" instead).
 
Level 9
Joined
Apr 23, 2011
Messages
460
Hate to bump a post, but this spell used to work and now it's not, idk what's wrong, i think i cleaned up all of the leaks so it might be in the math. Any ideas?
  • Masters Light
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Master's Light
    • Actions
      • Set tempGroup = (Units currently selected by (Triggering player))
      • Set tempCaster = (Triggering unit)
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + ((5.00 x (Real((Intelligence of tempCaster (Include bonuses))))) + (5.00 x ((Real((Level of (Ability being cast) for tempCaster))) + 20.00))))
      • Custom script: call DestroyGroup(udg_tempGroup)
 
Level 9
Joined
Apr 23, 2011
Messages
460
I tried setting it to begins the affect of an ability, I learned that it is reading the ability correctly but something in the set life is not working. After setting the variables I put the action Game - Display to (All players) the text: (Proper name of (Random unit from tempGroup)) and it's pulling up my heroes name. This is most likely the issue. So I'll fiddle with the variables a bit until it works :p

EDIT: The spell now works 100% and is leakless and MUI :D hooray
  • Masters Light
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Master's Light
    • Actions
      • Set tempUnit = (Target unit of ability being cast)
      • Set tempCaster = (Triggering unit)
      • Unit - Set life of tempUnit to ((Life of tempUnit) + ((5.00 x (Real((Intelligence of tempCaster (Include bonuses))))) + (5.00 x ((Real((Level of (Ability being cast) for tempCaster))) + 100.00))))
 
I think this will work:

  • Nerubian Sacrifice
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nerubian Sacrifice
    • Actions
      • Custom script: local group udg_tempGroup = CreateGroup()
      • Set tempLoc = (Position of (Triggering unit))
      • Set tempGroup = (Units within 300.00 of tempLoc matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True))
      • Custom script: call RemoveLocation(udg_tempLoc)
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Invulnerable
      • Wait ((Real((Level of (Ability being cast) for (Casting unit)))) x 10.00) game-time seconds
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Vulnerable
      • Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) / 4.00)
      • Custom script: call DestroyGroup(udg_tempGroup)
      • Custom script: set udg_tempGroup = null
I didn't really test it though :|
But it should be MUI with the local group.

I don't think it's MUI.

The tempGroup may be redefined during the wait. Here are my suggestions:
- Make the variables into array variables.
- Set Trigger 1 to make the units invulnerable.
- Use a timer or dummy with expiration timer to trigger Trigger 2.
- Set Trigger 2 to make the units vulnerable.

For example:

  • Nerubian Sacrifice
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nerubian Sacrifice
    • Actions
      • Set MUI = MUI + 1
      • Set User[MUI] = (Triggering unit)
      • Set tempLoc[MUI] = (Position of (Triggering unit))
      • Set Player[MUI] = (Owner of (Triggering unit))
      • Set tempGroup[MUI] = (Units within 300.00 of tempLoc[MUI] matching (((Matching unit) belongs to an enemy of Player[MUI]) Equal to True))
      • Unit Group - Pick every unit in tempGroup[MUI] and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Invulnerable
      • Unit - Create 1 Dummy for Player[MUI] at tempLoc[MUI]
      • Unit - Set Custom Value of (last created unit) to MUI
      • Unit - Add ((Real((Level of (Ability being cast) for (Casting unit)))) x 10.00) Generic expiration timer to last created unit
      • Custom script: call RemoveLocation(udg_tempLoc[MUI])
  • Nerubian Sacrifice 2
    • Events
      • Unit - A unit dies
    • Conditions
      • Unit-type of dying unit Equal to Dummy
    • Actions
      • Set tempInteger = Custom Value of dying unit
      • Unit Group - Pick every unit in tempGroup[tempInteger] and do (Actions)
        • Loop - Actions
          • Unit - Make (Picked unit) Vulnerable
      • Unit - Set life of (User[tempInteger]) to ((Life of (User[tempInteger])) / 4.00)
      • Custom script: call DestroyGroup(udg_tempGroup[tempInteger])


Correct me if I'm wrong.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I don't think it's MUI.

The tempGroup may be redefined during the wait. Here are my suggestions:

Correct me if I'm wrong.

The tempGroup is a local variable, not a global one.
It doesn't change (not even with the wait). This is also why it needs to be nulled at the end (whereas nulling globals is pointless).
That's my theory at least... :|
 
Status
Not open for further replies.
Top