- Joined
- Jun 25, 2011
- Messages
- 36
Hi,
I would like to share this buff system and improve it if you have suggestions.
I have tested it and I didn't find bug but it's possible that there are.
(Sorry for the bad english in the code ^^)
Example :
I would like to share this buff system and improve it if you have suggestions.
I have tested it and I didn't find bug but it's possible that there are.
(Sorry for the bad english in the code ^^)
JASS:
library Buff /*
*************************************************************************************
*
* Allows rapid and efficient buff development.
*
*************************************************************************************
*
* */ uses /*
*
* - */ UnitIndexer /*
* - */ TimerUtils /*
* - */ DDS /*
* - */ optional DamageEvent /*
*
*************************************************************************************
*
* First you have to define a buff type : create a struct that extends array and
* implement BuffStruct module.
*
* struct BuffTypeA extends array
*
* implement BuffStruct
*
* endstruct
*
* Then you can configure your buff type with those optional parameters :
* - static boolean stackable = false
* - When a non-stackable buff is applied on a unit that already
* have this buff type, the old buff is refreshed.
* - See onRefresh event response for more informations.
* - static boolean permanent = false
* - Permanent buffs can't be dispelled.
* - See Dispel part for more informations.
* - static integer dispelPriority = -1
* - See Dispel part for more informations.
* - static integer auraId = 0
* - Displays the buff in the status bar of the unit.
* - To do this, create a spell based on slow aura, and the set
* targets on self.
* - Then add the corresponding buff.
* - static integer buffId = 0
* - This is the buff added by the slow aura.
* - static integer alignment = BUFF_ALIGNMENT_NEUTRAL
* - Buff alignment. There are three types :
* - BUFF_ALIGNMENT_POSITIVE
* - BUFF_ALIGNMENT_NEGATIVE
* - BUFF_ALIGNMENT_NEUTRAL
* - static boolean positiveBuffImmune = false
* - Immune unit against the positive buffs.
* - static boolean negativeBuffImmune = false
* - Immune unit against the negative buffs.
* - static boolean neutralBuffImmune = false
* - Immune unit against the neutral buffs.
* - static boolean positiveDispellImmune = false
* - Immune unit against the positive buffs dissipations.
* - static boolean negativeDispellImmune = false
* - Immune unit against the negative buffs dissipations.
* - static boolean neutralDispellImmune = false
* - Immune unit against the neutral buffs dissipations.
* - static boolean keepAtDeath = false
* - If true, the unit keep the buff at death.
* - static real period
* - Period for the periodic callback.
* - static integer damagePriority = 0
* - Priority for the onDamage method call.
* - static integer category = 0
* - Use it as you wish.
*
* Once these settings done, it is possible to add event responses.
* There are eight responses, all optional:
* - static method onApply takes Buff this returns nothing
* - Called when the buff is applied.
* - static method onPeriodic takes Buff this returns nothing
* - Method called periodically.
* - It is necessary to add a period parameter.
*
* - static method onRefresh takes Buff this returns nothing
* - Called when the buff is refreshed.
* - To access the settings from the old buff, use:
* - previousDuration
* - previousCaster
* - previousLevel
*
* - static method onDispel takes Buff this, unit dispeler, boolean b returns nothing
* - Called when an attempt to buff dissipation occur.
* - The unit argument is the unit trying to dispel the buff.
* - The boolean argument is true if the dissipation was successful
* - (so the buff will be destroyed), false otherwise.
* - See Dispel part for more informations.
*
* - static method onExpire takes Buff this returns nothing
* - Called when the buff expires (the duration is null).
* - It is possible to redefine the duration so the buff is not destroyed.
*
* - static method onDeath takes Buff this returns nothing
* - Called when the buff target dies.
*
* - static method onRemove takes Buff this returns nothing
* - Called when the buff is destroyed.
* - Redefine the duration or refresh don't prevent its destruction.
*
* - static method onDamage takes Buff this returns nothing
* - Called when buff target takes damage.
* - Can only be used with the library DamageEvent.
*
* The module implements a method apply to apply the buff and a method type which returns
* the buff type.
*
*************************************************************************************
*
* struct Buff extends array
*
* - readonly unit caster (use refresh method if you want to modify it)
* - readonly unit target
* - readonly integer targetId
* - readonly real level (use refresh method if you want to modify it)
* - readonly integer buffType
* - public real duration (method operator)
* - readonly real initialDuration (method operator)
* - static method apply takes BuffType buffType, unit caster, unit target, real level,
* real duration returns thistype
* - If the duration is null, the buff will never expire.
* - method destroy takes nothing returns nothing
* - Prefer using buff dissipation instead of destroy method.
* - method refresh takes unit caster, real level, real duration returns thistype
* - Refreshes the buff with the new settings.
* - static method has takes unit target, BuffType buffType returns boolean
* - static method count takes unit target returns integer
* - static method countType takes unit target, BuffType buffType returns integer
* - static method countAlignment takes unit target, integer alignment returns integer
* - static method immune takes unit target, integer alignment returns boolean
* - Returns true if the unit is immune to buffs of the specified alignment.
* - static method dispelImmune takes unit target, integer alignment returns boolean
* - Returns true if the unit is immune to dispels of the specified alignment.
*
*
*************************************************************************************
*
* Dispel
* ------
*
* - method dispel takes unit dispeler, integer priority returns boolean
* - The buff will be dissipated if the priority of dispel is strictly
* greater than the priority of the buff dissipation.
*
* - static method dispelAlignment takes unit dispeler, unit target, integer priority, integer alignment returns integer
* - Applies a dissipation on all buffs of the specified alignment to the target.
*
* - static method dispelAll takes unit dispeler, unit target, integer priority returns integer
* - Applies a dissipation on all bufff of the target.
*
* The permanent buffs can not be dispelled, but can be destroyed through with the destroy () method.
*
* Enumerating buffs on a unit
* ---------------------------
*
* Buffs unit are classified to enable efficient enumerations. Each buff has next and prev
* members, allowing access to the next and previous buffs:
* A1 A2 A3 C1 C2 B1 B2 B3 D1 D2 E1 E2 E3 E4 E5
* -->-->-->-->-- -> -->-->-->-->-- -> -->-->-->-->--
* Positives buffs Negatives buffs Neutral buffs
*
* There are three ways to access the buffs a unit:
* - local Buff this = Buff[unit]
* - Returns the first buff of the unit (A1 in the example) :
* - loop
* exitwhen this == 0
* set this = this.next
* endloop
* - local Buff this = Buff[unit][type]
* - Returns the first unit buff of the specified type (A1, C1, B1, D1 or E1 in the example)
* - loop
* exitwhen this.type != myType
* set this = this.next
* endloop
* - local Buff this = Buff[unit][alignment]
* - Returns the first unit buff of the specified alignment (A1, B1 or E1 in the example)
* - loop
* exitwhen this.type.alignment != monAlignement
* set this = this.next
* endloop
*
*************************************************************************************/
globals
key BUFF_ALIGNMENT_POSITIVE
key BUFF_ALIGNMENT_NEGATIVE
key BUFF_ALIGNMENT_NEUTRAL
endglobals
globals
private constant integer applyEvent = 0
private constant integer refreshEvent = 1
private constant integer dispelEvent = 2
private constant integer removeEvent = 3
private constant integer expireEvent = 4
private constant integer deathEvent = 5
private boolean eventBool
private integer triggerBuff
private boolexpr array buffEvent
private integer eventType
private trigger eventTrig = CreateTrigger()
endglobals
globals
private real array buffTypePeriod
private boolean array buffTypeStackable
private integer array buffTypeAuraId
private integer array buffTypeBuffId
private integer array buffTypeAlignment
private integer array buffTypeDispelPriority
private boolean array buffTypePermanent
private boolean array buffTypePositiveBuffImmune
private boolean array buffTypeNegativeBuffImmune
private boolean array buffTypeNeutralBuffImmune
private boolean array buffTypePositiveDispelImmune
private boolean array buffTypeNegativeDispelImmune
private boolean array buffTypeNeutralDispelImmune
private boolean array buffTypeKeepAtDeath
private boolean array buffTypeHasApplyEvent
private boolean array buffTypeHasDeathEvent
private boolean array buffTypeHasRemoveEvent
private boolean array buffTypeHasDispelEvent
private boolean array buffTypeHasExpireEvent
private boolean array buffTypeHasRefreshEvent
private integer array buffTypeCategory
endglobals
struct BuffType extends array
method operator stackable takes nothing returns boolean
return buffTypeStackable[this]
endmethod
method operator period takes nothing returns real
return buffTypePeriod[this]
endmethod
method operator auraId takes nothing returns integer
return buffTypeAuraId[this]
endmethod
method operator buffId takes nothing returns integer
return buffTypeBuffId[this]
endmethod
method operator alignment takes nothing returns integer
return buffTypeAlignment[this]
endmethod
method operator dispelPriority takes nothing returns integer
return buffTypeDispelPriority[this]
endmethod
method operator permanent takes nothing returns boolean
return buffTypePermanent[this]
endmethod
method operator positiveBuffImmune takes nothing returns boolean
return buffTypePositiveBuffImmune[this]
endmethod
method operator negativeBuffImmune takes nothing returns boolean
return buffTypeNegativeBuffImmune[this]
endmethod
method operator neutralBuffImmune takes nothing returns boolean
return buffTypeNeutralBuffImmune[this]
endmethod
method operator positiveDispelImmune takes nothing returns boolean
return buffTypePositiveDispelImmune[this]
endmethod
method operator negativeDispelImmune takes nothing returns boolean
return buffTypeNegativeDispelImmune[this]
endmethod
method operator neutralDispelImmune takes nothing returns boolean
return buffTypeNeutralDispelImmune[this]
endmethod
method operator keepAtDeath takes nothing returns boolean
return buffTypeKeepAtDeath[this]
endmethod
method operator hasApplyEvent takes nothing returns boolean
return buffTypeHasApplyEvent[this]
endmethod
method operator hasDeathEvent takes nothing returns boolean
return buffTypeHasDeathEvent[this]
endmethod
method operator hasRemoveEvent takes nothing returns boolean
return buffTypeHasRemoveEvent[this]
endmethod
method operator hasDispelEvent takes nothing returns boolean
return buffTypeHasDispelEvent[this]
endmethod
method operator hasExpireEvent takes nothing returns boolean
return buffTypeHasExpireEvent[this]
endmethod
method operator hasRefreshEvent takes nothing returns boolean
return buffTypeHasRefreshEvent[this]
endmethod
method operator category takes nothing returns integer
return buffTypeCategory[this]
endmethod
endstruct
globals
// Periodic timer for onPeriodic method.
private timer array periodicTim
endglobals
private module Init
private static method onInit takes nothing returns nothing
local trigger death = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(death, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(death, Filter(function thistype.onDeath))
call UnitIndexer.DEINDEX.register(Filter(function thistype.onDeindex))
endmethod
endmodule
struct Buff extends array
readonly static real previousLevel = 0
readonly static unit previousCaster = null
readonly static real previousDuration = 0
private static integer array buffCount
private static thistype array firstBuff
private static hashtable table = InitHashtable()
private static integer instanceCount = 0
private thistype recycle
readonly thistype prev
readonly thistype next
readonly real level
readonly unit caster
readonly integer targetId
readonly BuffType buffType
private timer tim
method operator target takes nothing returns unit
return GetUnitById(targetId)
endmethod
method operator initialDuration takes nothing returns real
return TimerGetTimeout(tim)
endmethod
method operator duration takes nothing returns real
return TimerGetRemaining(tim)
endmethod
method operator duration= takes real dur returns nothing
if (dur > 0) then
if (tim == null) then
set tim = NewTimerEx(this)
endif
call TimerStart(tim, dur, false, function thistype.expire)
else
if (tim != null) then
call ReleaseTimer(tim)
set tim = null
endif
endif
endmethod
static method has takes unit targ, integer id returns boolean
return HaveSavedInteger(table, GetUnitUserData(targ), id)
endmethod
static method count takes unit target returns integer
return buffCount[GetUnitUserData(target)]
endmethod
static method countType takes unit target, integer id returns integer
return LoadInteger(table, GetUnitUserData(target), -id)
endmethod
static method countAlignment takes unit target, integer align returns integer
return LoadInteger(table, GetUnitUserData(target), -align)
endmethod
static method operator [] takes unit targ returns thistype
return firstBuff[GetUnitUserData(targ)]
endmethod
method operator [] takes integer id returns thistype
return LoadInteger(table, GetUnitUserData(target), id)
endmethod
static method immune takes unit targ, integer align returns boolean
return LoadInteger(table, -GetUnitUserData(targ), align) > 0
endmethod
static method immuneById takes integer targetId, integer align returns boolean
return LoadInteger(table, -targetId, align) > 0
endmethod
static method dispelImmune takes unit targ, integer align returns boolean
return LoadInteger(table, -GetUnitUserData(targ), -align) > 0
endmethod
static method dispelImmuneById takes integer targetId, integer align returns boolean
return LoadInteger(table, -targetId, -align) > 0
endmethod
// Methods for more readability
//******************************************************************************************
private static method increaseImmuneCount takes integer targetId, integer alignment returns nothing
call SaveInteger(table, -targetId, alignment, LoadInteger(table, -targetId, alignment) + 1)
endmethod
private static method decreaseImmuneCount takes integer targetId, integer alignment returns nothing
call SaveInteger(table, -targetId, alignment, LoadInteger(table, -targetId, alignment) - 1)
endmethod
private static method increaseDispelImmuneCount takes integer targetId, integer alignment returns nothing
call SaveInteger(table, -targetId, -alignment, LoadInteger(table, -targetId, -alignment) + 1)
endmethod
private static method decreaseDispelImmuneCount takes integer targetId, integer alignment returns nothing
call SaveInteger(table, -targetId, -alignment, LoadInteger(table, -targetId, -alignment) - 1)
endmethod
private static method increaseCount takes integer targetId, integer id returns nothing
call SaveInteger(table, targetId, -id, LoadInteger(table, targetId, -id) + 1)
endmethod
private static method decreaseCount takes integer targetId, integer id returns nothing
call SaveInteger(table, targetId, -id, LoadInteger(table, targetId, -id) - 1)
endmethod
private static method first takes integer targetId, integer id returns thistype
return LoadInteger(table, targetId, id)
endmethod
private static method setFirst takes integer targetId, integer id, integer this returns nothing
call SaveInteger(table, targetId, id, this)
endmethod
private static method removeCount takes integer targetId, integer id returns nothing
call RemoveSavedInteger(table, targetId, -id)
endmethod
private static method removeFirst takes integer targetId, integer id returns nothing
call RemoveSavedInteger(table, targetId, id)
endmethod
//********************************************************************************************
private method fireEvent takes integer whichEvent returns nothing
set eventType = whichEvent
set triggerBuff = this
call TriggerClearConditions(eventTrig)
call TriggerAddCondition(eventTrig, buffEvent[buffType])
call TriggerEvaluate(eventTrig)
endmethod
method destroy takes nothing returns nothing
local thistype previous = first(targetId, buffType)
if (buffType.hasRemoveEvent) then
call fireEvent(removeEvent)
endif
set buffCount[targetId] = buffCount[targetId] - 1
call decreaseCount(targetId, buffType)
call decreaseCount(targetId, buffType.alignment)
if (buffType.positiveBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (buffType.positiveDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (this == previous) then
if (buffType != next.buffType) then
call removeFirst(targetId, buffType)
call removeCount(targetId, buffType)
call UnitRemoveAbility(target, buffType.auraId)
call UnitRemoveAbility(target, buffType.buffId)
else
call setFirst(targetId, buffType, next)
endif
set previous = first(targetId, buffType.alignment)
if (this == previous) then
if (buffType.alignment != next.buffType.alignment) then
call removeFirst(targetId, buffType.alignment)
call removeCount(targetId, buffType.alignment)
else
call setFirst(targetId, buffType.alignment, next)
endif
endif
endif
if (prev == 0) then
set firstBuff[targetId] = next
else
set prev.next = next
endif
set next.prev = prev
set caster = null
call ReleaseTimer(tim)
set tim = null
call ReleaseTimer(periodicTim[this])
set periodicTim[this] = null
set recycle = thistype(0).recycle
set thistype(0).recycle = this
endmethod
method dispel takes unit cast, integer priority returns boolean
set eventBool = priority > buffType.dispelPriority and not buffType.permanent and not dispelImmuneById(targetId, buffType.alignment)
if (buffType.hasDispelEvent) then
set thistype(0).caster = cast
call fireEvent(dispelEvent)
endif
if (eventBool) then
call destroy()
endif
return eventBool
endmethod
static method dispelAlignment takes unit cast, unit targ, integer priority, integer align returns integer
local thistype this = thistype[targ][align]
local integer c = 0
loop
exitwhen (buffType.alignment != align)
set eventBool = priority > buffType.dispelPriority and not buffType.permanent and not dispelImmuneById(targetId, align)
if (buffType.hasDispelEvent) then
set thistype(0).caster = cast
call fireEvent(dispelEvent)
endif
if (eventBool) then
set c = c + 1
call destroy()
endif
set this = next
endloop
return c
endmethod
static method dispelAll takes unit cast, unit targ, integer priority returns integer
return dispelAlignment(cast, targ, priority, BUFF_ALIGNMENT_POSITIVE) + /*
*/ dispelAlignment(cast, targ, priority, BUFF_ALIGNMENT_NEGATIVE) + /*
*/ dispelAlignment(cast, targ, priority, BUFF_ALIGNMENT_NEUTRAL)
endmethod
private static method expire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if (buffType.hasExpireEvent) then
call fireEvent(expireEvent)
endif
if (tim != null and duration == 0) then
call destroy()
endif
endmethod
method refresh takes unit cast, real lev, real dur returns thistype
local real plev = previousLevel
local real pdur = previousDuration
local unit pcas = previousCaster
set previousLevel = level
set previousDuration = duration
set previousCaster = caster
set caster = cast
set level = lev
set duration = dur
if (buffType.hasRefreshEvent) then
call fireEvent(refreshEvent)
endif
set previousLevel = plev
set previousDuration = pdur
set previousCaster = pcas
return this
endmethod
static method apply takes BuffType buffType, unit cast, unit targ, real lev, real duration returns thistype
local thistype this
local thistype previous
local thistype align
local integer targId = GetUnitUserData(targ)
if (targId == 0 or immuneById(targId, buffType.alignment)) then
return 0
endif
set previous = LoadInteger(table, targId, buffType)
if (not buffType.stackable and previous != 0) then
return previous.refresh(cast, lev, duration)
else
if (thistype(0).recycle != 0) then
set this = thistype(0).recycle
set thistype(0).recycle = recycle
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
set align = first(targId, buffType.alignment)
if (previous == 0) then
if (align == 0) then
set previous = firstBuff[targId]
else
set previous = align
endif
call UnitAddAbility(targ, buffType.auraId)
call SetUnitAbilityLevel(targ, buffType.auraId, R2I(lev))
call UnitMakeAbilityPermanent(targ, true, buffType.auraId)
endif
if (previous == firstBuff[targId]) then
set firstBuff[targId] = this
call setFirst(targId, buffType.alignment, this)
elseif (previous == align) then
call setFirst(targId, buffType.alignment, this)
endif
call setFirst(targId, buffType, this)
set prev = previous.prev
set next = previous
set prev.next = this
set next.prev = this
call increaseCount(targId, buffType)
call increaseCount(targId, buffType.alignment)
set buffCount[targId] = buffCount[targId] + 1
if (buffType.positiveBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (buffType.positiveDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_NEUTRAL)
endif
set caster = cast
set targetId = targId
set level = lev
set this.buffType = buffType
if (duration > 0) then
set tim = NewTimerEx(this)
call TimerStart(tim, duration, false, function thistype.expire)
endif
if (buffType.hasApplyEvent) then
call fireEvent(applyEvent)
endif
endif
return this
endmethod
private static method onDeath takes nothing returns boolean
local thistype this = firstBuff[GetUnitUserData(GetDyingUnit())]
loop
exitwhen (this == 0)
if (buffType.hasDeathEvent) then
call fireEvent(deathEvent)
endif
if (not buffType.keepAtDeath) then
call destroy()
endif
set this = next
endloop
return false
endmethod
private static method onDeindex takes nothing returns boolean
local integer unitId = GetIndexedUnitId()
local thistype this = firstBuff[unitId]
loop
exitwhen (this == 0)
if (buffType.hasRemoveEvent) then
call fireEvent(removeEvent)
endif
if (next == 0) then
set recycle = thistype(0).recycle
else
set recycle = next
endif
set caster = null
call ReleaseTimer(tim)
set tim = null
call ReleaseTimer(periodicTim[this])
set periodicTim[this] = null
set this = next
endloop
set this = firstBuff[unitId]
set firstBuff[unitId] = 0
set buffCount[unitId] = 0
call FlushChildHashtable(table, unitId)
call FlushChildHashtable(table, -unitId)
set thistype(0).recycle = this
return false
endmethod
implement Init
endstruct
private struct DefaultValues extends array
static boolean stackable = false
static boolean permanent = false
static integer dispelPriority = -1
static integer auraId = 0
static integer buffId = 0
static integer alignment = BUFF_ALIGNMENT_NEUTRAL
static boolean positiveBuffImmune = false
static boolean negativeBuffImmune = false
static boolean neutralBuffImmune = false
static boolean positiveDispelImmune = false
static boolean negativeDispelImmune = false
static boolean neutralDispelImmune = false
static boolean keepAtDeath = false
static integer category = 0
static if (LIBRARY_PriorityEvent) then
static integer damagePriority = 0
endif
endstruct
module BuffStruct
private static delegate DefaultValues default
static if (LIBRARY_DamageEvent and thistype.onDamage.exists) then
private static method damageCall takes nothing returns boolean
static if (thistype.damageFilter.exists) then
local Buff this
if (damageFilter()) then
set this = Buff[DDS.target][typeid]
loop
exitwhen (this == 0)
call onDamage(this)
set this = this.next
endloop
endif
else
local Buff this = Buff[DDS.target][typeid]
loop
exitwhen (this == 0)
call onDamage(this)
set this = this.next
endloop
endif
return false
endmethod
endif
static if (thistype.onPeriodic.exists) then
private static method periodicCall takes nothing returns nothing
call onPeriodic(GetTimerData(GetExpiredTimer()))
endmethod
endif
private static method onEvent takes nothing returns boolean
if (eventType == applyEvent) then
static if thistype.onPeriodic.exists then
set periodicTim[triggerBuff] = NewTimerEx(triggerBuff)
call TimerStart(periodicTim[triggerBuff], buffType.period, true, function thistype.periodicCall)
endif
static if thistype.onApply.exists then
call onApply(triggerBuff)
endif
elseif (eventType == dispelEvent) then
static if (thistype.onDispel.exists) then
call onDispel(triggerBuff, Buff(0).caster, eventBool)
endif
elseif (eventType == refreshEvent) then
static if (thistype.onRefresh.exists) then
call onRefresh(triggerBuff)
endif
elseif (eventType == removeEvent) then
static if (thistype.onRemove.exists) then
call onRemove(triggerBuff)
endif
elseif (eventType == expireEvent) then
static if thistype.onExpire.exists then
call onExpire(triggerBuff)
endif
elseif (eventType == deathEvent) then
static if (thistype.onDeath.exists) then
call onDeath(triggerBuff)
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
set buffEvent[typeid] = Filter(function thistype.onEvent)
set buffTypeStackable[typeid] = stackable
static if thistype.onPeriodic.exists then
set buffTypePeriod[typeid] = period
endif
set buffTypeAuraId[typeid] = auraId
set buffTypeBuffId[typeid] = buffId
set buffTypeAlignment[typeid] = alignment
set buffTypeDispelPriority[typeid] = dispelPriority
set buffTypePermanent[typeid] = permanent
set buffTypePositiveBuffImmune[typeid] = positiveBuffImmune
set buffTypeNegativeBuffImmune[typeid] = negativeBuffImmune
set buffTypeNeutralBuffImmune[typeid] = neutralBuffImmune
set buffTypePositiveDispelImmune[typeid] = positiveDispelImmune
set buffTypeNegativeDispelImmune[typeid] = negativeDispelImmune
set buffTypeNeutralDispelImmune[typeid] = neutralDispelImmune
set buffTypeKeepAtDeath[typeid] = keepAtDeath
set buffTypeCategory[typeid] = category
static if (LIBRARY_DamageEvent and thistype.onDamage.exists) then
static if LIBRARY_PriorityEvent then
call DDS.ANY.register(Filter(function thistype.damageCall), damagePriority)
else
call DDS.ANY.register(Filter(function thistype.damageCall))
endif
endif
static if (thistype.onApply.exists) then
set buffTypeHasApplyEvent[typeid] = true
elseif (thistype.onPeriodic.exists) then
set buffTypeHasApplyEvent[typeid] = true
endif
static if (thistype.onRefresh.exists) then
set buffTypeHasRefreshEvent[typeid] = true
endif
static if (thistype.onRemove.exists) then
set buffTypeHasRemoveEvent[typeid] = true
endif
static if (thistype.onExpire.exists) then
set buffTypeHasExpireEvent[typeid] = true
endif
static if (thistype.onDeath.exists) then
set buffTypeHasDeathEvent[typeid] = true
endif
static if (thistype.onDispel.exists) then
set buffTypeHasDispelEvent[typeid] = true
endif
endmethod
static method apply takes unit caster, unit target, real level, real duration returns Buff
return Buff.apply(typeid, caster, target, level, duration)
endmethod
static method operator buffType takes nothing returns BuffType
return typeid
endmethod
static method operator previousCaster takes nothing returns unit
return Buff.previousCaster
endmethod
static method operator previousDuration takes nothing returns real
return Buff.previousDuration
endmethod
static method operator previousLevel takes nothing returns real
return Buff.previousLevel
endmethod
endmodule
endlibrary
Example :
JASS:
scope MagicShield initializer onInit
//Very original name :P
struct MagicShield extends array
private static constant integer auraId = 'A000' //Spell based on slow aura
private static constant integer buffId = 'B000' //The buff added by the slow aura
private static constant boolean negativeBuffImmune = true
/*
private static method onApply takes Buff this returns nothing
call UnitAddArmor(this.target, R2I(this.level))
endmethod
private static method onRefresh takes Buff this returns nothing
call UnitRemoveArmor(this.target, R2I(previousLevel))
call UnitAddArmor(this.target, R2S(this.level))
endmethod
private static method onRemove takes Buff this returns nothing
call UnitRemoveArmor(this.target, R2I(this.level))
endmethod
*/
private static method onDamage takes Buff this returns nothing
call SetUnitState(this.target, UNIT_STATE_LIFE, GetUnitState(this.target, UNIT_STATE_LIFE) + DamageEvent.amount / 2)
endmethod
implement BuffStruct
endstruct
private function onInit takes nothing returns nothing
local unit caster = CreateUnit(Player(0), 'Hpal', 0, 0, 0)
local unit target = CreateUnit(Player(0), 'hfoo', 200, 0, 0)
local unit attacker = CreateUnit(Player(1), 'hfoo', 300, 0, 180)
call MagicShield.apply(caster, target, 3, 15)
set caster = null
set target = null
set attacker = null
endfunction
endscope
Last edited: