package BuffHandler import LinkedList import public BuffHandlerConfig import public BuffHandlerGen public enum BuffPolicy STACKING LAST public function unit.hasBuff(int buffTypeId) returns boolean return this.getBuffList().countBuffsOfTypeId(buffTypeId) > 0 public abstract class Buff use BuffCustomMembers private timer timerObject private int timerCounter private int timerCounterMax private boolean timerDestroyAfter private BuffList parent /** Functions that can be overridden by Buff-classes: **/ function getName() returns string return "" protected function getRaw() returns int return 0 protected function getBuffRaw() returns int return 0 protected function getPolicy() returns BuffPolicy return BuffPolicy.STACKING protected function checkApply() returns boolean if this.getPolicy() == BuffPolicy.LAST for Buff b in this.parent.buffs if b.typeId == this.typeId and b != this destroy b return true protected function onCreate() protected function onApply() protected function onRemove() protected function onDestroy() protected function onTimer() /** Buff API: **/ protected function getParentBufflist() returns BuffList return this.parent function getUnit() returns unit if this.parent != null return this.parent.u else return null function destroyAfter(real timeout) startTimed(timeout, 1, true) /** Starts a timer which calls the onTimer() function. Runs with specified timeout and a specified number of times (-1 for infinity). If destroyAfter is set, destroys buff object afterwards. */ function startTimed(real timeout, int times, boolean destroyAfter) timerDestroyAfter = destroyAfter timerCounterMax = times timerCounter = 0 timerObject = getTimer() ..setData(this castTo int) ..startPeriodic(timeout, function timerCallback) function stopTimed() timerObject.release() timerObject = null function getTimerCounter() returns int return timerCounter function getTimerCounterMax() returns int return timerCounterMax /** End of API **/ private static function timerCallback() timer t = GetExpiredTimer() thistype obj = t.getData() castTo thistype obj.timerCounter++ obj.onTimer() if obj.timerCounterMax != -1 and obj.timerCounter >= obj.timerCounterMax if obj.timerDestroyAfter destroy obj // Destroy buff (calls stopTimed() in destructor) else obj.stopTimed() // Only destroy the timer construct() this.parent = null this.initCustomMembers() this.onCreate() private function addBuffIcon() let raw = this.getRaw() if raw != 0 if parent.countBuffsOfType(this) <= 1 disableDamageEvents(true) // avoid slowaura bug which causes the dmg detection to trigger parent.u.addAbility(raw) disableDamageEvents(false) UnitMakeAbilityPermanent(parent.u, true, raw) private function removeBuffIcon() let raw = this.getRaw() if raw != 0 if parent.countBuffsOfType(this) <= 1 UnitMakeAbilityPermanent(parent.u, false, raw) parent.u.removeAbility(raw) let buffRaw = this.getBuffRaw() if buffRaw != 0 parent.u.removeAbility(buffRaw) function apply(unit target) if this.parent != null this.onRemove() this.removeBuffIcon() this.parent.buffs.remove(this) this.parent = null if target != null this.parent = target.getBuffList() if this.checkApply() this.parent.buffs.add(this) this.addBuffIcon() this.onApply() function debugPrint() print("- Buff: " + this.getName() + " #" + I2S(this castTo int) + " on unit: " + this.getUnit().getName()) ondestroy this.apply(null) this.onDestroy() this.destroyCustomMembers() if this.timerObject != null stopTimed() public class BuffList protected LinkedList buffs protected unit u construct(unit u) this.u = u this.buffs = new LinkedList() function destroyAllBuffs() while this.buffs.getSize() > 0 destroy this.buffs.get(0) function asList() returns LinkedList return buffs ondestroy this.destroyAllBuffs() destroy this.buffs function countBuffsOfTypeId(int id) returns integer var n = 0 for Buff b in this.buffs if b.typeId == id n++ return n function countBuffsOfType(Buff b) returns integer return countBuffsOfTypeId(b.typeId) function getFirstBuffOfType(int id) returns Buff Buff bf = null for Buff b in this.buffs if b.typeId == id bf = b break return bf function debugPrint() print("Buffs on unit " + u.getName() + ", BuffList #" + this castTo int.toString()) for Buff b in this.buffs b.debugPrint()