System Status

Discussion in 'Systems and Snippets' started by Jesus4Lyf, Sep 2, 2009.

  1. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    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='A500'
            private constant integer ABIL_SILENCE='A501'
            private constant integer ABIL_DISARM_BOTH='A502'
            private constant integer ABIL_DISARM_MELEE='A503'
            private constant integer ABIL_DISARM_RANGE='A504'
            private constant integer ABIL_IMMOBOLISE='A505'
            private constant integer ABIL_INVISIBLE='A507'
            private constant integer ABIL_GHOST='A508'
            private constant integer ABIL_DOOM='A509'
            private constant integer ABIL_IMMUNITY='A50B'
            private constant integer ABIL_HEX='A50C'
            private constant integer ABIL_UNLOCUST='A50D'
            private constant integer ABIL_NEVER_MISS='A50F'
            private constant integer ABIL_ALWAYS_MISS='A50H'
            private constant integer ABIL_UNTOUCHABLE='A50J'
            private constant integer ABIL_BANISH='A50K'
            private constant integer ABIL_PHASE='A50L'
            //private constant integer ABIL_DOUBLE_ATTACK='A50O'
            private constant integer ABIL_RESISTANT_SKIN='A50Q'
            private constant integer ABIL_REFLECT_PIERCING='A50S'
            private constant integer ABIL_DISABLE='A50T'
            
            private constant integer ABIL_ARMOR='A5A@'
            private constant integer ABIL_DAMAGE='A5B@'
            private constant integer ABIL_STR='A5C@'
            private constant integer ABIL_AGI='A5D@'
            private constant integer ABIL_INT='A5E@'
            private constant integer ABIL_ATTACK_SPEED='A5F@'
            private constant integer ABIL_HEALTH='A5G@'
            private constant integer ABIL_MANA='A5H@'
            
            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='B500'
            private constant integer BUFF_SILENCE='B501'
            private constant integer BUFF_DOOM='B509'
            private constant integer BUFF_DISARM_MELEE='B503'
            private constant integer BUFF_DISARM_RANGE='B504'
            private constant integer BUFF_DISARM_BOTH='B502'
            private constant integer BUFF_IMMOBOLISE_GROUND='B505'
            private constant integer BUFF_IMMOBOLISE_AIR='B506'
            private constant integer BUFF_HEX='B50C'
            private constant integer BUFF_BANISH='B50K'
            private constant integer BUFF_PHASE='B50L'
            private constant integer BUFF_DISABLE='B50T'
            
            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...


    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
    This is very efficient, provides only the basic functions, supports multi-instancing stuns on one unit at once (it will become unstunned when it has no more stuns remaining on it) and doesn't force you into using any particular timer system.

    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. :p

    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.
     

    Attached Files:

    • Like Like x 2
  2. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    JASS:
    //continued..
        struct Status extends array
            private method AIDS_onCreate takes nothing returns nothing
                static if PERMENANTLY_REVEAL then
                    call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                endif
                
                set this.disableLevel=0
                set this.stunLevel=0
                set this.silenceLevel=0
                set this.doomLevel=0
                set this.disarmMeleeLevel=0
                set this.disarmRangeLevel=0
                set this.immoboliseLevel=0
                set this.invisibleLevel=0
                set this.ghostLevel=0
                set this.invulnerableLevel=0
                set this.immunityLevel=0
                set this.pauseLevel=0
                set this.hideLevel=0
                set this.unpathLevel=0
                set this.hexLevel=0
                set this.locustLevel=0
                set this.neverMissLevel=0
                set this.alwaysMissLevel=0
                set this.untouchableLevel=0
                set this.banishLevel=0
                set this.phaseLevel=0
                set this.resistantSkinLevel=0
                set this.reflectPiercingLevel=0
                
                set this.armorBonus=0
                set this.damageBonus=0
                set this.strBonus=0
                set this.agiBonus=0
                set this.intBonus=0
                set this.attackSpeedBonus=0
                set this.healthBonus=0
                set this.manaBonus=0
                set this.healthRegenBonus=0
                set this.manaRegenBonus=0
                set this.healthRegenPercentBonus=0
                set this.manaRegenPercentBonus=0
                
                set this.moveSpeedBonus=0.0
                set this.moveSpeedPercentBonus=0.0
                call this.stopPeriodic()
            endmethod
            //! runtextmacro AIDS()
            private static unit dummyCaster=null
            private static unit dummyCaster2=null
            private static unit dummyCaster3=null
            
            implement StatusInit
            implement TwoPowArray
            implement PreloadModule
            
            ////////////////////
            // Status Effects //
            ////////////////////
            
            // Stun
            private integer stunLevel
            method addStun takes nothing returns nothing
                set this.stunLevel=this.stunLevel+1
                if this.stunLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_STUN,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeStun takes nothing returns nothing
                set this.stunLevel=this.stunLevel-1
                if this.stunLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_STUN)
                endif
            endmethod
            method isStunned takes nothing returns boolean
                return this.stunLevel>0
            endmethod
            
            // Disable
            private integer disableLevel
            method addDisable takes nothing returns nothing
                set this.disableLevel=this.disableLevel+1
                if this.disableLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_DISABLE,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeDisable takes nothing returns nothing
                set this.disableLevel=this.disableLevel-1
                if this.disableLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_DISABLE)
                debug elseif this.disableLevel<0 then
                    debug call BJDebugMsg("Status Error - More disables removed than previously added.")
                endif
            endmethod
            method isDisabled takes nothing returns boolean
                return this.disableLevel>0
            endmethod
            
            // Silence
            private integer silenceLevel
            method addSilence takes nothing returns nothing
                set this.silenceLevel=this.silenceLevel+1
                if this.silenceLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_SILENCE,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeSilence takes nothing returns nothing
                set this.silenceLevel=this.silenceLevel-1
                if this.silenceLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_SILENCE)
                endif
            endmethod
            method isSilenced takes nothing returns boolean
                return this.silenceLevel>0
            endmethod
            
            private integer doomLevel
            method addDoom takes nothing returns nothing
                set this.doomLevel=this.doomLevel+1
                if this.doomLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_DOOM,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeDoom takes nothing returns nothing
                set this.doomLevel=this.doomLevel-1
                if this.doomLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_DOOM)
                endif
            endmethod
            method isDoomed takes nothing returns boolean
                return this.doomLevel>0
            endmethod
            
            // Disarm (Melee)
            private integer disarmMeleeLevel
            private integer disarmRangeLevel
            method addDisarmMelee takes nothing returns nothing
                set this.disarmMeleeLevel=this.disarmMeleeLevel+1
                if this.disarmMeleeLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    if this.disarmRangeLevel>0 then
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_RANGE)
                        call IssueTargetOrderById(CASTER_DISARM_BOTH,OID_DISARM,this.unit)
                    else
                        call IssueTargetOrderById(CASTER_DISARM_MELEE,OID_DISARM,this.unit)
                    endif
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method addDisarmRange takes nothing returns nothing
                set this.disarmRangeLevel=this.disarmRangeLevel+1
                if this.disarmRangeLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    if this.disarmMeleeLevel>0 then
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_MELEE)
                        call IssueTargetOrderById(CASTER_DISARM_BOTH,OID_DISARM,this.unit)
                    else
                        call IssueTargetOrderById(CASTER_DISARM_RANGE,OID_DISARM,this.unit)
                    endif
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method addDisarm takes nothing returns nothing
                set this.disarmMeleeLevel=this.disarmMeleeLevel+1
                set this.disarmRangeLevel=this.disarmRangeLevel+1
                if this.disarmMeleeLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    if this.disarmRangeLevel>0 then
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_RANGE)
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_MELEE)
                        call IssueTargetOrderById(CASTER_DISARM_BOTH,OID_DISARM,this.unit)
                    else
                        call IssueTargetOrderById(CASTER_DISARM_MELEE,OID_DISARM,this.unit)
                    endif
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                else
                    if this.disarmRangeLevel>0 then
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                        endif
                        call IssueTargetOrderById(CASTER_DISARM_RANGE,OID_DISARM,this.unit)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                        endif
                    endif
                endif
            endmethod
            method removeDisarmMelee takes nothing returns nothing
                set this.disarmMeleeLevel=this.disarmMeleeLevel-1
                if this.disarmMeleeLevel==0 then
                    if this.disarmRangeLevel>0 then
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_BOTH)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                        endif
                        call IssueTargetOrderById(CASTER_DISARM_RANGE,OID_DISARM,this.unit)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                        endif
                    else
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_MELEE)
                    endif
                endif
            endmethod
            method removeDisarmRange takes nothing returns nothing
                set this.disarmRangeLevel=this.disarmRangeLevel-1
                if this.disarmRangeLevel==0 then
                    if this.disarmMeleeLevel>0 then
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_BOTH)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                        endif
                        call IssueTargetOrderById(CASTER_DISARM_MELEE,OID_DISARM,this.unit)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                        endif
                    else
                        call UnitRemoveAbility(this.unit,BUFF_DISARM_RANGE)
                    endif
                endif
            endmethod
            method removeDisarm takes nothing returns nothing
                set this.disarmMeleeLevel=this.disarmMeleeLevel-1
                set this.disarmRangeLevel=this.disarmRangeLevel-1
                if this.disarmMeleeLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_DISARM_BOTH)
                    call UnitRemoveAbility(this.unit,BUFF_DISARM_MELEE)
                    if this.disarmRangeLevel>0 then
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                        endif
                        call IssueTargetOrderById(CASTER_DISARM_RANGE,OID_DISARM,this.unit)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                        endif
                    endif
                elseif this.disarmRangeLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_DISARM_BOTH)
                    call UnitRemoveAbility(this.unit,BUFF_DISARM_RANGE)
                    if this.disarmMeleeLevel>0 then
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                        endif
                        call IssueTargetOrderById(CASTER_DISARM_MELEE,OID_DISARM,this.unit)
                        static if not PERMENANTLY_REVEAL then
                            call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                        endif
                    endif
                endif
            endmethod
            method isDisarmedMelee takes nothing returns boolean
                return this.disarmMeleeLevel>0
            endmethod
            method isDisarmedRange takes nothing returns boolean
                return this.disarmRangeLevel>0
            endmethod
            method isDisarmed takes nothing returns boolean
                return this.disarmMeleeLevel>0 and this.disarmRangeLevel>0
            endmethod
            
            // Immobolise
            private integer immoboliseLevel
            method addImmobolise takes nothing returns nothing
                set this.immoboliseLevel=this.immoboliseLevel+1
                if this.immoboliseLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_IMMOBOLISE,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeImmobolise takes nothing returns nothing
                set this.immoboliseLevel=this.immoboliseLevel-1
                if this.immoboliseLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_IMMOBOLISE_GROUND)
                    call UnitRemoveAbility(this.unit,BUFF_IMMOBOLISE_AIR)
                endif
            endmethod
            method isImmobolised takes nothing returns boolean
                return this.immoboliseLevel>0
            endmethod
            
            // Invisibility
            private integer invisibleLevel
            method addInvisible takes nothing returns nothing
                set this.invisibleLevel=this.invisibleLevel+1
                if this.invisibleLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_INVISIBLE)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_INVISIBLE)
                endif
            endmethod
            method removeInvisible takes nothing returns nothing
                set this.invisibleLevel=this.invisibleLevel-1
                if this.invisibleLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_INVISIBLE)
                    call UnitRemoveAbility(this.unit,ABIL_INVISIBLE)
                endif
            endmethod
            method isInvisible takes nothing returns boolean
                return this.invisibleLevel>0
            endmethod
            
            // Ghost
            private integer ghostLevel
            method addGhost takes nothing returns nothing
                set this.ghostLevel=this.ghostLevel+1
                if this.ghostLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_GHOST)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_GHOST)
                endif
            endmethod
            method removeGhost takes nothing returns nothing
                set this.ghostLevel=this.ghostLevel-1
                if this.ghostLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_GHOST)
                    call UnitRemoveAbility(this.unit,ABIL_GHOST)
                endif
            endmethod
            method isGhost takes nothing returns boolean
                return this.ghostLevel>0
            endmethod
            
            // Invulnerability
            private integer invulnerableLevel
            method addInvulnerable takes nothing returns nothing
                set this.invulnerableLevel=this.invulnerableLevel+1
                if this.invulnerableLevel>0 then
                    call SetUnitInvulnerable(this.unit,true)
                endif
            endmethod
            method removeInvulnerable takes nothing returns nothing
                set this.invulnerableLevel=this.invulnerableLevel-1
                if this.invulnerableLevel==0 then
                    call SetUnitInvulnerable(this.unit,false)
                endif
            endmethod
            method isInvulnerable takes nothing returns boolean
                return this.invulnerableLevel>0
            endmethod
            
            // Spell Immunity
            private integer immunityLevel
            method addImmunity takes nothing returns nothing
                set this.immunityLevel=this.immunityLevel+1
                if this.immunityLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_IMMUNITY)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_IMMUNITY)
                endif
            endmethod
            method removeImmunity takes nothing returns nothing
                set this.immunityLevel=this.immunityLevel-1
                if this.immunityLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_IMMUNITY)
                    call UnitRemoveAbility(this.unit,ABIL_IMMUNITY)
                endif
            endmethod
            method isImmune takes nothing returns boolean
                return this.immunityLevel>0
            endmethod
            
            // Pause
            private integer pauseLevel
            method addPause takes nothing returns nothing
                set this.pauseLevel=this.pauseLevel+1
                if this.pauseLevel>0 then
                    call PauseUnit(this.unit,true)
                endif
            endmethod
            method removePause takes nothing returns nothing
                set this.pauseLevel=this.pauseLevel-1
                if this.pauseLevel==0 then
                    call PauseUnit(this.unit,false)
                endif
            endmethod
            method isPaused takes nothing returns boolean
                return this.pauseLevel>0
            endmethod
            
            // Hide
            private integer hideLevel
            method addHide takes nothing returns nothing
                set this.hideLevel=this.hideLevel+1
                if this.hideLevel>0 then
                    call ShowUnit(this.unit,false)
                endif
            endmethod
            method removeHide takes nothing returns nothing
                set this.hideLevel=this.hideLevel-1
                if this.hideLevel==0 then
                    call ShowUnit(this.unit,true)
                endif
            endmethod
            method isHidden takes nothing returns boolean
                return this.hideLevel>0
            endmethod
            
            // Unpath
            private integer unpathLevel
            method addUnpath takes nothing returns nothing
                set this.unpathLevel=this.unpathLevel+1
                if this.unpathLevel>0 then
                    call SetUnitPathing(this.unit,false)
                endif
            endmethod
            method removeUnpath takes nothing returns nothing
                set this.unpathLevel=this.unpathLevel-1
                if this.unpathLevel==0 then
                    call SetUnitPathing(this.unit,true)
                endif
            endmethod
            method isUnpathed takes nothing returns boolean
                return this.unpathLevel>0
            endmethod
            
            // Hex
            private integer hexLevel
            method addHex takes nothing returns nothing
                set this.hexLevel=this.hexLevel+1
                if this.hexLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_HEX,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeHex takes nothing returns nothing
                set this.hexLevel=this.hexLevel-1
                if this.hexLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_HEX)
                endif
            endmethod
            method isHexed takes nothing returns boolean
                return this.hexLevel>0
            endmethod
            
            // Locust
            private integer locustLevel
            method addLocust takes nothing returns nothing
                set this.locustLevel=this.locustLevel+1
                if this.locustLevel>0 then
                    call UnitAddAbility(this.unit,'Aloc')
                    call UnitMakeAbilityPermanent(this.unit,true,'Aloc')
                endif
            endmethod
            method removeLocust takes nothing returns nothing
                set this.locustLevel=this.locustLevel-1
                if this.locustLevel==0 then
                    call ShowUnit(this.unit,false)
                    call UnitMakeAbilityPermanent(this.unit,false,'Aloc')
                    call UnitRemoveAbility(this.unit,'Aloc')
                    call ShowUnit(this.unit,true)
                    call UnitAddAbility(this.unit,ABIL_UNLOCUST)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_UNLOCUST)
                    call IssueImmediateOrderById(this.unit,OID_UNLOCUST)
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_UNLOCUST)
                    call UnitRemoveAbility(this.unit,ABIL_UNLOCUST)
                endif
            endmethod
            method isLocust takes nothing returns boolean
                return this.locustLevel>0
            endmethod
            
            // Never Miss
            private integer neverMissLevel
            method addNeverMiss takes nothing returns nothing
                set this.neverMissLevel=this.neverMissLevel+1
                if this.neverMissLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_NEVER_MISS)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_NEVER_MISS)
                endif
            endmethod
            method removeNeverMiss takes nothing returns nothing
                set this.neverMissLevel=this.neverMissLevel-1
                if this.neverMissLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_NEVER_MISS)
                    call UnitRemoveAbility(this.unit,ABIL_NEVER_MISS)
                endif
            endmethod
            method isNeverMiss takes nothing returns boolean
                return this.neverMissLevel>0
            endmethod
            
            // Always Miss
            private integer alwaysMissLevel
            method addAlwaysMiss takes nothing returns nothing
                set this.alwaysMissLevel=this.alwaysMissLevel+1
                if this.alwaysMissLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_ALWAYS_MISS)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_ALWAYS_MISS)
                endif
            endmethod
            method removeAlwaysMiss takes nothing returns nothing
                set this.alwaysMissLevel=this.alwaysMissLevel-1
                if this.alwaysMissLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_ALWAYS_MISS)
                    call UnitRemoveAbility(this.unit,ABIL_ALWAYS_MISS)
                endif
            endmethod
            method isAlwaysMiss takes nothing returns boolean
                return this.alwaysMissLevel>0
            endmethod
            
            // Untouchable
            private integer untouchableLevel
            method addUntouchable takes nothing returns nothing
                set this.untouchableLevel=this.untouchableLevel+1
                if this.untouchableLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_UNTOUCHABLE)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_UNTOUCHABLE)
                endif
            endmethod
            method removeUntouchable takes nothing returns nothing
                set this.untouchableLevel=this.untouchableLevel-1
                if this.untouchableLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_UNTOUCHABLE)
                    call UnitRemoveAbility(this.unit,ABIL_UNTOUCHABLE)
                endif
            endmethod
            method isUntouchable takes nothing returns boolean
                return this.untouchableLevel>0
            endmethod
            
            // Banish
            private integer banishLevel
            method addBanish takes nothing returns nothing
                set this.banishLevel=this.banishLevel+1
                if this.banishLevel>0 then
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,true)
                    endif
                    call IssueTargetOrderById(thistype.dummyCaster,OID_BANISH,this.unit)
                    static if not PERMENANTLY_REVEAL then
                        call UnitShareVision(this.unit,DUMMY_CASTER_OWNER,false)
                    endif
                endif
            endmethod
            method removeBanish takes nothing returns nothing
                set this.banishLevel=this.banishLevel-1
                if this.banishLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_BANISH)
                endif
            endmethod
            method isBanished takes nothing returns boolean
                return this.banishLevel>0
            endmethod
            
            // Phase
            private integer phaseLevel
            method addPhase takes nothing returns nothing
                set this.phaseLevel=this.phaseLevel+1
                if this.phaseLevel>0 then
                    call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit),ABIL_PHASE,true)
                    if UnitAddAbility(this.unit,ABIL_PHASE) then
                        call UnitMakeAbilityPermanent(this.unit,true,ABIL_PHASE)
                    endif
                    call IssueImmediateOrderById(this.unit,OID_PHASE)
                    call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit),ABIL_PHASE,false)
                endif
            endmethod
            method removePhase takes nothing returns nothing
                set this.phaseLevel=this.phaseLevel-1
                if this.phaseLevel==0 then
                    call UnitRemoveAbility(this.unit,BUFF_PHASE)
                endif
            endmethod
            method isPhased takes nothing returns boolean
                return this.phaseLevel>0
            endmethod
            /*
            // Double Attack
            private integer doubleAttackLevel
            method addDoubleAttack takes nothing returns nothing
                set this.doubleAttackLevel=this.doubleAttackLevel+1
                if this.doubleAttackLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_DOUBLE_ATTACK)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_DOUBLE_ATTACK)
                endif
            endmethod
            method removeDoubleAttack takes nothing returns nothing
                set this.doubleAttackLevel=this.doubleAttackLevel-1
                if this.doubleAttackLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_DOUBLE_ATTACK)
                    call UnitRemoveAbility(this.unit,ABIL_DOUBLE_ATTACK)
                endif
            endmethod
            method isDoubleAttack takes nothing returns boolean
                return this.doubleAttackLevel>0
            endmethod
            */
            // Resistant Skin
            private integer resistantSkinLevel
            method addResistantSkin takes nothing returns nothing
                set this.resistantSkinLevel=this.resistantSkinLevel+1
                if this.resistantSkinLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_RESISTANT_SKIN)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_RESISTANT_SKIN)
                endif
            endmethod
            method removeResistantSkin takes nothing returns nothing
                set this.resistantSkinLevel=this.resistantSkinLevel-1
                if this.resistantSkinLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_RESISTANT_SKIN)
                    call UnitRemoveAbility(this.unit,ABIL_RESISTANT_SKIN)
                endif
            endmethod
            method isResistantSkin takes nothing returns boolean
                return this.resistantSkinLevel>0
            endmethod
            
            // Reflect Piercing
            private integer reflectPiercingLevel
            method addReflectPiercing takes nothing returns nothing
                set this.reflectPiercingLevel=this.reflectPiercingLevel+1
                if this.reflectPiercingLevel>0 then
                    call UnitAddAbility(this.unit,ABIL_REFLECT_PIERCING)
                    call UnitMakeAbilityPermanent(this.unit,true,ABIL_REFLECT_PIERCING)
                endif
            endmethod
            method removeReflectPiercing takes nothing returns nothing
                set this.reflectPiercingLevel=this.reflectPiercingLevel-1
                if this.reflectPiercingLevel==0 then
                    call UnitMakeAbilityPermanent(this.unit,false,ABIL_REFLECT_PIERCING)
                    call UnitRemoveAbility(this.unit,ABIL_REFLECT_PIERCING)
                endif
            endmethod
            method isReflectPiercing takes nothing returns boolean
                return this.reflectPiercingLevel>0
            endmethod
            
            
            ////////////////////
            // Status Bonuses //
            ////////////////////
            private static method setBonus takes unit u, integer abil, integer levels, integer amount returns nothing
                local boolean addNeg=false
                if amount<0 then
                    set addNeg=true
                    set amount=amount+thistype.twoPow[levels]
                else
                    call UnitMakeAbilityPermanent(u,false,abil)
                    call UnitRemoveAbility(u,abil)
                endif
                
                set abil=abil+levels
                set levels=thistype.twoPow[levels]
                loop
                    set levels=levels/2
                    
                    if amount>=levels then
                        call UnitAddAbility(u,abil)
                        call UnitMakeAbilityPermanent(u,true,abil)
                        set amount=amount-levels
                    else
                        call UnitMakeAbilityPermanent(u,false,abil)
                        call UnitRemoveAbility(u,abil)
                    endif
                    
                    set abil=abil-1
                    exitwhen levels==1
                endloop
                
                if addNeg then
                    call UnitAddAbility(u,abil)
                    call UnitMakeAbilityPermanent(u,true,abil)
                endif
            endmethod
            
            private integer armorBonus
            method modArmorBonus takes integer amount returns nothing
                set this.armorBonus=this.armorBonus+amount
                debug if this.armorBonus>=thistype.twoPow[LEVELS_ARMOR] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modArmorBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_ARMOR])+".")
                debug endif
                debug if this.armorBonus<-thistype.twoPow[LEVELS_ARMOR] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modArmorBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_ARMOR])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_ARMOR,LEVELS_ARMOR,this.armorBonus)
            endmethod
            method getArmorBonus takes nothing returns integer
                return this.armorBonus
            endmethod
            
            private integer damageBonus
            method modDamageBonus takes integer amount returns nothing
                set this.damageBonus=this.damageBonus+amount
                debug if this.damageBonus>=thistype.twoPow[LEVELS_DAMAGE] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modDamageBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_DAMAGE])+".")
                debug endif
                debug if this.damageBonus<-thistype.twoPow[LEVELS_DAMAGE] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modDamageBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_DAMAGE])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_DAMAGE,LEVELS_DAMAGE,this.damageBonus)
            endmethod
            method getDamageBonus takes nothing returns integer
                return this.damageBonus
            endmethod
            
            private integer strBonus
            method modStrBonus takes integer amount returns nothing
                set this.strBonus=this.strBonus+amount
                debug if this.strBonus>=thistype.twoPow[LEVELS_STR] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modStrBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_STR])+".")
                debug endif
                debug if this.strBonus<-thistype.twoPow[LEVELS_STR] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modStrBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_STR])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_STR,LEVELS_STR,this.strBonus)
            endmethod
            method getStrBonus takes nothing returns integer
                return this.strBonus
            endmethod
            
            private integer agiBonus
            method modAgiBonus takes integer amount returns nothing
                set this.agiBonus=this.agiBonus+amount
                debug if this.agiBonus>=thistype.twoPow[LEVELS_AGI] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modAgiBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_AGI])+".")
                debug endif
                debug if this.agiBonus<-thistype.twoPow[LEVELS_AGI] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modAgiBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_AGI])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_AGI,LEVELS_AGI,this.agiBonus)
            endmethod
            method getAgiBonus takes nothing returns integer
                return this.agiBonus
            endmethod
            
            private integer intBonus
            method modIntBonus takes integer amount returns nothing
                set this.intBonus=this.intBonus+amount
                debug if this.intBonus>=thistype.twoPow[LEVELS_INT] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modIntBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_INT])+".")
                debug endif
                debug if this.intBonus<-thistype.twoPow[LEVELS_INT] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modIntBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_INT])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_INT,LEVELS_INT,this.intBonus)
            endmethod
            method getIntBonus takes nothing returns integer
                return this.intBonus
            endmethod
            
            private integer attackSpeedBonus
            method modAttackSpeedBonus takes integer amount returns nothing
                set this.attackSpeedBonus=this.attackSpeedBonus+amount
                debug if this.attackSpeedBonus>=thistype.twoPow[LEVELS_ATTACK_SPEED] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modAttackSpeedBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_ATTACK_SPEED])+".")
                debug endif
                debug if this.attackSpeedBonus<-thistype.twoPow[LEVELS_ATTACK_SPEED] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modAttackSpeedBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_ATTACK_SPEED])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_ATTACK_SPEED,LEVELS_ATTACK_SPEED,this.attackSpeedBonus)
            endmethod
            method getAttackSpeedBonus takes nothing returns integer
                return this.attackSpeedBonus
            endmethod
            
            private integer healthBonus
            method modHealthBonus takes integer amount returns nothing
                set this.healthBonus=this.healthBonus+amount
                debug if this.healthBonus>=thistype.twoPow[LEVELS_HEALTH] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modHealthBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_HEALTH])+".")
                debug endif
                debug if this.healthBonus<-thistype.twoPow[LEVELS_HEALTH] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modHealthBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_HEALTH])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_HEALTH,LEVELS_HEALTH,this.healthBonus)
            endmethod
            method getHealthBonus takes nothing returns integer
                return this.healthBonus
            endmethod
            
            private integer manaBonus
            method modManaBonus takes integer amount returns nothing
                set this.manaBonus=this.manaBonus+amount
                debug if this.manaBonus>=thistype.twoPow[LEVELS_MANA] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modManaBonus("+I2S(amount)+") - must not reach >= "+I2S(thistype.twoPow[LEVELS_MANA])+".")
                debug endif
                debug if this.manaBonus<-thistype.twoPow[LEVELS_MANA] then
                    debug call BJDebugMsg("Status Error: Status["+GetUnitName(this.unit)+"].modManaBonus("+I2S(amount)+") - must not reach < -"+I2S(thistype.twoPow[LEVELS_MANA])+".")
                debug endif
                call thistype.setBonus(this.unit,ABIL_MANA,LEVELS_MANA,this.manaBonus)
            endmethod
            method getManaBonus takes nothing returns integer
                return this.manaBonus
            endmethod
            
            // Periodic bonuses
            private static unit updateUnit
            
            private static group healthRegenGroup=CreateGroup()
            private static method healthRegenPeriodic takes nothing returns nothing
                set thistype.updateUnit=GetEnumUnit()
                if UnitAlive(thistype.updateUnit) then
                    call SetWidgetLife(thistype.updateUnit,GetWidgetLife(thistype.updateUnit)+thistype[thistype.updateUnit].healthRegenBonus)
                endif
            endmethod
            private real healthRegenBonus
            method modHealthRegenBonus takes real amount returns nothing
                set this.healthRegenBonus=this.healthRegenBonus+amount*PERIOD
                if this.healthRegenBonus==0 then
                    call GroupRemoveUnit(thistype.healthRegenGroup,this.unit)
                else
                    call GroupAddUnit(thistype.healthRegenGroup,this.unit)
                endif
            endmethod
            method getHealthRegenBonus takes nothing returns real
                return this.healthRegenBonus/PERIOD
            endmethod
            
            private static group manaRegenGroup=CreateGroup()
            private static method manaRegenPeriodic takes nothing returns nothing
                set thistype.updateUnit=GetEnumUnit()
                if UnitAlive(thistype.updateUnit) then
                    call SetUnitState(thistype.updateUnit,UNIT_STATE_MANA,GetUnitState(thistype.updateUnit,UNIT_STATE_MANA)+thistype[thistype.updateUnit].manaRegenBonus)
                endif
            endmethod
            private real manaRegenBonus
            method modManaRegenBonus takes real amount returns nothing
                set this.manaRegenBonus=this.manaRegenBonus+amount*PERIOD
                if this.manaRegenBonus==0 then
                    call GroupRemoveUnit(thistype.manaRegenGroup,this.unit)
                else
                    call GroupAddUnit(thistype.manaRegenGroup,this.unit)
                endif
            endmethod
            method getManaRegenBonus takes nothing returns real
                return this.manaRegenBonus/PERIOD
            endmethod
            
            private static group healthRegenPercentGroup=CreateGroup()
            private static method healthRegenPercentPeriodic takes nothing returns nothing
                set thistype.updateUnit=GetEnumUnit()
                if UnitAlive(thistype.updateUnit) then
                    call SetWidgetLife(thistype.updateUnit,GetWidgetLife(thistype.updateUnit)+GetUnitState(thistype.updateUnit,UNIT_STATE_MAX_LIFE)*thistype[thistype.updateUnit].healthRegenPercentBonus)
                endif
            endmethod
            private real healthRegenPercentBonus
            method modHealthRegenPercentBonus takes real amount returns nothing
                set this.healthRegenPercentBonus=this.healthRegenPercentBonus+amount*PERIOD*0.01
                if this.healthRegenPercentBonus==0 then
                    call GroupRemoveUnit(thistype.healthRegenPercentGroup,this.unit)
                else
                    call GroupAddUnit(thistype.healthRegenPercentGroup,this.unit)
                endif
            endmethod
            method getHealthRegenPercentBonus takes nothing returns real
                return this.healthRegenPercentBonus/PERIOD/0.01
            endmethod
            
            private static group manaRegenPercentGroup=CreateGroup()
            private static method manaRegenPercentPeriodic takes nothing returns nothing
                set thistype.updateUnit=GetEnumUnit()
                if UnitAlive(thistype.updateUnit) then
                    call SetUnitState(thistype.updateUnit,UNIT_STATE_MANA,GetUnitState(thistype.updateUnit,UNIT_STATE_MANA)+GetUnitState(thistype.updateUnit,UNIT_STATE_MAX_MANA)*thistype[thistype.updateUnit].manaRegenPercentBonus)
                endif
            endmethod
            private real manaRegenPercentBonus
            method modManaRegenPercentBonus takes real amount returns nothing
                set this.manaRegenPercentBonus=this.manaRegenPercentBonus+amount*PERIOD*0.01
                if this.manaRegenPercentBonus==0 then
                    call GroupRemoveUnit(thistype.manaRegenPercentGroup,this.unit)
                else
                    call GroupAddUnit(thistype.manaRegenPercentGroup,this.unit)
                endif
            endmethod
            method getManaRegenPercentBonus takes nothing returns real
                return this.manaRegenPercentBonus/PERIOD/0.01
            endmethod
            
            // Links periodic effects.
            private static method periodicLink takes nothing returns nothing
                call ForGroup(thistype.healthRegenGroup,function thistype.healthRegenPeriodic)
                call ForGroup(thistype.manaRegenGroup,function thistype.manaRegenPeriodic)
                call ForGroup(thistype.healthRegenPercentGroup,function thistype.healthRegenPercentPeriodic)
                call ForGroup(thistype.manaRegenPercentGroup,function thistype.manaRegenPercentPeriodic)
            endmethod
            implement StaticPeriodic
            
            ////////////////////
            // Movement Speed //
            ////////////////////
            
            private real moveSpeedBonus
            private real moveSpeedPercentBonus
            private real x
            private real y
            private static real updateUnitX
            private static real updateUnitY
            private static real xInc
            private static real yInc
            private static real updateDist
            private method periodic takes nothing returns nothing
                set thistype.updateUnit=this.unit
                set thistype.updateUnitX=GetUnitX(thistype.updateUnit)
                set thistype.updateUnitY=GetUnitY(thistype.updateUnit)
                set thistype.xInc=thistype.updateUnitX-this.x
                set thistype.yInc=thistype.updateUnitY-this.y
                set thistype.updateDist=SquareRoot(thistype.xInc*thistype.xInc+thistype.yInc*thistype.yInc)
                if thistype.updateDist>0 then
                    if UnitAlive(thistype.updateUnit) and this.disableLevel<=0 and this.stunLevel<=0 and this.pauseLevel<=0 and this.immoboliseLevel<=0 and GetUnitMoveSpeed(thistype.updateUnit)>0 then
                        if this.moveSpeedPercentBonus!=0.0 then
                            set thistype.updateUnitX=thistype.updateUnitX+thistype.xInc*this.moveSpeedPercentBonus
                            set thistype.updateUnitY=thistype.updateUnitY+thistype.yInc*this.moveSpeedPercentBonus
                        endif
                        if this.moveSpeedBonus!=0.0 then
                            set thistype.updateDist=this.moveSpeedBonus/thistype.updateDist
                            set thistype.updateUnitX=thistype.updateUnitX+thistype.xInc*thistype.updateDist
                            set thistype.updateUnitY=thistype.updateUnitY+thistype.yInc*thistype.updateDist
                        endif
                        call SetUnitX(thistype.updateUnit,thistype.updateUnitX)
                        call SetUnitY(thistype.updateUnit,thistype.updateUnitY)
                    endif
                endif
                set this.x=thistype.updateUnitX
                set this.y=thistype.updateUnitY
            endmethod
            implement T32xs
            method modMoveSpeedBonus takes real amount returns nothing
                set this.moveSpeedBonus=this.moveSpeedBonus+amount*T32_PERIOD
                if this.moveSpeedBonus==0 and this.moveSpeedPercentBonus==0 then
                    call this.stopPeriodic()
                else
                    set this.x=GetUnitX(this.unit)
                    set this.y=GetUnitY(this.unit)
                    call this.startPeriodic()
                endif
            endmethod
            method getMoveSpeedBonus takes nothing returns real
                return this.moveSpeedBonus/T32_PERIOD
            endmethod
            method modMoveSpeedPercentBonus takes real amount returns nothing
                set this.moveSpeedPercentBonus=this.moveSpeedPercentBonus+amount*0.01
                if this.moveSpeedBonus==0 and this.moveSpeedPercentBonus==0 then
                    call this.stopPeriodic()
                else
                    set this.x=GetUnitX(this.unit)
                    set this.y=GetUnitY(this.unit)
                    call this.startPeriodic()
                endif
            endmethod
            method getMoveSpeedPercentBonus takes nothing returns real
                return this.moveSpeedPercentBonus/0.01
            endmethod
        endstruct
    endlibrary
    
    library Stun uses Status // Deprecated. Backwards compatability with "Stun" system.
        function AddStun takes unit whichUnit returns nothing
            call Status[whichUnit].addStun()
        endfunction
        function RemoveStun takes unit whichUnit returns nothing
            call Status[whichUnit].removeStun()
        endfunction
        function Stun_IsUnitStunned takes unit whichUnit returns boolean
            return Status[whichUnit].isStunned()
        endfunction
    endlibrary
     
  3. Viikuna

    Viikuna No Marlo no game.

    Ratings:
    +265 / 0 / -0
    This is solved by using a dummy unit with 100% bash, like Anitarf does in his buff system.

    Also, Im not really a fan of little systems like these.

    I would rather see some big bad ass buff system, that allows you to create triggered custom buffs, that can have various effects, like stun, spellcast disable, attack disable and total disable, as well as stats modifying stuff, ( example: attack, armor, strength, manaregen, movespeed )

    ( It should probably use UnitProperties for this stats modifying stuff )

    Buff system should also support some nice triggered effects, that you can apply onBuffStart and remove onBuffEnd ( or whatever names you use for that stuff ) as well as do stuff periodically during the buff duration.

    edit. Actually, that stats modifying stuff can also be done in onAdd and onRemove just fine. But yea, Big
    Bad Ass Buff System.

    edit2. Actually, if you dont like the idea of Big Bad Ass Buff System you could convert this to something like that DummyCaster struct I used in Quicksand. People then use this for stunning, and slowing and rooting etc.

    JASS:
    
       set Stun=Buff.create( STUN_ABILITY_ID,STUN_ORDER_ID)
       set Roots=Buff.create( ROOTS_ABILITY_ID,ROOTS_ORDER_ID)  
       
       //...
    
       call Stun.add( unit )
       // ...
       call Stun.remove( unit )
     
  4. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    Can that instant cast?
    I dunno. All this stuff is inconsistent. Do you make it so the user has to design their own buffs and such, or is it done through a textmacro for example?

    It's not like you can really give a good interface for buff stuff either way. I'd largely just write the 5 lines of code or w/e to do it myself.

    Stun is needed so often. I could extend it to other effects, like Silence. I suppose it makes sense.
     
  5. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    Would that work on ethereal?

    Stun spells can work on magic immune if the spell is made to be an "ultimate" hero ability, and Gameplay - Magic Immunes Resist Ultimates is set to false in the Gameplay Constants. (False is the default.)

    [edit] I'm not sure how this would play with the spell shield item, though, or anti-magic shell.
     
  6. Viikuna

    Viikuna No Marlo no game.

    Ratings:
    +265 / 0 / -0
    Good point.

    I think what Weep suggested is the way to go.
     
  7. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    I actually like it not working on magic immune, to be honest.

    Do you need this to work on magic immune? =/

    >I'm not sure how this would play with the spell shield item, though, or anti-magic shell.
    We can't account for everything. o.o
     
  8. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    If it can, why not? Let the user decide if they want to stun magic immune.

    We can try! :D

    Attacks can take effect instantly, but not "instant cast" in the sense of having one unit cast successively at once. One dummy per target would be needed.
     
  9. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    Then I'd prefer the current way.

    Even so, the stun would have to either not work on ethereal units, or not work on spell immune units? So this is moot point. Makes more sense not to work on spell immune.

    Lol, what if a unit had evasion?

    I'm still convinced a spell has the best set of pros vs cons - and definitely the most expected.
     
  10. Tyrande_ma3x

    Tyrande_ma3x .

    Ratings:
    +91 / 0 / -0
    You can always use Aerial Shackles but it would require 1 dummy per unit; still, it goes through magic immunes and will always "stun" your target.
     
  11. Kenny

    Kenny Back for now.

    Ratings:
    +202 / 0 / -0
    I think he went that attacking would need one dummy per target. If you made the spell an ultimate then it would work on magic immune and ethereal.

    Isn't there an option on bash to not miss any attacks? Same with critical strike.

    Anyways this is good. Personally, I like this for something like stun. I don't see a need for a massive system for buffs. Stuns are pretty much an integral part of warcraft, having a separate system for it is smart. Plus this works really well.

    Also makes me think you should update Stack Safety with some more safety functions soon. :D
     
  12. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    Heh, makes more sense to not work on ethereal, to me. They're like ghosts - how can you konk a ghost on the head? :p Besides, which situation is less common, and therefore less important to support: spell immune or ethereal?

    But you're right, it is moot; as an "ultimate", the spell could stun magic immune units in most maps, which I think is good enough (and I don't see any validity to your preference to limit it at the system-level). Besides, even as a last resort, the system could use both methods, only using the attack-bash if the target is spell immune, but that's not really necessary.

    That's the nice thing about a 100% bash with Never Miss set true. :D
     
  13. Viikuna

    Viikuna No Marlo no game.

    Ratings:
    +265 / 0 / -0
    Aerial Shackles is actually pretty good for disabling target, when you dont wanna mess your stunning functions.
     
  14. TriggerHappy

    TriggerHappy ...

    Ratings:
    +341 / 0 / -0
  15. GetTriggerUnit-

    GetTriggerUnit- DogEntrepreneur

    Ratings:
    +128 / 0 / -0
    Or the "Custom stun system" could run of the effect of the stun's buff and pause safety?

    This is just an idea... :D

    JASS:
    
    function StunUnit takes unit u, real dura returns nothing
        local effect sfx = AddSpecialEffectTarget(u, STUNEFFECT, "overhead")
        call TriggerSleepAction(dura)
        call DestroyEffect(sfx)
        set sfx = null
    // It could even use some timer system... 
    // And AIDS, of course there's not a system made by J4L that does not uses AIDS!!:exclamationmark:
    endfunction
     
  16. TriggerHappy

    TriggerHappy ...

    Ratings:
    +341 / 0 / -0
    I think this naming convention is better. It fits Warcraft's naming conventions.

    JASS:
    function UnitAddStun takes unit target returns nothing
    function UnitRemoveStun takes unit target returns nothing
     
  17. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    Just tried, didn't work (tried on Phoenix). Thanks for suggestion.

    >as an "ultimate", the spell could stun magic immune units in most maps
    I don't see how to make an ability an ultimate. I think that may be built into the ability.

    I don't want dummy-per-cast or else I wouldn't use this myself...
     
  18. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    Make the ability a hero ability and set its required level to something higher than 1. (...I think. Usually I set it to 6 to match the built-in abilities. In case you're concerned, you can, of course, add hero abilities to non-hero units through triggers and it'll work just fine.)

    In case it wasn't clear, that was only needed for dummies that would attack/bash. "Ultimates" work just like normal spells, except the map can allow them to work even on spell immune units.

    (Not every spell will work properly as an ultimate, but fortunately, stun does. I've tried. :))
     
    • Like Like x 1
  19. Jesus4Lyf

    Jesus4Lyf Good Idea™

    Ratings:
    +394 / 0 / -0
    HAX!!

    Thankyou noted and implemented. Now works on spell immune units. :thup:
     
  20. Azlier

    Azlier Old World Ghost

    Ratings:
    +461 / 0 / -0
    That's incredible! Ultimate abilities can be created rather than just needing to clone an existing one. Very nice.
     

Share This Page