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)
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 functioninterface 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 functioninterface OTEffect takes<unit>caster,<unit>target,<real>value andreturnsboolean
The function should allways returntrueif you do not want the struct to be destroyed.
If the struct should be destroyed just returnfalse,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
Script
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
globalsprivateconstantreal timerInterval =0.03125//Interval of the timerendglobalsfunctioninterface OTEffect takesunit caster,unit target,real value returnsbooleanstruct OverTimeEffect
privateunit caster =nullprivateunit target =nullprivatereal interval =0.0privatereal fullDuration =0.0privatereal duration =0.0privatereal curTime =0.0privatereal value =0.0private OTEffect executeFunc =0//used for struct stackingprivatestatictimer tim =nullprivatestaticthistypearray data
privatestaticinteger total =0//core method, calls the function interface and evaluates the "stored" function if the function returns false the struct will be destroyedprivatestaticmethod callback takesnothingreturnsnothinglocalthistypethislocalinteger i =0localreal damage =0.0loopexitwhen i >=thistype.totalsetthis=thistype.data[i]setthis.curTime=this.curTime+ timerInterval
setthis.duration=this.duration- timerInterval
ifthis.curTime>=this.intervalthen//check if user chosed interval is reachedset damage =this.value/(this.fullDuration/this.interval)ifthis.executeFunc.evaluate(this.caster,this.target, damage)!=truethen//destroy it babysetthis.total=this.total-1setthis.data[i]=this.data[this.total]set i = i -1callthis.destroy()endifsetthis.curTime=0.0endififthis.duration<=0.0thensetthis.total=this.total-1setthis.data[i]=this.data[this.total]set i = i -1callthis.destroy()endifset i = i +1endloop//if there are no structs left, we should pause the timer, because it's not neededifthistype.total==0thencallPauseTimer(thistype.tim)endifendmethod//setting all vars needed and also starting timerstaticmethod create takesunit caster,unit target,real interval,real duration,real value, OTEffect executeFunc returnsthistypelocalthistypethis=thistype.allocate()setthis.caster= caster
setthis.target= target
if interval < timerInterval thensetthis.interval= timerInterval
elsesetthis.interval= interval
endifsetthis.fullDuration= duration
setthis.duration= duration
setthis.value= value
setthis.executeFunc= executeFunc
ifthis.total==0thencallTimerStart(this.tim,timerInterval,true,functionthistype.callback)endifsetthis.data[this.total]=thissetthis.total=this.total+1returnthisendmethod//initializing timerprivatestaticmethod onInit takesnothingreturnsnothingsetthistype.tim=CreateTimer()endmethod//cleaning leaksprivatemethod onDestroy takesnothingreturnsnothingsetthis.caster=nullsetthis.target=nullendmethodendstructendlibrary
You could just initialize the timer in the globals block instead of the onInit method. I'm also pretty sure that struct members don't need to be nulled.
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).
But do you really need it? With more uses (lets say casting it 100 times, thats not that hard in bigger maps) you have about 100 timers which run every X seconds, thats to much.
Edit: Umm, the struct name is really ugly. I would prefer TEffectData or something like that.