- Joined
- Aug 26, 2009
- Messages
- 192
[WurstScript] StatusHandler 1.2
StatusHandler is a library for WurstScript which provides an easy way to apply status effects like stuns and silences.
There are no requirements except for the obligatory WurstScript StandardLib.
Code:
Object Generation:
Configuration:
To configure the StatusHandler, create a package named "StatusHandlerConfig" and specify the ability and buff ids. You also have to implement the two functions "function unit.getIndex() returns int" and "function int.getUnit() returns unit". Here is an example implementation in case you don't use a unit indexer yet.
GitHub:
StatusHandler
Changelog:
1.0 - Initial release
1.1 - Made abilities require level 6 to also apply status effects to magic immunte units
1.2 - Added the function removeTimedStatus(), reduceTimedStatus(real timeout), clearStatus(), clearAll() and changed the function order a bit
Credits:
- Pingufex, the bishop of antarctica and the leader of the worldwide Pingu Church
- muzzel
- WaterKnight
- Crigges
- PurgeandFire
StatusHandler is a library for WurstScript which provides an easy way to apply status effects like stuns and silences.
There are no requirements except for the obligatory WurstScript StandardLib.
Code:
Wurst:
/**
* A package to apply status effects like stun and silence.
* This package counts the amount of applied and removed status effects,
* therefore you have to care yourself about how many times you add or
* remove a status effect from a unit. To use this, you will need a
* Unit Indexer and have to implement the function in the config file.
*/
package StatusHandler
import StatusHandlerConfig
import DummyCaster
constant DummyCaster STUN_DUMMY_CASTER = new DummyCaster(STUN_ABILITY_ID, "firebolt", DUMMY_PLAYER, false)
constant DummyCaster SILENCE_DUMMY_CASTER = new DummyCaster(SILENCE_ABILITY_ID, "soulburn", DUMMY_PLAYER, false)
constant DummyCaster DISARM_BOTH_DUMMY_CASTER = new DummyCaster(DISARM_BOTH_ABILITY_ID, "drunkenhaze", DUMMY_PLAYER, false)
constant DummyCaster DISARM_MELEE_DUMMY_CASTER = new DummyCaster(DISARM_MELEE_ABILITY_ID, "drunkenhaze", DUMMY_PLAYER, false)
constant DummyCaster DISARM_RANGED_DUMMY_CASTER = new DummyCaster(DISARM_RANGED_ABILITY_ID, "drunkenhaze", DUMMY_PLAYER, false)
constant DummyCaster ENSNARE_DUMMY_CASTER = new DummyCaster(ENSNARE_ABILITY_ID, "ensnare", DUMMY_PLAYER, false)
/**
* A class which holds all informations about the status effect of the given unit.
*/
public class Status
protected static Status array status
protected timer stunTimer
protected int stunCounter
protected timer silenceTimer
protected int silenceCounter
protected timer ensnareTimer
protected int ensnareCounter
protected timer disarmBothTimer
protected int disarmBothCounter
protected timer disarmMeleeTimer
protected int disarmMeleeCounter
protected timer disarmRangedTimer
protected int disarmRangedCounter
/**
* Constructs a Status object with the given unit.
*
* unit u - the unit whose Status object is being created
*/
construct(unit u)
int i = u.getIndex()
status[i] = this
stunTimer = null
stunCounter = 0
silenceTimer = null
silenceCounter = 0
ensnareTimer = null
ensnareCounter = 0
disarmBothTimer = null
disarmBothCounter = 0
disarmMeleeTimer = null
disarmMeleeCounter = 0
disarmRangedTimer = null
disarmRangedCounter = 0
ondestroy
if stunTimer != null
stunTimer.release()
if silenceTimer != null
silenceTimer.release()
if ensnareTimer != null
ensnareTimer.release()
if disarmBothTimer != null
disarmBothTimer.release()
if disarmMeleeTimer != null
disarmMeleeTimer.release()
if disarmRangedTimer != null
disarmRangedTimer.release()
/**
* Returns a boolean indicating if the unit is stunned.
*
* returns true if the unit is stunned, false otherwise
*/
public function unit.isStunned() returns boolean
return Status.status[this.getIndex()].stunCounter > 0
/**
* Applys a stun to the given unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all stuns which have been applied before.
*/
public function unit.addStun()
if not this.isStunned()
STUN_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].stunCounter++
/**
* Applies a timed stun to the given unit. If there is already a timed stun on this unit,
* the stun with the longer duration will be used.
*
* real timeout - the stun duration
*/
public function unit.addStunTimed(real timeout)
int i = this.getIndex()
if Status.status[i].stunTimer != null and Status.status[i].stunTimer.getRemaining() >= timeout
return
if Status.status[i].stunTimer == null
Status.status[i].stunTimer = getTimer()..setData(i)
this.addStun()
Status.status[i].stunTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeStun()
Status.status[j].stunTimer.release()
Status.status[j].stunTimer = null
end)
/**
* Reduces the timed stun duration by the given amount. If the duration is smaller
* then the given amount the timed stun is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedStun(real timeout)
int i = this.getIndex()
if Status.status[i].stunTimer == null
return
if Status.status[i].stunTimer.getRemaining() - timeout > 0.
Status.status[i].stunTimer.start(Status.status[i].stunTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeStun()
Status.status[j].stunTimer.release()
Status.status[j].stunTimer = null
end)
else
this.removeStun()
Status.status[i].stunTimer.release()
Status.status[i].stunTimer = null
/**
* Removes one stun stack from the given unit. It is possible that the unit
* is still stunned afterwards. Throws a warning if a non-existing stun is being
* removed.
*/
public function unit.removeStun()
Status.status[this.getIndex()].stunCounter--
if Status.status[this.getIndex()].stunCounter < 0
printWarning("StatusHandler: tried removing a non-existing stun.")
Status.status[this.getIndex()].stunCounter = 0
if not this.isStunned()
this.removeAbility(STUN_BUFF_ID)
/**
* Removes the current timed stun from the given unit. This only removes
* the timed stun. Stuns applied with addStun() might still exist. Throws
* a warning if there is no timed stun active.
*/
public function unit.removeTimedStun()
int i = this.getIndex()
if Status.status[i].stunTimer != null
i.getUnit().removeStun()
Status.status[i].stunTimer.release()
Status.status[i].stunTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed stun.")
/**
* Removes all stun stacks and the timed stun from the given unit. Afterwards
* the unit is not stunned anymore.
*/
public function unit.clearStun()
int i = this.getIndex()
if not this.isStunned()
this.removeAbility(STUN_BUFF_ID)
Status.status[i].stunCounter = 0
if Status.status[i].stunTimer != null
i.getUnit().removeStun()
Status.status[i].stunTimer.release()
Status.status[i].stunTimer = null
/**
* Returns a boolean indicating if the unit is silenced.
*
* returns true if the unit is silenced, false otherwise
*/
public function unit.isSilenced() returns boolean
return Status.status[this.getIndex()].silenceCounter > 0
/**
* Applys a silence to the given unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all silences which have been applied before.
*/
public function unit.addSilence()
if not this.isSilenced()
SILENCE_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].silenceCounter++
/**
* Applies a timed silence to the given unit. If there is already a timed silence on this unit,
* the silence with the longer duration will be used.
*
* real timeout - the silence duration
*/
public function unit.addSilenceTimed(real timeout)
int i = this.getIndex()
if Status.status[i].silenceTimer != null and Status.status[i].silenceTimer.getRemaining() >= timeout
return
if Status.status[i].silenceTimer == null
Status.status[i].silenceTimer = getTimer()..setData(i)
this.addSilence()
Status.status[i].silenceTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeSilence()
Status.status[j].silenceTimer.release()
Status.status[j].silenceTimer = null
end)
/**
* Reduces the timed silence duration by the given amount. If the duration is smaller
* then the given amount the timed silence is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedSilence(real timeout)
int i = this.getIndex()
if Status.status[i].silenceTimer == null
return
if Status.status[i].silenceTimer.getRemaining() - timeout > 0.
Status.status[i].silenceTimer.start(Status.status[i].silenceTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeSilence()
Status.status[j].silenceTimer.release()
Status.status[j].silenceTimer = null
end)
else
this.removeSilence()
Status.status[i].silenceTimer.release()
Status.status[i].silenceTimer = null
/**
* Removes one silence stack from the given unit. It is possible that the unit
* is still silenced afterwards. Throws a warning if a non-existing silence is being
* removed.
*/
public function unit.removeSilence()
Status.status[this.getIndex()].silenceCounter--
if Status.status[this.getIndex()].silenceCounter < 0
printWarning("StatusHandler: tried removing a non-existing silence.")
Status.status[this.getIndex()].silenceCounter = 0
if not this.isSilenced()
this.removeAbility(SILENCE_BUFF_ID)
/**
* Removes the current timed silence from the given unit. This only removes
* the timed silence. Silences applied with addSilence() might still exist. Throws
* a warning if there is no timed silence active.
*/
public function unit.removeTimedSilence()
int i = this.getIndex()
if Status.status[i].silenceTimer != null
i.getUnit().removeSilence()
Status.status[i].silenceTimer.release()
Status.status[i].silenceTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed silence.")
/**
* Removes all silence stacks and the timed silence from the given unit. Afterwards
* the unit is not silenced anymore.
*/
public function unit.clearSilence()
int i = this.getIndex()
if not this.isSilenced()
this.removeAbility(SILENCE_BUFF_ID)
Status.status[i].silenceCounter = 0
if Status.status[i].silenceTimer != null
i.getUnit().removeSilence()
Status.status[i].silenceTimer.release()
Status.status[i].silenceTimer = null
/**
* Returns a boolean indicating if the unit is ensnared.
*
* returns true if the unit is ensnared, false otherwise
*/
public function unit.isEnsnared() returns boolean
return Status.status[this.getIndex()].ensnareCounter > 0
/**
* Ensnares the given unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all ensnares which have been applied before.
*/
public function unit.addEnsnare()
if not this.isEnsnared()
ENSNARE_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].ensnareCounter++
/**
* Applies a timed ensnare to the given unit. If there is already a timed ensnare on this unit,
* the ensnare with the longer duration will be used.
*
* real timeout - the ensnare duration
*/
public function unit.addEnsnareTimed(real timeout)
int i = this.getIndex()
if Status.status[i].ensnareTimer != null and Status.status[i].ensnareTimer.getRemaining() >= timeout
return
if Status.status[i].ensnareTimer == null
Status.status[i].ensnareTimer = getTimer()..setData(i)
this.addEnsnare()
Status.status[i].ensnareTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeEnsnare()
Status.status[j].ensnareTimer.release()
Status.status[j].ensnareTimer = null
end)
/**
* Reduces the timed ensnare duration by the given amount. If the duration is smaller
* then the given amount the timed ensnare is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedEnsnare(real timeout)
int i = this.getIndex()
if Status.status[i].ensnareTimer == null
return
if Status.status[i].ensnareTimer.getRemaining() - timeout > 0.
Status.status[i].ensnareTimer.start(Status.status[i].ensnareTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeEnsnare()
Status.status[j].ensnareTimer.release()
Status.status[j].ensnareTimer = null
end)
else
this.removeEnsnare()
Status.status[i].ensnareTimer.release()
Status.status[i].ensnareTimer = null
/**
* Removes the current timed ensnare from the given unit. This only removes
* the timed ensnare. Ensnares applied with addEnsnare() might still exist. Throws
* a warning if there is no timed ensnare active.
*/
public function unit.removeTimedEnsnare()
int i = this.getIndex()
if Status.status[i].ensnareTimer != null
i.getUnit().removeEnsnare()
Status.status[i].ensnareTimer.release()
Status.status[i].ensnareTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed ensnare.")
/**
* Removes all ensnare stacks and the timed ensnare from the given unit. Afterwards
* the unit is not ensnared anymore.
*/
public function unit.clearEnsnare()
int i = this.getIndex()
if not this.isEnsnared()
this.removeAbility(ENSNARE1_BUFF_ID)
this.removeAbility(ENSNARE2_BUFF_ID)
Status.status[i].ensnareCounter = 0
if Status.status[i].ensnareTimer != null
i.getUnit().removeEnsnare()
Status.status[i].ensnareTimer.release()
Status.status[i].ensnareTimer = null
/**
* Removes one ensnare stack from the given unit. It is possible that the unit
* is still ensnared afterwards. Throws a warning if a non-existing ensnare is being
* removed.
*/
public function unit.removeEnsnare()
Status.status[this.getIndex()].ensnareCounter--
if Status.status[this.getIndex()].ensnareCounter < 0
printWarning("StatusHandler: tried removing a non-existing ensnare.")
Status.status[this.getIndex()].ensnareCounter = 0
if not this.isEnsnared()
this.removeAbility(ENSNARE1_BUFF_ID)
this.removeAbility(ENSNARE2_BUFF_ID)
/**
* Returns a boolean indicating if the unit is disarmed.
*
* returns true if the unit is disarmed, false otherwise
*/
public function unit.isDisarmedBoth() returns boolean
return Status.status[this.getIndex()].disarmBothCounter > 0
/**
* Disarms the given unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all disarmbuffs which have been applied before.
*/
public function unit.addDisarmBoth()
if not this.isDisarmedBoth()
DISARM_BOTH_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].disarmBothCounter++
/**
* Applies a timed disarm to the given unit. If there is already a timed disarm on this unit,
* the disarm with the longer duration will be used.
*
* real timeout - the disarm duration
*/
public function unit.addDisarmBothTimed(real timeout)
int i = this.getIndex()
if Status.status[i].disarmBothTimer != null and Status.status[i].disarmBothTimer.getRemaining() >= timeout
return
if Status.status[i].disarmBothTimer == null
Status.status[i].disarmBothTimer = getTimer()..setData(i)
this.addDisarmBoth()
Status.status[i].disarmBothTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmBoth()
Status.status[j].disarmBothTimer.release()
Status.status[j].disarmBothTimer = null
end)
/**
* Reduces the timed disarm duration by the given amount. If the duration is smaller
* then the given amount the timed disarm is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedDisarmBoth(real timeout)
int i = this.getIndex()
if Status.status[i].disarmBothTimer == null
return
if Status.status[i].disarmBothTimer.getRemaining() - timeout > 0.
Status.status[i].disarmBothTimer.start(Status.status[i].disarmBothTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmBoth()
Status.status[j].disarmBothTimer.release()
Status.status[j].disarmBothTimer = null
end)
else
this.removeDisarmBoth()
Status.status[i].disarmBothTimer.release()
Status.status[i].disarmBothTimer = null
/**
* Removes one disarm stack from the given unit. It is possible that the unit
* is still disarmed afterwards. Throws a warning if a non-existing disarmbuff is being
* removed.
*/
public function unit.removeDisarmBoth()
Status.status[this.getIndex()].disarmBothCounter--
if Status.status[this.getIndex()].disarmBothCounter < 0
printWarning("StatusHandler: tried removing a non-existing disarm both.")
Status.status[this.getIndex()].disarmBothCounter = 0
if not this.isDisarmedBoth()
this.removeAbility(DISARM_BOTH_BUFF_ID)
/**
* Removes the current timed disarm from the given unit. This only removes
* the timed disarm. Disarms applied with addDisarmBoth() might still exist. Throws
* a warning if there is no timed disarm active.
*/
public function unit.removeTimedDisarmBoth()
int i = this.getIndex()
if Status.status[i].disarmBothTimer != null
i.getUnit().removeDisarmBoth()
Status.status[i].disarmBothTimer.release()
Status.status[i].disarmBothTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed disarm both.")
/**
* Removes all disarm stacks and the timed disarm from the given unit. Afterwards
* the unit is not disarmed anymore.
*/
public function unit.clearDisarmBoth()
int i = this.getIndex()
if not this.isDisarmedBoth()
this.removeAbility(DISARM_BOTH_BUFF_ID)
Status.status[i].disarmBothCounter = 0
if Status.status[i].disarmBothTimer != null
i.getUnit().removeDisarmBoth()
Status.status[i].disarmBothTimer.release()
Status.status[i].disarmBothTimer = null
/**
* Returns a boolean indicating if the unit is melee-disarmed.
*
* returns true if the unit is melee-disarmed, false otherwise
*/
public function unit.isDisarmedMelee() returns boolean
return Status.status[this.getIndex()].disarmMeleeCounter > 0
/**
* Disarms the given melee unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all melee-disarms which have been applied before.
*/
public function unit.addDisarmMelee()
if not this.isDisarmedMelee()
DISARM_MELEE_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].disarmMeleeCounter++
/**
* Applies a timed melee-disarm to the given unit. If there is already a timed melee-disarm on this unit,
* the melee-disarm with the longer duration will be used.
*
* real timeout - the melee-disarm duration
*/
public function unit.addDisarmMeleeTimed(real timeout)
int i = this.getIndex()
if Status.status[i].disarmMeleeTimer != null and Status.status[i].disarmMeleeTimer.getRemaining() >= timeout
return
if Status.status[i].disarmMeleeTimer == null
Status.status[i].disarmMeleeTimer = getTimer()..setData(i)
this.addDisarmMelee()
Status.status[i].disarmMeleeTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmMelee()
Status.status[j].disarmMeleeTimer.release()
Status.status[j].disarmMeleeTimer = null
end)
/**
* Reduces the timed melee-disarm duration by the given amount. If the duration is smaller
* then the given amount the timed melee-disarm is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedDisarmMelee(real timeout)
int i = this.getIndex()
if Status.status[i].disarmMeleeTimer == null
return
if Status.status[i].disarmMeleeTimer.getRemaining() - timeout > 0.
Status.status[i].disarmMeleeTimer.start(Status.status[i].disarmMeleeTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmMelee()
Status.status[j].disarmMeleeTimer.release()
Status.status[j].disarmMeleeTimer = null
end)
else
this.removeDisarmMelee()
Status.status[i].disarmMeleeTimer.release()
Status.status[i].disarmMeleeTimer = null
/**
* Removes one melee-disarm stack from the given unit. It is possible that the unit
* is still melee-disarmed afterwards. Throws a warning if a non-existing melee-disarm is being
* removed.
*/
public function unit.removeDisarmMelee()
Status.status[this.getIndex()].disarmMeleeCounter--
if Status.status[this.getIndex()].disarmMeleeCounter < 0
printWarning("StatusHandler: tried removing a non-existing disarm melee.")
Status.status[this.getIndex()].disarmMeleeCounter = 0
if not this.isDisarmedMelee()
this.removeAbility(DISARM_MELEE_BUFF_ID)
/**
* Removes the current timed melee-disarm from the given unit. This only removes
* the timed melee-disarm. Melee-disarms applied with addDisarmMelee() might still exist. Throws
* a warning if there is no timed melee-disarm active.
*/
public function unit.removeTimedDisarmMelee()
int i = this.getIndex()
if Status.status[i].disarmMeleeTimer != null
i.getUnit().removeDisarmMelee()
Status.status[i].disarmMeleeTimer.release()
Status.status[i].disarmMeleeTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed disarm melee.")
/**
* Removes all melee-disarm stacks and the timed melee-disarm from the given unit. Afterwards
* the unit is not melee-disarmed anymore.
*/
public function unit.clearDisarmMelee()
int i = this.getIndex()
if not this.isDisarmedMelee()
this.removeAbility(DISARM_MELEE_BUFF_ID)
Status.status[i].disarmMeleeCounter = 0
if Status.status[i].disarmMeleeTimer != null
i.getUnit().removeDisarmMelee()
Status.status[i].disarmMeleeTimer.release()
Status.status[i].disarmMeleeTimer = null
/**
* Returns a boolean indicating if the unit is range-disarmed.
*
* returns true if the unit is range-disarmed, false otherwise
*/
public function unit.isDisarmedRanged() returns boolean
return Status.status[this.getIndex()].disarmRangedCounter > 0
/**
* Disarms the given ranged unit. The duration is infinite. Hence you have to
* remove it yourself. The function will count the amount of calls and will therefore
* last till you removed all range-disarms which have been applied before.
*/
public function unit.addDisarmRanged()
if not this.isDisarmedRanged()
DISARM_RANGED_DUMMY_CASTER.castOnTarget(this)
Status.status[this.getIndex()].disarmRangedCounter++
/**
* Applies a timed range-disarm to the given unit. If there is already a timed range-disarm on this unit,
* the range-disarm with the longer duration will be used.
*
* real timeout - the range-disarm duration
*/
public function unit.addDisarmRangedTimed(real timeout)
int i = this.getIndex()
if Status.status[i].disarmRangedTimer != null and Status.status[i].disarmRangedTimer.getRemaining() >= timeout
return
if Status.status[i].disarmRangedTimer == null
Status.status[i].disarmRangedTimer = getTimer()..setData(i)
this.addDisarmRanged()
Status.status[i].disarmRangedTimer.start(timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmRanged()
Status.status[j].disarmRangedTimer.release()
Status.status[j].disarmRangedTimer = null
end)
/**
* Reduces the timed range-disarm duration by the given amount. If the duration is smaller
* then the given amount the timed range-disarm is getting removed.
*
* real timeout - the amount the duration is getting reduced
*/
public function unit.reduceTimedDisarmRanged(real timeout)
int i = this.getIndex()
if Status.status[i].disarmRangedTimer == null
return
if Status.status[i].disarmRangedTimer.getRemaining() - timeout > 0.
Status.status[i].disarmRangedTimer.start(Status.status[i].disarmRangedTimer.getRemaining() - timeout, () -> begin
int j = GetExpiredTimer().getData()
j.getUnit().removeDisarmRanged()
Status.status[j].disarmRangedTimer.release()
Status.status[j].disarmRangedTimer = null
end)
else
this.removeDisarmRanged()
Status.status[i].disarmRangedTimer.release()
Status.status[i].disarmRangedTimer = null
/**
* Removes one range-disarm stack from the given unit. It is possible that the unit
* is still range-disarmed afterwards. Throws a warning if a non-existing range-disarm is being
* removed.
*/
public function unit.removeDisarmRanged()
Status.status[this.getIndex()].disarmRangedCounter--
if Status.status[this.getIndex()].disarmRangedCounter < 0
printWarning("StatusHandler: tried removing a non-existing disarm ranged.")
Status.status[this.getIndex()].disarmRangedCounter = 0
if not this.isDisarmedRanged()
this.removeAbility(DISARM_RANGED_BUFF_ID)
/**
* Removes the current timed range-disarm from the given unit. This only removes
* the timed range-disarm. Range-disarms applied with addDisarmRanged() might still exist. Throws
* a warning if there is no timed range-disarm active.
*/
public function unit.removeTimedDisarmRanged()
int i = this.getIndex()
if Status.status[i].disarmRangedTimer != null
i.getUnit().removeDisarmRanged()
Status.status[i].disarmRangedTimer.release()
Status.status[i].disarmRangedTimer = null
else
printWarning("StatusHandler: tried removing a non-existing timed disarm ranged.")
/**
* Removes all range-disarm stacks and the timed range-disarm from the given unit. Afterwards
* the unit is not range-disarmed anymore.
*/
public function unit.clearDisarmRanged()
int i = this.getIndex()
if not this.isDisarmedRanged()
this.removeAbility(DISARM_RANGED_BUFF_ID)
Status.status[i].disarmRangedCounter = 0
if Status.status[i].disarmRangedTimer != null
i.getUnit().removeDisarmRanged()
Status.status[i].disarmRangedTimer.release()
Status.status[i].disarmRangedTimer = null
/**
* Removes all status effects. This includes the stacks and the timed effects. Afterwards
* the unit has no status effect applied anymore.
*/
public function unit.clearAll()
this.clearStun()
this.clearSilence()
this.clearEnsnare()
this.clearDisarmBoth()
this.clearDisarmMelee()
this.clearDisarmRanged()
Wurst:
package StatusHandlerAbilityGen
import AbilityObjEditing
import BuffObjEditing
import ObjectIds
import StatusHandlerConfig
/**
* Sets some basic values for the abilitys used to apply the status effects.
*/
function AbilityDefinition.setBasicValues()
this..setLevels(1)
..setCooldown(1, 0)
..setCastingTime(1, 0)
..setManaCost(1, 0)
..setDurationNormal(1, 0)
..setDurationHero(1, 0)
..setCastRange(1, 99999.)
..setAnimationNames("")
..setMissileArt("")
..setMissileSpeed(0)
..setHeroAbility(true)
..setIconNormal("")
..setEditorSuffix("(Status System)")
..setTargetsAllowed(1, "invulnerable,vulnerable")
..setRequiredLevel(6)
.setRace("other")
/**
* Sets some basic values for the buffs used to apply the status effects.
*/
function BuffDefinition.setBasicValues()
this..setRace(1, "other")
..setTarget(1, "")
.setEditorSuffix(0, "(Status System)")
/**
* Generates the abilitys and buffs to apply the status effects.
*/
@compiletime function genAbilities()
new AbilityDefinitionFireBoltcreep(STUN_ABILITY_ID)
..setBasicValues()
..setDamage(1, 0)
..setName("Stun")
.setBuffs(1, idInteger2IdString(STUN_BUFF_ID))
new BuffDefinition(STUN_BUFF_ID, 'BPSE')
..setBasicValues()
..setTooltipNormal(1, STUN_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, STUN_TOOLTIP_EXTENDED)
.setIconNormal(1, STUN_ICON_PATH)
new AbilityDefinitionFirelordSoulBurn(SILENCE_ABILITY_ID)
..setBasicValues()
..setDamageAmount(1, 0)
..setDamagePeriod(1, 99999)
..setDamagePenalty(1, 0)
..setAttackSpeedReduction(1, 0)
..setMovementSpeedReduction(1, 0)
..setName("Silence")
.setBuffs(1, idInteger2IdString(SILENCE_BUFF_ID))
new BuffDefinition(SILENCE_BUFF_ID, 'BNso')
..setBasicValues()
..setTooltipNormal(1, SILENCE_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, SILENCE_TOOLTIP_EXTENDED)
.setIconNormal(1, SILENCE_ICON_PATH)
new AbilityDefinitionBrewmasterDrunkenHaze(DISARM_BOTH_ABILITY_ID)
..setBasicValues()
..setAttackSpeedModifier(1, 0)
..setMovementSpeedModifier(1, 0)
..setChanceToMiss(1, 0)
..setAttacksPrevented(1, "3")
..setName("Disarm (Both)")
.setBuffs(1, idInteger2IdString(DISARM_BOTH_BUFF_ID))
new BuffDefinition(DISARM_BOTH_BUFF_ID, 'BNdh')
..setBasicValues()
..setTooltipNormal(1, DISARM_BOTH_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, DISARM_BOTH_TOOLTIP_EXTENDED)
.setIconNormal(1, DISARM_BOTH_ICON_PATH)
new AbilityDefinitionBrewmasterDrunkenHaze(DISARM_MELEE_ABILITY_ID)
..setBasicValues()
..setAttackSpeedModifier(1, 0)
..setMovementSpeedModifier(1, 0)
..setChanceToMiss(1, 0)
..setAttacksPrevented(1, "1")
..setName("Disarm (Melee)")
.setBuffs(1, idInteger2IdString(DISARM_MELEE_BUFF_ID))
new BuffDefinition(DISARM_MELEE_BUFF_ID, 'BNdh')
..setBasicValues()
..setTooltipNormal(1, DISARM_MELEE_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, DISARM_MELEE_TOOLTIP_EXTENDED)
.setIconNormal(1, DISARM_BOTH_ICON_PATH)
new AbilityDefinitionBrewmasterDrunkenHaze(DISARM_RANGED_ABILITY_ID)
..setBasicValues()
..setAttackSpeedModifier(1, 0)
..setMovementSpeedModifier(1, 0)
..setChanceToMiss(1, 0)
..setAttacksPrevented(1, "2")
..setName("Disarm (Range)")
.setBuffs(1, idInteger2IdString(DISARM_RANGED_BUFF_ID))
new BuffDefinition(DISARM_RANGED_BUFF_ID, 'BNdh')
..setBasicValues()
..setTooltipNormal(1, DISARM_RANGED_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, DISARM_RANGED_TOOLTIP_EXTENDED)
.setIconNormal(1, DISARM_BOTH_ICON_PATH)
new AbilityDefinitionEnsnareCreep(ENSNARE_ABILITY_ID)
..setBasicValues()
..setAirUnitLowerDuration(1, -1)
..setAirUnitHeight(1, -1)
..setName("Ensnare")
.setBuffs(1, idInteger2IdString(ENSNARE1_BUFF_ID) + "," + idInteger2IdString(ENSNARE2_BUFF_ID))
new BuffDefinition(ENSNARE1_BUFF_ID, 'Beng')
..setBasicValues()
..setTooltipNormal(1, ENSNARE_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, ENSNARE_TOOLTIP_EXTENDED)
.setIconNormal(1, ENSNARE_ICON_PATH)
new BuffDefinition(ENSNARE2_BUFF_ID, 'Bena')
..setBasicValues()
..setTooltipNormal(1, ENSNARE_TOOLTIP_NORMAL)
..setTooltipNormalExtended(1, ENSNARE_TOOLTIP_EXTENDED)
.setIconNormal(1, ENSNARE_ICON_PATH)
To configure the StatusHandler, create a package named "StatusHandlerConfig" and specify the ability and buff ids. You also have to implement the two functions "function unit.getIndex() returns int" and "function int.getUnit() returns unit". Here is an example implementation in case you don't use a unit indexer yet.
Wurst:
package StatusHandlerConfig
import StatusHandler
public constant int STUN_ABILITY_ID = 'SAST'
public constant int STUN_BUFF_ID = 'SBST'
public constant string STUN_TOOLTIP_NORMAL = "Stunned"
public constant string STUN_TOOLTIP_EXTENDED = "This unit is stunned; it cannot move, attack or cast spells."
public constant string STUN_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNStun.blp"
public constant int SILENCE_ABILITY_ID = 'SASI'
public constant int SILENCE_BUFF_ID = 'SBSI'
public constant string SILENCE_TOOLTIP_NORMAL = "Silence"
public constant string SILENCE_TOOLTIP_EXTENDED = "This unit is silenced; it cannot cast spells."
public constant string SILENCE_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNSilence.blp"
public constant int DISARM_BOTH_ABILITY_ID = 'SADA'
public constant int DISARM_BOTH_BUFF_ID = 'SBDA'
public constant string DISARM_BOTH_TOOLTIP_NORMAL = "Disarmed"
public constant string DISARM_BOTH_TOOLTIP_EXTENDED = "This unit is disarmed; it cannot attack."
public constant string DISARM_BOTH_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp"
public constant int DISARM_MELEE_ABILITY_ID = 'SADM'
public constant int DISARM_MELEE_BUFF_ID = 'SBDM'
public constant string DISARM_MELEE_TOOLTIP_NORMAL = "Disarmed (Melee)"
public constant string DISARM_MELEE_TOOLTIP_EXTENDED = "This unit is disarmed; it cannot use melee attacks."
public constant string DISARM_MELEE_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp"
public constant int DISARM_RANGED_ABILITY_ID = 'SADR'
public constant int DISARM_RANGED_BUFF_ID = 'SBDR'
public constant string DISARM_RANGED_TOOLTIP_NORMAL = "Disarmed (Ranged)"
public constant string DISARM_RANGED_TOOLTIP_EXTENDED = "This unit is disarmed; it cannot use ranged attacks."
public constant string DISARM_RANGED_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp"
public constant int ENSNARE_ABILITY_ID = 'SAEN'
/** This is for ground units */
public constant int ENSNARE1_BUFF_ID = 'SBE1'
/** This is for air units */
public constant int ENSNARE2_BUFF_ID = 'SBE2'
public constant string ENSNARE_TOOLTIP_NORMAL = "Ensnared"
public constant string ENSNARE_TOOLTIP_EXTENDED = "This unit is ensnared, it cannot move or fly."
public constant string ENSNARE_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNWirtsOtherLeg.blp"
/**
* Implement this function to return a unique integer for every unit.
*/
public function unit.getIndex() returns int
return this.getUserData()
/**
* Implement this function to return the related unit to this integer.
*/
public function int.getUnit() returns unit
return (this castTo UnitWrapper).u
public class UnitWrapper
unit u
Status status
construct(player owner, int raw, real x, real y, real face)
u = CreateUnit(owner, raw, x, y, face)
u.setUserData(this castTo int)
status = new Status(u)
ondestroy
u.setUserData(0) // Invalid units should have index 0.
destroy status
StatusHandler
Changelog:
1.0 - Initial release
1.1 - Made abilities require level 6 to also apply status effects to magic immunte units
1.2 - Added the function removeTimedStatus(), reduceTimedStatus(real timeout), clearStatus(), clearAll() and changed the function order a bit
Credits:
- Pingufex, the bishop of antarctica and the leader of the worldwide Pingu Church
- muzzel
- WaterKnight
- Crigges
- PurgeandFire
Last edited: