Snippet RemoveLocationIn & DestroyEffectIn

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
This is a very small, but useful snippet that allow the user to remove/destroy a location/effect after the specified amount of time is eslaped.

Requirements:
Jass NewGen Pack 1.5d
TimerUtils

Pros:
Mui
Can be used in Gui
Leakless
Lagless
Cons:
Requires JassNewGenPack

How to use?:
To Use it, call these functions:
JASS:

call RemoveLocationIn(whichlocation, whichamount of time (Real))
call DestroyEffectIn(whicheffect, whichamount of time (Real))

Trigger:
  • Actions
    • Custom script: call RemoveLocationIn(whichlocation, whichamount of time (Real))
    • Custom script: call DestroyEffectIn(whicheffect, whichamount of time (Real))



Code:
JASS:

library In requires TimerUtils

    private struct data
        effect ef
        method KillEf takes nothing returns nothing
            set .ef = null
        endmethod
    endstruct
    private function TimerKillEf takes nothing returns nothing
        local data d = GetTimerData(GetExpiredTimer())
        call DestroyEffect(d.ef)
        call d.KillEf()
    endfunction
    function DestroyEffectIn takes effect e, real time returns nothing
        local data d = data.create()
        local timer t
        set t = NewTimer()
        set d.ef = e
        call SetTimerData(t,d)
        call TimerStart(t, time, false, function TimerKillEf) 
    endfunction
    
//==============================================================================

    private struct datae
        location lo
        method KillLo takes nothing returns nothing
            set .lo = null
        endmethod
    endstruct
    private function TimerKillLo takes nothing returns nothing
        local datae d = GetTimerData(GetExpiredTimer())
        call RemoveLocation(d.lo)
        call d.KillLo()
    endfunction
    function RemoveLocationIn takes location l, real time returns nothing
        local datae d = data.create()
        local timer t
        set t = NewTimer()
        set d.lo = l
        call SetTimerData(t,d)
        call TimerStart(t, time, false, function TimerKillLo)
    endfunction
    
endlibrary


How to Import:
To import, create a new trigger called "In" and paste this following code in it. Also make sure you have TimerUtils
JASS:

library In requires TimerUtils

    private struct data
        effect ef
        method KillEf takes nothing returns nothing
            set .ef = null
        endmethod
    endstruct
    private function TimerKillEf takes nothing returns nothing
        local data d = GetTimerData(GetExpiredTimer())
        call DestroyEffect(d.ef)
        call d.KillEf()
    endfunction
    function DestroyEffectIn takes effect e, real time returns nothing
        local data d = data.create()
        local timer t
        set t = NewTimer()
        set d.ef = e
        call SetTimerData(t,d)
        call TimerStart(t, time, false, function TimerKillEf) 
    endfunction
    
//==============================================================================

    private struct datae
        location lo
        method KillLo takes nothing returns nothing
            set .lo = null
        endmethod
    endstruct
    private function TimerKillLo takes nothing returns nothing
        local datae d = GetTimerData(GetExpiredTimer())
        call RemoveLocation(d.lo)
        call d.KillLo()
    endfunction
    function RemoveLocationIn takes location l, real time returns nothing
        local datae d = data.create()
        local timer t
        set t = NewTimer()
        set d.lo = l
        call SetTimerData(t,d)
        call TimerStart(t, time, false, function TimerKillLo)
    endfunction
    
endlibrary
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
Cons:
Requires JassNewGenPack

Why is that a Con? Also, this has been done 20 times over. Explain why your sys is better, or it might not be approved.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Why is that a Con?

Because if I could make it of normal Jass it would be better, Jass and vJass users could use it.
This way, only vJass users can use it, it's a Con In my opinion.

Also, this has been done 20 times over. Explain why your sys is better, or it might not be approved.

Didn't found any other. I found TextMacros, but it can't be used in Gui.
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
>Because if I could make it of normal Jass it would be better, Jass and vJass users could use it.
This way, only vJass users can use it, it's a Con In my opinion.
Using NewGen is not a con, I don't see how it could be a pro either. You either use it or not, it's not both ways.

>Didn't found any other. I found TextMacros, but it can't be used in Gui.
Well, this system that's so eerily similar was Gy'd TimedEffect.
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
What does that have to do with anything, the fact is what makes your system 'awesome'. If you can set the period and the trigger runs twice, won't it override and leak?
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
I've did a few test with Effect created on "Head", "Right Hand", "Left Hand" with different amount of time and they all dissapeared when it was their turn.

It shouldn't leak since I destroy my struct.

Maybe not. I can't tell
 

RaiJin

New Member
Reaction score
40
>Didn't found any other. I found TextMacros, but it can't be used in Gui.
Well, this system that's so eerily similar was Gy'd TimedEffect.

ew inaccurate wait >.<

though i don't see why anyone would have the need to destroy a location later, seems rather pointless, but i can relate to destroy an effect later
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
Also, I'd provide a link to TimerUtils, and/or make a demo map demonstrating its use.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Oh, thanks for info. Link to TimerUtils is there, JassNewGenPack too.

Should my trigger be of Gui or Jass?

Edit: Also, destroy the location later could be useful for a Gui trigger like a WaveForm. (I'm talking of the one you did.)
When it's cast, "set WF_TargetPoint[WF_CustomValue] = Target point of ability being cast" you could have added after "call RemoveLocationIn(udg_WF_TargetPoint[udgWF_CustomValue], 10.00)" because you'd know the spell will be done in 10 seconds. :)
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
Both, show how it can be used.

Edit: I don't see a link..
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
Why does it link to page 7? :p
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
I used google, "Copy link" didn't know it was page 7.

Working on a Gui trigger.

Edit: Added an example of use:

Trigger:
  • WaveForm
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to WaveForm
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • WF_MUICount Equal to 300
        • Then - Actions
          • Set WF_MUICount = 1
        • Else - Actions
          • Set WF_MUICount = (WF_MUICount + 1)
      • Set WF_CasterPoint[WF_MUICount] = (Position of (Triggering unit))
      • Set WF_TargetPoint[WF_MUICount] = (Target point of ability being cast)
      • Set WF_CastAngle[WF_MUICount] = (Angle from WF_CasterPoint[WF_MUICount] to WF_TargetPoint[WF_MUICount])
      • Set WF_Damage[WF_MUICount] = (100.00 x (Real((Level of WaveFormfor (Triggering unit)))))
      • Set WF_Offset[WF_MUICount] = 0.00
      • Unit - Set the custom value of (Triggering unit) to WF_MUICount
      • Unit Group - Add (Triggering unit) to WF_CasterGroup
      • Unit Group - Remove all units from WF_DamagedGroup[WF_MUICount]
      • Custom script: call RemoveLocationIn(udg_WF_CasterPoint[udg_WF_MUICount], 10.00)
      • Custom script: call RemoveLocationIn(udg_WF_TargetPoint[udg_WF_MUICount], 10.00)

Trigger:
  • WaveForm Periodic
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
      • (Number of units in WF_CasterGroup) Greater than 0
    • Actions
      • Unit Group - Pick every unit in WF_CasterGroup and do (Actions)
        • Loop - Actions
          • Set WF_DamageUnit = (Picked unit)
          • Set WF_CustomValue = (Custom value of (Picked unit))
          • Set WF_Offset[WF_CustomValue] = (WF_Offset[WF_CustomValue] + 20.00)
          • Set WF_NewPoint = (WF_CasterPoint[WF_CustomValue] offset by WF_Offset[WF_CustomValue] towards WF_CastAngle[WF_CustomValue] degrees)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between WF_NewPoint and WF_TargetPoint[WF_CustomValue]) Less than or equal to 50.00
            • Then - Actions
              • Unit - Move (Picked unit) instantly to WF_NewPoint
              • Special Effect - Create a special effect at WF_NewPoint using Objects\Spawnmodels\Naga\NagaDeath\NagaDeath.mdl
              • Special Effect - Destroy (Last created special effect)
              • Set WF_AroundGroup = (Units within 150.00 of WF_NewPoint matching ((((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True) and (((Matching unit) is in WF_DamagedGroup[WF_CustomValue]) Equal to False)))
              • Unit Group - Pick every unit in WF_AroundGroup and do (Actions)
                • Loop - Actions
                  • Unit - Cause WF_DamageUnit to damage (Picked unit), dealing WF_Damage[WF_CustomValue] damage of attack type Spells and damage type Normal
                  • Unit Group - Add (Picked unit) to WF_DamagedGroup[WF_CustomValue]
              • Custom script: call DestroyGroup(udg_WF_AroundGroup)
            • Else - Actions
              • Custom script: call DestroyGroup(udg_WF_DamagedGroup[udg_WF_CustomValue])
          • Custom script: call RemoveLocation(udg_WF_NewPoint)
 
Reaction score
341
This is pretty much the same as this.

And this could of had been a lot better coded. At least the one above is configurable in what handles you want to add.
 

Kenny

Back for now.
Reaction score
202
Even though I think this has been done time and time again, I personally would rather see something like this:

JASS:
struct DestroyEffectEx

    private timer  t  = null
    private effect fx = null

    static method create takes effect sfx, real time returns thistype
        local thistype this = thistype.allocate()

        set this.t  = NewTimer()
        set this.fx = sfx
        
        call SetTimerData(this.t,this)
        call TimerStart(this.t,time,false,function thistype.update)

        return this
    endmethod

    private static method update takes nothing returns nothing
        call GetTimerData(GetExpiredTimer()).destroy()
    endmethod

    private method onDestroy takes nothing returns nothing
        call DestroyEffect(this.fx)
        set this.fx = null

        call ReleaseTimer(this.t)
        set this.t = null
    endmethod

endstruct

function DestroyEffectExFunc takes effect sfx, real time returns nothing
    call DestroyEffectEx.create(sfx,time)
endfunction


I'm not sure if the syntax and all that is right, but something like that would allow both normal and struct syntax, to please everyone, and it is written a little nicer.
 

Jesus4Lyf

Good Idea™
Reaction score
397
What the hell? Why would you use H2I for a delayed remove? :(

Any map using this will break on patch. Finding an alternative to TimerUtils would be a bonus that other systems may not have, but I haven't looked at other systems...

This will probably get GY'd anyway, if I'm not mistaken? GUI is perfectly capable of removing effects after X seconds in a more efficient way than this.

Write a trigger that saves a global effect to a local, wait x seconds, call remove on it. To use it, set the global to the effect to be removed, and execute the trigger. Done.
 

RaiJin

New Member
Reaction score
40
Even though I think this has been done time and time again, I personally would rather see something like this:

JASS:

struct DestroyEffectEx

    private timer  t  = null
    private effect fx = null

    static method create takes effect sfx, real time returns thistype
        local thistype this = thistype.allocate()

        set this.t  = NewTimer()
        set this.fx = sfx
        
        call SetTimerData(this.t,this)
        call TimerStart(this.t,time,false,function thistype.update)

        return this
    endmethod

    private static method update takes nothing returns nothing
        call GetTimerData(GetExpiredTimer()).destroy()
    endmethod

    private method onDestroy takes nothing returns nothing
        call DestroyEffect(this.fx)
        set this.fx = null

        call ReleaseTimer(this.t)
        set this.t = null
    endmethod

endstruct

function DestroyEffectExFunc takes effect sfx, real time returns nothing
    call DestroyEffectEx.create(sfx,time)
endfunction


I'm not sure if the syntax and all that is right, but something like that would allow both normal and struct syntax, to please everyone, and it is written a little nicer.

i agree i like this it looks way more neater,

>Hey, the kind of stuff keep repeated...
yes people keep making the same stuff over and over again
 

Jesus4Lyf

Good Idea™
Reaction score
397
Graveyarded.

This isn't that useful, everyone writes their own.

It could be resurrected and approved if:
It was written in different flavors to support the user's timer system of choice.

Then it could be justified as a resource that other resources could use, while keeping abstraction from the timer sys itself (low coupling, nice programming thing).
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top