Jesus4Lyf
Good Idea™
- Reaction score
- 397
Status
Version 1.3.0
Requirements:
- Jass NewGen
- AIDS
- DummyCaster
- Timer32
Documentation (code in map, can't fit in post):
JASS:
//
// ___ _____ _ _____ _ _ ___
// / __|_ _/_\_ _| | | / __|
// \__ \ | |/ _ \| | | |_| \__ \ By Jesus4Lyf.
// |___/ |_/_/ \_\_| \____/|___/ v 1.3.0
//
// What is Status?
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Status allows you to apply stuns, silences, disable attacks and much
// more. Status effects based off dummy casted spells are applied 0.0
// seconds after the "add" method is called. Status aims to commoditise
// unit effects in WC3.
//
// Restrictions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Disarming spell immune units is not possible. Some status effects will
// not apply to invulnerable units, namely those which are dummy casted.
//
// How to implement?
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Create a new trigger called Status, go to 'Edit -> Convert to
// Custom Text', and replace everything that's there with this script.
//
// Save the map, close it, reopen it, and then delete the "!" from the
// FAR left side of the next line (so "runtextmacro" will line up with this line):
//! runtextmacro Status__CreateAbilities()
//
// Go to the object editor, and select abilities. Go to Special > Heroes,
// and select Disarm (Both). Change Data - Attacks Prevented to Melee, Ranged.
// For Disarm (Melee), change Attacks Prevented to Melee. For Disarm (Range),
// change Attacks Prevented to Ranged. Object merger has a bug that does not
// allow setting this field automatically.
//
// Methods:
// ¯¯¯¯¯¯¯¯¯¯
// Statuses (short list):
// - Disable (addDisable, removeDisable, isDisabled)
// - Stun (addStun, removeStun, isStunned)
// - Silence (addSilence, removeSilence, isSilenced)
// - Doom (addDoom, removeDoom, isDoomed)
// - DisarmMelee (addDisarmMelee, removeDisarmMelee, isDisarmedMelee)
// - DisarmRange (addDisarmRange, removeDisarmRange, isDisarmedRange)
// - Disarm (addDisarm, removeDisarm, isDisarmed) // this is both Melee AND Ranged.
// - Immobolise (addImmobolise, removeImmobolise, isImmobolised)
// - Invisible (addInvisible, removeInvisible, isInvisible)
// - Ghost (addGhost, removeGhost, isGhost)
// - Invulnerable (addInvulnerable, removeInvulnerable, isInvulnerable)
// - Immunity (addImmunity, removeImmunity, isImmune)
// - Pause (addPause, removePause, isPaused)
// - Hide (addHide, removeHide, isHidden)
// - Unpath (addUnpath, removeUnpath, isUnpathed)
// - Hex (addHex, removeHex, isHexed)
// - Locust (addLocust, removeLocust, isLocust) // does not remove correctly for flying units, use with caution.
// - NeverMiss (addNeverMiss, removeNeverMiss, isNeverMiss)
// - AlwaysMiss (addAlwaysMiss, removeAlwaysMiss, isAlwaysMiss)
// - Untouchable (addUntouchable, removeUntouchable, isUntouchable) // 100% evasion
// - Banish (addBanish, removeBanish, isBanished)
// - Phase (addPhase, removePhase, isPhased) // clashes with windwalk, interrupts current order
// - ResistantSkin (addResistantSkin, removeResistantSkin, isResistantSkin)
// - ReflectPiercing (addReflectPiercing, removeReflectPiercing, isReflectPiercing)
//
// Bonuses (short list):
// - ArmorBonus (modArmorBonus, getArmorBonus)
// - DamageBonus (modDamageBonus, getDamageBonus)
// - StrBonus (modStrBonus, getStrBonus)
// - AgiBonus (modAgiBonus, getAgiBonus)
// - IntBonus (modIntBonus, getIntBonus)
// - AttackSpeedBonus (modAttackSpeedBonus, getAttackSpeedBonus)
// - Health (modHealthBonus, getHealthBonus)
// - Mana (modManaBonus, getManaBonus)'
// - HealthRegen (modHealthRegenBonus, getHealthRegenBonus)
// - HealthRegenPercent (modHealthRegenPercentBonus, getHealthRegenPercentBonus) // percent of max
// - ManaRegen (modManaRegenBonus, getManaRegenBonus)
// - ManaRegenPercent (modManaRegenPercentBonus, getManaRegenPercentBonus) // percent of max
// - MoveSpeed (modMoveSpeedBonus, getMoveSpeedBonus)
// - MoveSpeedPercent (modMoveSpeedPercentBonus, getMoveSpeedPercentBonus) // percent of current move speed (after normal bonuses).
//
// How to Use:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// Statuses:
// Status[unit].add?()
// - Adds the status effect to the unit.
// - This does not add any animation.
// Status[unit].remove?()
// - Removes the status effect added with .add?().
// - Will not actually remove it until all added instances are removed.
// Status[unit].is?() --> boolean
// - Checks to see whether or not a unit has a status effect applied.
//
// Bonuses:
// Status[unit].mod?(amount)
// - Modifies the bonus by the amount given.
// - Use a negative value to reverse a bonus.
// - Supports giving negative of a bonus.
// Status[unit].get?()
// - Gets the curret total amount for a given bonus.
//
// Thanks:
// ¯¯¯¯¯¯¯¯¯
// - Weep: for suggesting that making the ability an ultimate hero ability
// would allow it to stun magic immune units, and suggesting a simpler
// target allowance for the ability.
//
// - 13lade619: for noticing that the PreloadModule was not actually
// implemented, causing first use lag.
//
library Status uses AIDS, DummyCaster, T32
globals
private constant real PERIOD=0.1 // for regen effects.
private constant player DUMMY_CASTER_OWNER=Player(PLAYER_NEUTRAL_PASSIVE)
private constant boolean PERMENANTLY_REVEAL=true // reveal all units always, or only during dummy spells
// To change these, change them also in the externalblock before executing it.
private constant integer ABIL_STUN=039;A500039;
private constant integer ABIL_SILENCE=039;A501039;
private constant integer ABIL_DISARM_BOTH=039;A502039;
private constant integer ABIL_DISARM_MELEE=039;A503039;
private constant integer ABIL_DISARM_RANGE=039;A504039;
private constant integer ABIL_IMMOBOLISE=039;A505039;
private constant integer ABIL_INVISIBLE=039;A507039;
private constant integer ABIL_GHOST=039;A508039;
private constant integer ABIL_DOOM=039;A509039;
private constant integer ABIL_IMMUNITY=039;A50B039;
private constant integer ABIL_HEX=039;A50C039;
private constant integer ABIL_UNLOCUST=039;A50D039;
private constant integer ABIL_NEVER_MISS=039;A50F039;
private constant integer ABIL_ALWAYS_MISS=039;A50H039;
private constant integer ABIL_UNTOUCHABLE=039;A50J039;
private constant integer ABIL_BANISH=039;A50K039;
private constant integer ABIL_PHASE=039;A50L039;
//private constant integer ABIL_DOUBLE_ATTACK='A50O'
private constant integer ABIL_RESISTANT_SKIN=039;A50Q039;
private constant integer ABIL_REFLECT_PIERCING=039;A50S039;
private constant integer ABIL_DISABLE=039;A50T039;
private constant integer ABIL_ARMOR=039;A5A@039;
private constant integer ABIL_DAMAGE=039;A5B@039;
private constant integer ABIL_STR=039;A5C@039;
private constant integer ABIL_AGI=039;A5D@039;
private constant integer ABIL_INT=039;A5E@039;
private constant integer ABIL_ATTACK_SPEED=039;A5F@039;
private constant integer ABIL_HEALTH=039;A5G@039;
private constant integer ABIL_MANA=039;A5H@039;
private constant integer LEVELS_ARMOR=10
private constant integer LEVELS_DAMAGE=15
private constant integer LEVELS_STR=10
private constant integer LEVELS_AGI=10
private constant integer LEVELS_INT=10
private constant integer LEVELS_ATTACK_SPEED=9
private constant integer LEVELS_HEALTH=20
private constant integer LEVELS_MANA=20
// To change these, change them also in the externalblock before executing it.
private constant integer BUFF_STUN=039;B500039;
private constant integer BUFF_SILENCE=039;B501039;
private constant integer BUFF_DOOM=039;B509039;
private constant integer BUFF_DISARM_MELEE=039;B503039;
private constant integer BUFF_DISARM_RANGE=039;B504039;
private constant integer BUFF_DISARM_BOTH=039;B502039;
private constant integer BUFF_IMMOBOLISE_GROUND=039;B505039;
private constant integer BUFF_IMMOBOLISE_AIR=039;B506039;
private constant integer BUFF_HEX=039;B50C039;
private constant integer BUFF_BANISH=039;B50K039;
private constant integer BUFF_PHASE=039;B50L039;
private constant integer BUFF_DISABLE=039;B50T039;
private constant integer OID_STOP=851972 //stop
private constant integer OID_STUN=852231 //firebolt
private constant integer OID_SILENCE=852668 //soulburn
private constant integer OID_DISARM=852585 //drunkenhaze
private constant integer OID_IMMOBOLISE=852106 //ensnare
private constant integer OID_DOOM=852583 //doom
private constant integer OID_HEX=852502 //hex
private constant integer OID_UNLOCUST=852155 //ravenform
private constant integer OID_BANISH=852486 //banish
private constant integer OID_PHASE=852129 //windwalk
private constant integer OID_DISABLE=852252 //creepthunderbolt (hurlboulder)
private unit CASTER_DISARM_BOTH=null
private unit CASTER_DISARM_MELEE=null
private unit CASTER_DISARM_RANGE=null
endglobals
native UnitAlive takes unit id returns boolean
private module PreloadModule
private static method onInit takes nothing returns nothing
local unit u=CreateUnit(DUMMY_CASTER_OWNER,DUMMY_TYPE,0,0,0)
local integer abil
//! textmacro Status__PreloadBonus takes BONUS
set abil=ABIL_$BONUS$+LEVELS_$BONUS$
loop
call UnitAddAbility(u,abil)
exitwhen abil==ABIL_$BONUS$
set abil=abil-1
endloop
//! endtextmacro
call UnitAddAbility(u,ABIL_INVISIBLE)
call UnitAddAbility(u,ABIL_GHOST)
call UnitAddAbility(u,ABIL_IMMUNITY)
call UnitAddAbility(u,ABIL_UNLOCUST)
call UnitAddAbility(u,ABIL_NEVER_MISS)
call UnitAddAbility(u,ABIL_ALWAYS_MISS)
call UnitAddAbility(u,ABIL_UNTOUCHABLE)
call UnitAddAbility(u,ABIL_PHASE)
//call UnitAddAbility(u,ABIL_DOUBLE_ATTACK)
call UnitAddAbility(u,ABIL_RESISTANT_SKIN)
call UnitAddAbility(u,ABIL_REFLECT_PIERCING)
//! runtextmacro Status__PreloadBonus("ARMOR")
//! runtextmacro Status__PreloadBonus("DAMAGE")
//! runtextmacro Status__PreloadBonus("STR")
//! runtextmacro Status__PreloadBonus("AGI")
//! runtextmacro Status__PreloadBonus("INT")
//! runtextmacro Status__PreloadBonus("ATTACK_SPEED")
//! runtextmacro Status__PreloadBonus("HEALTH")
//! runtextmacro Status__PreloadBonus("MANA")
call KillUnit(u)
call RemoveUnit(u)
set u=null
endmethod
endmodule
private module StaticPeriodic
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(),PERIOD,true,function thistype.periodicLink)
endmethod
endmodule
private module StatusInit
private static method onInit takes nothing returns nothing
local integer i
//! textmacro Status__CreateAbilities
// For reflecting piercing.
//! externalblock extension=lua ConstantMerger $FILENAME$
//! i setvalue("Misc","DefendDeflection","1")
//! endexternalblock
// Start externalblock
//! externalblock extension=lua ObjectMerger $FILENAME$
////////////////////
// Status Effects //
////////////////////
// Stun (X500, firebolt)
//! i setobjecttype("buffs")
//! i createobject("BPSE","B500")
//! i makechange(current,"frac","other")
//! i makechange(current,"ftip","Stunned")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"fube","This unit is stunned; it cannot move, attack or cast spells.")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ACfb","A500")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Stun")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"amat","")
//! i makechange(current,"amsp",0)
//! i makechange(current,"Htb1",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"invulnerable,vulnerable")
//! i makechange(current,"abuf",1,"B500")
//! i makechange(current,"aher",1)
//! i makechange(current,"arlv",6)
// Silence (X501, soulburn)
//! i setobjecttype("buffs")
//! i createobject("BNso","B501")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Silence")
//! i makechange(current,"fube","This unit is Silenced; it cannot cast spells.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNSilence.blp")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ANso","A501")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Silence")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"Nso1",1,0)
//! i makechange(current,"Nso3",1,0)
//! i makechange(current,"Nso2",1,99999)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B501")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"arlv",6)
//! i makechange(current,"alev",1)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"invulnerable,vulnerable")
// Disarm (Both) (X502, drunkenhaze)
//! i setobjecttype("buffs")
//! i createobject("BNdh", "B502")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Disarmed")
//! i makechange(current,"fube","This unit is Disarmed; it cannot attack.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ANdh","A502")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Disarm (Both)")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"amat","")
//! i makechange(current,"amac",0)
//! i makechange(current,"amsp",0)
//! i makechange(current,"arlv",6)
//! i makechange(current,"alev",1)
//! i makechange(current,"Nsi2",1,0)
//! i makechange(current,"Nsi3",1,0)
//! i makechange(current,"aare",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B502")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Disarm (Melee) (X503, drunkenhaze)
//! i setobjecttype("buffs")
//! i createobject("BNdh", "B503")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Disarmed (Melee)")
//! i makechange(current,"fube","This unit is Disarmed; it cannot use melee attacks.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ANdh","A503")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Disarm (Melee)")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"amat","")
//! i makechange(current,"amac",0)
//! i makechange(current,"amsp",0)
//! i makechange(current,"arlv",6)
//! i makechange(current,"alev",1)
//! i makechange(current,"Nsi2",1,0)
//! i makechange(current,"Nsi3",1,0)
//! i makechange(current,"aare",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B503")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Disarm (Range) (X504, drunkenhaze)
//! i setobjecttype("buffs")
//! i createobject("BNdh", "B504")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Disarmed (Ranged)")
//! i makechange(current,"fube","This unit is Disarmed; it cannot use ranged attacks.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ANdh","A504")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Disarm (Range)")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"amat","")
//! i makechange(current,"amac",0)
//! i makechange(current,"amsp",0)
//! i makechange(current,"arlv",6)
//! i makechange(current,"alev",1)
//! i makechange(current,"Nsi2",1,0)
//! i makechange(current,"Nsi3",1,0)
//! i makechange(current,"aare",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B504")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Entangle (X505 - X506, ensnare)
//! i setobjecttype("buffs")
//! i createobject("Beng","B505")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Immobilised")
//! i makechange(current,"fube","This unit is immobilised; it cannot move or fly.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNWirtsOtherLeg.blp")
//! i makechange(current,"ftat","")
//! i createobject("Bena","B506")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftip","Immobilised")
//! i makechange(current,"fube","This unit is immobilised; it cannot move or fly.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNWirtsOtherLeg.blp")
//! i makechange(current,"ftat", "")
//! i setobjecttype("abilities")
//! i createobject("ACen","A505")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Immobilise")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"amat","")
//! i makechange(current,"amsp",0)
//! i makechange(current,"aher",1)
//! i makechange(current,"arlv",6)
//! i makechange(current,"alev",1)
//! i makechange(current,"areq","")
//! i makechange(current,"Ens1",1,-1)
//! i makechange(current,"Ens2",1,-1)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B505,B506")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Invisibility (X507)
//! i setobjecttype("abilities")
//! i createobject("Apiv","A507")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Invisibility")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"ahdu",1,0.5)
//! i makechange(current,"adur",1,0.5)
// Ghost (X508)
//! i setobjecttype("abilities")
//! i createobject("Agho","A508")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Ghost")
//! i makechange(current,"ansf","(Status System)")
// Doom (X509, doom)
//! i setobjecttype("buffs")
//! i createobject("BNdo","B509")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftat","")
//! i makechange(current,"fube","This unit has been stricken with Doom; it cannot cast spells.")
//! i setobjecttype("abilities")
//! i createobject("ANdo","A509")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Doom")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"Ndo1",1,0)
//! i makechange(current,"Ndo2",1,0)
//! i makechange(current,"Ndo3",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B509")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Spell Immunity (X50A - X50B)
//! i setobjecttype("abilities")
//! i createobject("Amim","A50A")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Spell Immunity")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("Aspb","A50B")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Spell Immunity")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50A")
// Hex (X50C, hex)
//! i setobjecttype("buffs")
//! i createobject("BOhx","B50C")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"feat","")
//! i setobjecttype("abilities")
//! i createobject("AOhx","A50C")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Hex")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"asat","")
//! i makechange(current,"alev",1)
//! i makechange(current,"arlv",6)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B50C")
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
// Unlocust (X50D, crowform)
//! i setobjecttype("abilities")
//! i createobject("Amrf","A50D")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Unlocust")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"Eme3",1,-1)
//! i makechange(current,"Eme4",1,-1)
//! i makechange(current,"acas",1,0)
//! i makechange(current,"adur",1,0)
// Never Miss (X50E - X50F)
//! i setobjecttype("abilities")
//! i createobject("ACct","A50E")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Never Miss")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"Ocr1",1,100)
//! i makechange(current,"Ocr2",1,0)
//! i makechange(current,"Ocr5",1,1)
//! i makechange(current,"atar",1,"notself")
//! i createobject("Aspb","A50F")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Never Miss")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50E")
// Always Miss (X50G - X50H)
//! i setobjecttype("abilities")
//! i createobject("ACbh","A50G")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Always Miss")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"Hbh1",1,0)
//! i makechange(current,"Hbh4",1,100)
//! i makechange(current,"atar",1,"notself")
//! i createobject("Aspb","A50H")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Always Miss")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50G")
// Untouchable (X50I - X50J)
//! i setobjecttype("abilities")
//! i createobject("ACes","A50I")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Untouchable")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("Aspb","A50J")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Untouchable")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50I")
// Banish (X50K, banish)
//! i setobjecttype("buffs")
//! i createobject("BNdo","B50K")
//! i makechange(current,"frac","other")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"ftat","")
//! i makechange(current,"fefl","")
//! i setobjecttype("abilities")
//! i createobject("AHbn","A50K")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Banish")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"aefs","")
//! i makechange(current,"alev",1)
//! i makechange(current,"arlv",6)
//! i makechange(current,"Hbn1",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"abuf",1,"B50K")
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"notself")
// Phase (X50L, windwalk)
//! i setobjecttype("buffs")
//! i createobject("BOwk","B50L")
//! i makechange(current,"frac","other")
//! i makechange(current,"ftip","Phase")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"fube","This unit is Phasing; it can walk through other units.")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNMirrorImage.blp")
//! i setobjecttype("abilities")
//! i createobject("ANwk","A50L")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Phase")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aefs","")
//! i makechange(current,"Owk3",1,0)
//! i makechange(current,"Owk4",1,0)
//! i makechange(current,"Owk2",1,0)
//! i makechange(current,"Owk1",1,-1)
//! i makechange(current,"abuf",1,"B50L")
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"aher",0)
/*
// Double Attack (X50M - X50O)
//! i setobjecttype("abilities")
//! i createobject("ACsa","A50M")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Double Attack")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"amat","")
//! i makechange(current,"Hfa1",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"invulnerable,vulnerable")
//! i createobject("AIll","A50N")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Double Attack")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"amat","")
//! i makechange(current,"asat","")
//! i makechange(current,"atat","")
//! i makechange(current,"Iob2",1,100)
//! i makechange(current,"Iob3",1,100)
//! i makechange(current,"Iob4",1,100)
//! i makechange(current,"Idam",1,0)
//! i makechange(current,"Iobu",1,"A50M")
//! i makechange(current,"atar",1,"invulnerable,vulnerable")
//! i createobject("Aspb","A50O")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Double Attack")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50N")
*/
// Resistant Skin (X50P - X50Q)
//! i setobjecttype("abilities")
//! i createobject("ACrk","A50P")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Resistant Skin")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("Aspb","A50Q")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Resistant Skin")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50P")
// Reflect Piercing (X50R - X50S)
//! i setobjecttype("abilities")
//! i createobject("Aegr","A50R")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Reflect Piercing")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"Def6",1,100)
//! i makechange(current,"Def1",1,1)
//! i makechange(current,"Def7",1,0)
//! i makechange(current,"Def5",1,0)
//! i createobject("Aspb","A50S")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Reflect Piercing")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"spb5",1,"")
//! i makechange(current,"spb4",1,1)
//! i makechange(current,"spb3",1,1)
//! i makechange(current,"spb1",1,"A50R")
// Disable (X50T, creepthunderbolt (hurlboulder))
//! i setobjecttype("buffs")
//! i createobject("BPSE","B50T")
//! i makechange(current,"frac","other")
//! i makechange(current,"ftip","Disabled")
//! i makechange(current,"fube","This unit is Disabled; it cannot do anything.")
//! i makechange(current,"fnsf","(Status System)")
//! i makechange(current,"fart","ReplaceableTextures\\CommandButtons\\BTNReplay-Pause.blp")
//! i makechange(current,"ftat","")
//! i setobjecttype("abilities")
//! i createobject("ACtb","A50T")
//! i makechange(current,"aart","")
//! i makechange(current,"arac","other")
//! i makechange(current,"anam","Disable")
//! i makechange(current,"ansf","(Status System)")
//! i makechange(current,"aani","")
//! i makechange(current,"amat","")
//! i makechange(current,"amsp",0)
//! i makechange(current,"Ctb1",1,0)
//! i makechange(current,"aran",1,99999)
//! i makechange(current,"acdn",1,0)
//! i makechange(current,"ahdu",1,0)
//! i makechange(current,"adur",1,0)
//! i makechange(current,"amcs",1,0)
//! i makechange(current,"atar",1,"invulnerable,vulnerable")
//! i makechange(current,"abuf",1,"B50T")
//! i makechange(current,"aher",1)
//! i makechange(current,"arlv",6)
////////////////////
// Status Bonuses //
////////////////////
//! i setobjecttype("abilities")
//! i myChar={}
//! i myChar[1]="A"
//! i myChar[2]="B"
//! i myChar[3]="C"
//! i myChar[4]="D"
//! i myChar[5]="E"
//! i myChar[6]="F"
//! i myChar[7]="G"
//! i myChar[8]="H"
//! i myChar[9]="I"
//! i myChar[10]="J"
//! i myChar[11]="K"
//! i myChar[12]="L"
//! i myChar[13]="M"
//! i myChar[14]="N"
//! i myChar[15]="O"
//! i myChar[16]="P"
//! i myChar[17]="Q"
//! i myChar[18]="R"
//! i myChar[19]="S"
//! i myChar[20]="T"
//! i myChar[21]="U"
//! i myChar[22]="V"
//! i myChar[23]="W"
//! i myChar[24]="X"
//! i myChar[25]="Y"
//! i myChar[26]="Z"
//! i myBin={}
//! i myBin[1]=1
//! i myBin[2]=2
//! i myBin[3]=4
//! i myBin[4]=8
//! i myBin[5]=16
//! i myBin[6]=32
//! i myBin[7]=64
//! i myBin[8]=128
//! i myBin[9]=256
//! i myBin[10]=512
//! i myBin[11]=1024
//! i myBin[12]=2048
//! i myBin[13]=4096
//! i myBin[14]=8192
//! i myBin[15]=16384
//! i myBin[16]=32768
//! i myBin[17]=65536
//! i myBin[18]=131072
//! i myBin[19]=262144
//! i myBin[20]=524288
//! i myBin[21]=1048576
//! i myBin[22]=2097152
//! i myBin[23]=4194304
//! i myBin[24]=8388608
//! i myBin[25]=16777216
//! i myBin[26]=33554432
// Armor (10 = 1023 max)
//! i for i=1,10 do
//! i createobject("AId1","A5A"..myChar<i>)
//! i makechange(current,"Idef",1,myBin<i>)
//! i makechange(current,"anam","Armor Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AId1","A5A@")
//! i makechange(current,"Idef",1,-myBin[11])
//! i makechange(current,"anam","Armor Bonus")
//! i makechange(current,"ansf","(Status System)")
// Damage (15 = 32767 max)
//! i for i=1,15 do
//! i createobject("AItg","A5B"..myChar<i>)
//! i makechange(current,"Iatt",1,myBin<i>)
//! i makechange(current,"anam","Damage Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AItg","A5B@")
//! i makechange(current,"Iatt",1,-myBin[16])
//! i makechange(current,"anam","Damage Bonus")
//! i makechange(current,"ansf","(Status System)")
// Str/Agi/Int (10 = 1023 max)
//! i for i=1,10 do
//! i createobject("AIs1","A5C"..myChar<i>)
//! i makechange(current,"Istr",1,myBin<i>)
//! i makechange(current,"anam","Strength Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("AIa1","A5D"..myChar<i>)
//! i makechange(current,"Iagi",1,myBin<i>)
//! i makechange(current,"anam","Agility Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("AIi1","A5E"..myChar<i>)
//! i makechange(current,"Iint",1,myBin<i>)
//! i makechange(current,"anam","Intelligence Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AIs1","A5C@")
//! i makechange(current,"Istr",1,-myBin[11])
//! i makechange(current,"anam","Strength Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("AIa1","A5D@")
//! i makechange(current,"Iagi",1,-myBin[11])
//! i makechange(current,"anam","Agility Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i createobject("AIi1","A5E@")
//! i makechange(current,"Iint",1,-myBin[11])
//! i makechange(current,"anam","Intelligence Bonus")
//! i makechange(current,"ansf","(Status System)")
// Attack Speed (9 = 511% max)
//! i for i=1,9 do
//! i createobject("AIsx","A5F"..myChar<i>)
//! i makechange(current,"Isx1",1,myBin<i>*0.01)
//! i makechange(current,"anam","Attack Speed Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AIsx","A5F@")
//! i makechange(current,"Isx1",1,-myBin[10]*0.01)
//! i makechange(current,"anam","Attack Speed Bonus")
//! i makechange(current,"ansf","(Status System)")
// Max HP (20 = 1048575 max)
//! i for i=1,20 do
//! i createobject("AIl2","A5G"..myChar<i>)
//! i makechange(current,"Ilif",1,myBin<i>)
//! i makechange(current,"anam","Health Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AIl2","A5G@")
//! i makechange(current,"Ilif",1,-myBin[21])
//! i makechange(current,"anam","Health Bonus")
//! i makechange(current,"ansf","(Status System)")
// Max Mana (20 = 1048575 max)
//! i for i=1,20 do
//! i createobject("AImz","A5H"..myChar<i>)
//! i makechange(current,"Iman",1,myBin<i>)
//! i makechange(current,"anam","Mana Bonus")
//! i makechange(current,"ansf","(Status System)")
//! i end
//! i createobject("AImz","A5H@")
//! i makechange(current,"Iman",1,-myBin[21])
//! i makechange(current,"anam","Mana Bonus")
//! i makechange(current,"ansf","(Status System)")
// End externalblock
//! endexternalblock
//! endtextmacro
set thistype.dummyCaster=CreateUnit(DUMMY_CASTER_OWNER,DUMMY_TYPE,0,0,0)
set thistype.dummyCaster2=CreateUnit(DUMMY_CASTER_OWNER,DUMMY_TYPE,0,0,0)
set thistype.dummyCaster3=CreateUnit(DUMMY_CASTER_OWNER,DUMMY_TYPE,0,0,0)
call UnitAddAbility(thistype.dummyCaster,ABIL_STUN)
call UnitAddAbility(thistype.dummyCaster,ABIL_DISABLE)
call UnitAddAbility(thistype.dummyCaster,ABIL_SILENCE)
set CASTER_DISARM_BOTH=thistype.dummyCaster
set CASTER_DISARM_MELEE=thistype.dummyCaster2
set CASTER_DISARM_RANGE=thistype.dummyCaster3
call UnitAddAbility(CASTER_DISARM_BOTH,ABIL_DISARM_BOTH)
call UnitAddAbility(CASTER_DISARM_MELEE,ABIL_DISARM_MELEE)
call UnitAddAbility(CASTER_DISARM_RANGE,ABIL_DISARM_RANGE)
call UnitAddAbility(thistype.dummyCaster,ABIL_IMMOBOLISE)
call UnitAddAbility(thistype.dummyCaster,ABIL_DOOM)
call UnitAddAbility(thistype.dummyCaster,ABIL_HEX)
call UnitAddAbility(thistype.dummyCaster,ABIL_BANISH)
set i=bj_MAX_PLAYERS
loop
set i=i-1
call SetPlayerAbilityAvailable(Player(i),ABIL_IMMUNITY,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_NEVER_MISS,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_ALWAYS_MISS,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_UNTOUCHABLE,false)
//call SetPlayerAbilityAvailable(Player(i),ABIL_DOUBLE_ATTACK,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_RESISTANT_SKIN,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_REFLECT_PIERCING,false)
exitwhen i==0
endloop
endmethod
endmodule
private module TwoPowArray
readonly static integer array twoPow
private static method onInit takes nothing returns nothing
local integer i=0
local integer val=1
loop
set thistype.twoPow<i>=val // thistype.twoPow[0]=1
exitwhen i==30
set i=i+1
set val=val*2
endloop
endmethod
endmodule
//to be continued in next post...</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Demonstration:
JASS:
// Stuns every unit on the map for 5 seconds.
scope SimpleStun initializer Demo
private function Timeout takes unit target, real time returns nothing
// You should use your favourite timer system instead of TriggerSleepAction.
call TriggerSleepAction(time)
call Status[target].removeStun()
endfunction
function Stun takes unit target, real time returns nothing
call Status[target].addStun()
call Timeout.execute(target,time)
endfunction
private function Action takes nothing returns nothing
call Stun(GetEnumUnit(),5.0)
endfunction
private function DoThings takes nothing returns nothing
call TriggerSleepAction(1.0)
// This is because deep down I love GUI and all the trouble it causes.
call BJDebugMsg("Stunning everything for 5 seconds.")
call ForGroupBJ(GetUnitsInRectAll(GetPlayableMapRect()),function Action)
call TriggerSleepAction(5.0)
call BJDebugMsg("5 seconds has passed.")
endfunction
private function Demo takes nothing returns nothing
call DoThings.execute()
endfunction
endscope
Usually with stuns you want to add effects when they begin and remove then when they end, or use them in unit sliding effects which may end abruptly if it hits a wall or something. For this reason (and the freedom of choice for timer system) I have not made a timed stun system, merely a stun system. I think this is the API that mappers truly need, rather than someone that tries to do too much for you.
PS. I have been developing this since releasing DummyCaster. But today I realised the interface was wrong, and reduced it to 40 lines of code.
PPS. Today I realised that I should overhaul this, and make it epic.
PPPS. This is now 1958 lines long and cannot fit in a post.
Updates:
- Version 1.3.0: Fixed typo "alwaysNeverMiss" --> "removeAlwaysMiss".
- Version 1.2.9: Implemented the written (but unimplemented) PreloadModule (thanks 13lade619).
- Version 1.2.8: Gave Disable a different buff to Stun.
- Version 1.2.7: Added ReflectPiercing status.
- Version 1.2.6: Added MoveSpeed and MoveSpeedPercent bonuses, and Resistant Skin as a status. Also added HealthRegen, HealthRegenPercent, ManaRegen and ManaRegenPercent bonuses. Changed all "isXStatus" methods to simply read the level for the unit instead of check for the buff.
- Version 1.2.5: Fixed a bug where setting health or strength to negative would instantly kill the subject.
- Version 1.2.4: Added Phase status and added life and mana bonuses. Also preloaded all abilities.
- Version 1.2.3: Added many new statuses or released them publicly, as well as bonuses. All of them now implement negatively as well, except for Disable (which should not).
- Version 1.2.0: Now supports Silence, Disarm (Melee), Disarm (Range), Disarm (Both Melee and Range) and Immobolise, as well as Stun.
Stun:
- Version 1.1.3: No longer overwrites "Stone Form".
- Version 1.1.2: Now hits mechanical units.
- Version 1.1.1: Modified to issue the order by ID. I had the ID there, but I still used the "firebolt" string for some reason.
- Version 1.1.0: Stun can now stun magic immune targets.
- Version 1.0.1: Removed the stun level check before issuing the stun order.
- Version 1.0.0: Release.