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

OverTimeEffectSystem v2.0

Level 16
Joined
Feb 22, 2006
Messages
960
Because my old version is outdated and also the thread is closed I release a new version (it's totally recoded, there is nearly no equivalent to the old version)

Requires:
- JassHelper

Credits:
- Vexorian


JASS:
This system was started some time ago. It wasn not that efficient
but now I decided to totally rework it. It is much more 
comfortable now. The usage of an function interface gives the user
endless possibilities of creating timed effects.
 
An example usage:
call OverTimeEffect.create(<unit>caster,<unit>target,<real>interval,<real>duration,<real>damage,<OTEffect>functionInterface)

The function interface OTEffect takes <unit>caster,<unit>target,<real>value and returns boolean
  
The function should allways return true if you do not want the struct to be destroyed.
If the struct should be destroyed just return false, then the struct automaticly gets destroyed.

To use this system, just copy it into your map. The knowledge of how to use function interfaces would be good but you also could read through the JassHelper Manual

JASS:
/****************************************************************************************************************************************
 *  OverTimeEffectSystem v2.0 by xD.Schurke
 *  ---------------------------------------
 *  
 *  Requires:
 *          - JassHelper (0.9.H.3)
 *          
 *  Credits:
 *          - Vexorian
 *
 *  This system was started some time ago. It wasn not that efficient
 *  but now I decided to totally rework it. It is much more 
 *  comfortable now. The usage of an function interface gives the user
 *  endless possibilities of creating timed effects.
 *  
 *  An example usage:
 *  call OverTimeEffect.create(<unit>caster,<unit>target,<real>interval,<real>duration,<real>damage,<OTEffect>functionInterface)
 *
 *  The function interface OTEffect takes <unit>caster,<unit>target,<real>value and returns boolean
 *  
 *  The function should allways return true if you do not want the struct to be destroyed.
 *  If the struct should be destroyed just return false, then the struct automaticly gets destroyed.
 *
 *  To use this system, just copy it into your map. The knowledge of how to use function interfaces would be good.
 *  but you also could read through the JassHelper Manual
 *
 *
 ****************************************************************************************************************************************/
library OverTimeEffectSystem
globals
    private constant    real    timerInterval   =   0.03125 //Interval of the timer
endglobals

function interface OTEffect takes unit caster, unit target, real value returns boolean

struct OverTimeEffect
    private         unit                caster          =   null
    private         unit                target          =   null
    private         real                interval        =   0.0
    private         real                fullDuration    =   0.0
    private         real                duration        =   0.0
    private         real                curTime         =   0.0
    private         real                value           =   0.0
    private         OTEffect            executeFunc     =   0
    //used for struct stacking
    private static  timer               tim             =   null
    private static  thistype    array   data
    private static  integer             total           =   0
    //core method, calls the function interface and evaluates the "stored" function if the function returns false the struct will be destroyed
    private static method callback takes nothing returns nothing
        local thistype this
        local integer i = 0
        local real damage = 0.0
        loop
            exitwhen i >= thistype.total
            set this = thistype.data[i]
            set this.curTime = this.curTime + timerInterval
            set this.duration = this.duration - timerInterval
            if this.curTime >= this.interval then //check if user chosed interval is reached
                set damage = this.value/(this.fullDuration/this.interval)
                if this.executeFunc.evaluate(this.caster,this.target, damage) != true then //destroy it baby
                    set this.total = this.total - 1
                    set this.data[i] = this.data[this.total]
                    set i = i - 1                                
                    call this.destroy()                      
                endif
                set this.curTime = 0.0
            endif
            if this.duration <= 0.0 then
                set this.total = this.total - 1
                set this.data[i] = this.data[this.total]
                set i = i - 1                                
                call this.destroy()                            
            endif
            set i = i + 1
        endloop
        //if there are no structs left, we should pause the timer, because it's not needed
        if thistype.total == 0 then
            call PauseTimer(thistype.tim)
        endif
    endmethod
    //setting all vars needed and also starting timer
    static method create takes unit caster, unit target, real interval, real duration, real value, OTEffect executeFunc returns thistype
        local thistype this = thistype.allocate()
        set this.caster = caster
        set this.target = target
        if interval < timerInterval then
            set this.interval = timerInterval
        else
            set this.interval = interval
        endif
        set this.fullDuration = duration
        set this.duration = duration
        set this.value = value
        set this.executeFunc = executeFunc
        if this.total == 0 then
            call TimerStart(this.tim,timerInterval, true,function thistype.callback)
        endif
        set this.data[this.total] = this
        set this.total = this.total + 1
        return this
    endmethod
    //initializing timer
    private static method onInit takes nothing returns nothing
        set thistype.tim = CreateTimer()
    endmethod
    //cleaning leaks
    private method onDestroy takes nothing returns nothing
        set this.caster = null
        set this.target = null
    endmethod
endstruct
endlibrary


Changelog

v2.0
- Released new version
 

Attachments

  • OverTimeEffectSystem v2.0.w3x
    18.8 KB · Views: 320

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,177
You do not have to null struct members if you recycle them quickly, otherwise you do.

This is purly to free up more handle indexes quicker and remember that nulling takes near no time at all. Basically globals do not automatically free the handle index like locals, however they can not leak handle indexes unlike locals. Thus nulling them lets the indexes be recycled, while otherwise if the value of a handle in an array is never overwritten, it clogs up that handle index forever (eg if for some reason you used 30 structs at one point in the game while after that the max you used only was 10, 20 indexes worth of handles would be clogged up unnescescarily).
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,454
This should run on Timer 32 so that high-frequency timers like this don't clog up overhead during gameplay (would also clear the initializer burden), uses onDestroy (I'm moving towards making it forbidden except when totally unavoidable), stack-loop is very inefficient which would also strongly benefit from Timer 32...

Some new standards are going to be released soon, as well.
 
Top