HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

'effect system' remarks pls

10-26-2008, 12:47 PM#1
fX_
EDIT:

//buffs
now i have under buffs 'properties', 'pauses' (stuns), 'hides', and 'ownerships'. properties can be inc(dec)remented over the duration of the buff. pauses hides and ownerships are simple | pause/hide/change owner ---> wait ----> reset | (reset if the unit is not still pause/hidden by another pause/hideBuff).

they all can stack. stacking does this: adds the max durations (max duration x2). for property buffs, the inc(dec)crements are added also, and the initial level for the propertyId is added. if buffs of the same kind (same .intId) are made not to stack, the older one will be destroyed before the new one is applied.

ownershipbuffs has sort of 'control power' system, coz a unit can be controlled by only one owner at a time.

Buffs and Animations can be 'attached' and Buffs.

-movement speed Buff + -armor Buff + green gooey Animation = "Acid Bomb" Buff
destroy (triggered 'purge') one of the buffs, destroy the other AND the Animation. only buffs are meant to be 'purged'.

Effector
Collapse JASS:
library esEffector

////////////////////////////////////////////////////////////////////////////////
// esEffector
//------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////

interface Effect

    method Destroy takes nothing returns nothing

    //------------------------------------------------------------------//
    //Effector Actions

    public method Initiate takes Effector e returns nothing

    public method Terminate takes Effector e returns nothing

    public method Start takes Effector e returns nothing defaults nothing

    public method Meta takes Effector e returns nothing defaults nothing

    public method End takes Effector e returns nothing defaults nothing

endinterface

struct Effector

    //-----------------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS --

    public Effect data

    public boolean boolOn = true

    public real rDuration = 0.00
    public real rDurationInterval
    public integer intCountInterval = 0
    public integer intMaxCountInterval

    public Effector array effectorExtra[100] //Effectors that work in conjunction with a Effector. They get destroyed with the Effector.
                                     //e.g. When a buff that is constituted of two Buffs - say, one for movement speed and
                                     //the other for attack speed - (and an Animation) is destroyed (purge), all the two Buffs
                                     //and the Animation constituting it get destroyed.
    public integer intCountExtra = 0 //Number of Effectors associated with an Effector.

    public static method Create takes Effect data, real duration, integer interval returns Effector
        local Effector New = Effector.allocate()

        set New.data = data
        set New.rDurationInterval = duration
        set New.intMaxCountInterval = interval

        set New.intEffIndex = Effector.intCountEffector
        set Effector.inst[Effector.intCountEffector] = New
        set Effector.intCountEffector = Effector.intCountEffector + 1
        call Effector.UpdateTimer()

        call New.data.Initiate(New)

        return New
    endmethod

    public method Destroy takes nothing returns nothing
        call .data.Terminate(this)
        loop
            exitwhen .intCountExtra == 0
            set .intCountExtra = .intCountExtra - 1
            call .effectorExtra[.intCountExtra].Destroy()
        endloop

        set Effector.intCountEffector = Effector.intCountEffector - 1
        set Effector.inst[Effector.intCountEffector].intEffIndex = .intEffIndex
        set Effector.inst[.intEffIndex] = Effector.inst[Effector.intCountEffector]
        set Effector.inst[Effector.intCountEffector] = 0
        call Effector.UpdateTimer()
    endmethod
    
    //Associates a Effector with a Buff. Association is two-way. Boolean 'reciprocate'
    //is set to 'true' when the association is to be reciprocated from the Effector being
    //associated to the Effector associated to.
    public method AddExtra takes Effector newExtra, boolean reciprocate returns nothing
        set .effectorExtra[.intCountExtra] = newExtra
        set .intCountExtra = .intCountExtra + 1

        if reciprocate then
            call newExtra.AddExtra(this, false)
        endif
    endmethod

    //Disassociates an Effector from another. Disassociation is two-way.
    //NOTE: Disassociation only nullifies links; it doesn't destroy Buffs.
    public method RemoveExtra takes Buff extra, boolean reciprocate returns boolean
        local integer INT_ExtraIndex = 0
        local integer INT_ExtraIndex2 = 0

        loop
            exitwhen INT_ExtraIndex == .intCountExtra
            if .effectorExtra[INT_ExtraIndex] == extra then
                if reciprocate then
                    call .effectorExtra[INT_ExtraIndex].RemoveExtra(this, false)
                endif
                set INT_ExtraIndex2 = INT_ExtraIndex
                loop
                    exitwhen INT_ExtraIndex2 == .intCountExtra
                    set .effectorExtra[INT_ExtraIndex2] = .effectorExtra[INT_ExtraIndex2 + 1]
                    set INT_ExtraIndex2 = INT_ExtraIndex2 + 1
                endloop
                return true
            endif
            set INT_ExtraIndex = INT_ExtraIndex + 1
        endloop

        return false
    endmethod

    private method Execute takes nothing returns nothing
        if .rDuration == 0.00 and .intCountInterval == 0 then
            call .data.Start(this)
        endif

        set .rDuration = .rDuration + Effector.rDurationTimer
        if .rDuration / .rDurationInterval >= 1.00 then
            set .rDuration = 0.00
            set .intCountInterval = .intCountInterval + 1
            if .intCountInterval < .intMaxCountInterval then
                call .data.Meta(this)
            else
                call .data.End(this)
                call .data.Destroy()
            endif
        endif
    endmethod

    //-----------------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --

    private integer intEffIndex

    private static Effector array inst[8190]
    private static integer intCountEffector = 0

    private static timer tim = null
    private static constant real rDurationTimer = 0.10

    private static method GeneralExecute takes nothing returns nothing
        local integer INT_EffectorIndex = 0

        loop
            exitwhen INT_EffectorIndex == Effector.intCountEffector
            if Effector.inst[INT_EffectorIndex].boolOn then
                call Effector.inst[INT_EffectorIndex].Execute()
            endif
            set INT_EffectorIndex = INT_EffectorIndex + 1
        endloop
    endmethod

    private static method UpdateTimer takes nothing returns nothing
        if Effector.intCountEffector == 1 and Effector.tim == null then
            set Effector.tim = CreateTimer()
            call TimerStart(Effector.tim, Effector.rDurationTimer, true, function Effector.GeneralExecute)
        elseif Effector.intCountEffector == 0 then
            call PauseTimer(Effector.tim)
            call DestroyTimer(Effector.tim)
            set Effector.tim = null
        endif
    endmethod

endstruct

endlibrary

Buff
Collapse JASS:
library esBuff requires esEffector, esAnimation

////////////////////////////////////////////////////////////////////////////////
// esBuff
//------------------------------------------------------------------------------
// Buffs, here, work like standard Blizzard buffs; one instance of a buff
// per unit. A Buff is described by an AbilityId (.intId) and target (.uTarget).
//
// PropertyBuff
//
// PauseBuff
//
// HideBuff
//
// OwnershipBuff
// 
// Buffs can be stacked. Since stacking behavior differs between Buff
// extensions (though all stacking involves aggregation of .intMaxInterval's),
// each Buff extension has its own "stack code".
// For PropertyBUffs: A stacked Buff's max number of intervals is
// incremented by the max number of intervals of the additive effect; the
// stacked Buff's level is incremented by the additive effect's initial
// level; the stacked Buff's level margin is incremented by the that of
// the additive Buff.
// For the rest: durations stack.
////////////////////////////////////////////////////////////////////////////////

globals
    public Buff array gBUFF
endglobals

struct Buff extends Effect

    //------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS A --

    public integer intId //AbilityId of the ability that shows the buff in the target's status bar.
    public integer intLevel //Level of the above ability and the level of the Buff.
    public unit uSource //Unit that imparts the Buff.
    public unit uTarget //Unit that starts sustains the Buff.
    public boolean boolGood //A buff is considered to be good if it is the unit that imported it is non-hostile
                            //to the unit that sustains it.

    //Indexes a Buff extension as a Buff.
    public method CreateBuff takes integer id, integer level, unit source, unit target, real duration, integer interval returns nothing
        //Input Buff values (A).
        set .intId = id
        set .intLevel = level
        set .uSource = source
        set .uTarget = target
        set .boolGood = not IsUnitEnemy(source, GetOwningPlayer(target))
        set .effector = Effector.Create(this, duration, interval)
            
        //Manage Buff objects (indexes).
        set .intBuffIndex = Buff.intCountBuff
        set gBUFF[Buff.intCountBuff] = this
        set Buff.intCountBuff = Buff.intCountBuff + 1
    endmethod

    //Deindexes a Buff extension as a Buff.
    public method DestroyBuff takes nothing returns nothing
        //Nullify values and destroy extras.
        set .uSource = null
        set .uTarget = null
        
        //Manage Buff objects (indexes).
        set Buff.intCountBuff = Buff.intCountBuff - 1
        set gBUFF[Buff.intCountBuff].intBuffIndex = .intBuffIndex
        set gBUFF[.intBuffIndex] = gBUFF[Buff.intCountBuff]
        set gBUFF[Buff.intCountBuff] = 0
    endmethod

    //Stacks the Buffs. Sums-up their total durations and takes the higher level.
    public method StackBuff takes integer level, integer interval returns nothing
        //Update Buff level.
        if level > .intLevel then
            set .intLevel = level
            call SetUnitAbilityLevel(.uTarget, .intId, .intLevel)
        endif
        set .effector.intMaxCountInterval = .effector.intMaxCountInterval + interval
    endmethod
    
    public method AddBuff takes Buff newBuff returns nothing
        call .effector.AddExtra(newBuff.effector, true)
    endmethod
    
    public method RemoveBuff takes Animation buf returns nothing
        call .effector.RemoveExtra(buf.effector, true)
    endmethod

    public method AddAnimation takes Animation newAnim returns nothing
        call .effector.AddExtra(newAnim.effector, true)
    endmethod
    
    public method RemoveAnimation takes Animation anim returns nothing
        call .effector.RemoveExtra(anim.effector, true)
    endmethod

    //Gets a Buff object that corresponds to a query. Returns 0
    //(nothing) if the query is not a Buff object.
    public static method GetBuff takes integer id, unit target returns Buff
        local integer INT_BuffIndex = 0

        loop
            exitwhen INT_BuffIndex == Buff.intCountBuff
            if gBUFF[INT_BuffIndex].intId == id and gBUFF[INT_BuffIndex].uTarget == target then
                return gBUFF[INT_BuffIndex]
            endif
            set INT_BuffIndex = INT_BuffIndex + 1
        endloop

        return 0
    endmethod

    //NOTE: The struct methods below are put here to establish connections between Effectors
    //      Buff struct extensions.

    //Deconstructor.
    public method Destroy takes nothing returns nothing
    endmethod

    //------------------------------------------------------------------//
    //Effector Actions

    public Effector effector

    public method Initiate takes Effector e returns nothing
    endmethod

    public method Start takes Effector e returns nothing
    endmethod

    public method Meta takes Effector e returns nothing
    endmethod

    public method End takes Effector e returns nothing
    endmethod    

    public method Terminate takes Effector e returns nothing
    endmethod

    //-------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --

    private integer intBuffIndex
    private static integer intCountBuff = 0

endstruct

//======================================================================================================//
//======================================================================================================//
//======================================================================================================//
//======================================================================================================//

struct PropertyBuff extends Buff

    //------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS B --

    public integer intPropId //AbilityId of the ability that adjusts the target's property.
    public integer intPropLevel //Initial level of the ability.

    public integer intDPropLevel //Difference of the level of the above ability between every
                                 //interval of the effect.

    //PropertyBuff constructor.
    public static method Create takes boolean stack, integer id, integer level, unit source, unit target, real duration, integer interval, integer propId, integer propLevel, integer dPropLevel returns Buff
        local PropertyBuff New = 0
        local PropertyBuff BUFF_Current = Buff.GetBuff(id, target)
        local boolean BOOL_Create = true

        //If the unit already has a Buff of the query's type stack it or replace it.
        if BUFF_Current != 0 then
            //Stack it - by augmenting it - or destroy it so it can be replaced.
            if stack then
                set BOOL_Create = false
                set BUFF_Current.intDPropLevel = BUFF_Current.intDPropLevel + dPropLevel
                call BUFF_Current.StackBuff(level, interval)
                set New = BUFF_Current
            else
                call BUFF_Current.Destroy()
            endif
        endif

        //Create a new Buff if there isn't any yet.
        if BOOL_Create then

            set New = PropertyBuff.allocate()

            //Input values.
            //--PropertyBuff (B) values.
            set New.intPropId = propId
            set New.intPropLevel = propLevel
            set New.intDPropLevel = dPropLevel

            //--Buff (A) values.
            call New.CreateBuff(id, level, source, target, duration, interval)

            //Manage PropertyBuff objects (indexes).
            set New.intPBIndex = PropertyBuff.intCountPB
            set PropertyBuff.inst[PropertyBuff.intCountPB] = New
            set PropertyBuff.intCountPB = PropertyBuff.intCountPB + 1

        endif

        return New
    endmethod

    //PropertyBuff deconstructor.
    public method Destroy takes nothing returns nothing
        //Terminate effect.
        //This line HAS to be put before ALL data - Buff and Buff extension alike - clearing.
        call .effector.Destroy()

        //Nullify values.
        call .DestroyBuff()
        
        //Manage PropertyBuff objects (indexes).
        set PropertyBuff.intCountPB = PropertyBuff.intCountPB - 1
        set PropertyBuff.inst[PropertyBuff.intCountPB].intPBIndex = .intPBIndex
        set PropertyBuff.inst[.intPBIndex] = PropertyBuff.inst[PropertyBuff.intCountPB]
        set PropertyBuff.inst[PropertyBuff.intCountPB] = 0
    endmethod

    //------------------------------------------------------------------//
    //Effector Actions

    public method Initiate takes Effector e returns nothing
        //Add buff.
        call UnitAddAbility(.uTarget, .intId)
        call SetUnitAbilityLevel(.uTarget, .intId, .intLevel)
        //Add property adjuster.
        call UnitAddAbility(.uTarget, .intPropId)
        call SetUnitAbilityLevel(.uTarget, .intPropId, .intPropLevel)
    endmethod

    public method Meta takes Effector e returns nothing
        //Apply inc(de)crementation of property adjuster.
        if .intDPropLevel != 0 then
            set .intPropLevel = .intPropLevel + .intDPropLevel
            call SetUnitAbilityLevel(.uTarget, .intPropId, .intPropLevel)
        endif
    endmethod

    public method Terminate takes Effector e returns nothing
        //Remove buff and property adjuster.
        call UnitRemoveAbility(.uTarget, .intPropId)
        call UnitRemoveAbility(.uTarget, .intId)
    endmethod

    //------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --
    
    private integer intPBIndex
    
    private static PropertyBuff array inst[8190]
    private static integer intCountPB = 0

endstruct

//======================================================================================================//
//======================================================================================================//

struct PauseBuff extends Buff

    //------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS B --

    //PauseBuff constructor.
    public static method Create takes boolean stack, integer id, integer level, unit source, unit target, real duration returns Buff
        local PauseBuff New = 0
        local PauseBuff BUFF_Current = Buff.GetBuff(id, target)
        local boolean BOOL_Create = true

        //If the unit already has a Buff of the query's type stack it or replace it.
        if BUFF_Current != 0 then
            //Stack it - by augmenting it - or destroy it so it can be replaced.
            if stack then
                set BOOL_Create = false
                call BUFF_Current.StackBuff(level, 1)
                set New = BUFF_Current
            else
                call BUFF_Current.Destroy()
            endif
        endif

        //Create a new Buff if there isn't any yet.
        if BOOL_Create then

            set New = PauseBuff.allocate()

            //Input values.
            //--PauseBuff (B) values.
            //(There are none.)

            //--Buff (A) values.
            call New.CreateBuff(id, level, source, target, duration, 1)

            //Manage PauseBuff objects (indexes).
            set New.intPBIndex = PauseBuff.intCountPB
            set PauseBuff.inst[PauseBuff.intCountPB] = New
            set PauseBuff.intCountPB = PauseBuff.intCountPB + 1

        endif

        return New
    endmethod

    //PauseBuff deconstructor.
    public method Destroy takes nothing returns nothing
        //Terminate effect.
        //This line HAS to be put before ALL data - Buff and Buff extension alike - clearing.
        call .effector.Destroy()

        //Nullify values.
        call .DestroyBuff()
        
        //Manage PauseBuff objects (indexes).
        set PauseBuff.intCountPB = PauseBuff.intCountPB - 1
        set PauseBuff.inst[PauseBuff.intCountPB].intPBIndex = .intPBIndex
        set PauseBuff.inst[.intPBIndex] = PauseBuff.inst[PauseBuff.intCountPB]
        set PauseBuff.inst[PauseBuff.intCountPB] = 0
    endmethod
    
    private method IsNotStillPaused takes nothing returns boolean
        local integer INT_PBIndex = 0

        loop
            exitwhen INT_PBIndex == PauseBuff.intCountPB
            if PauseBuff.inst[INT_PBIndex].intPBIndex != .intPBIndex and PauseBuff.inst[INT_PBIndex].uTarget == .uTarget then
                return false
            endif
            set INT_PBIndex = INT_PBIndex + 1
        endloop
        
        return true
    endmethod

    //------------------------------------------------------------------//
    //Effector Actions

    public method Initiate takes Effector e returns nothing
        //Add buff.
        call UnitAddAbility(.uTarget, .intId)
        call SetUnitAbilityLevel(.uTarget, .intId, .intLevel)
        //Pause target.
        call PauseUnit(.uTarget, true)
    endmethod

    public method Terminate takes Effector e returns nothing
        //Unpause the target if it not paused by another PauseBuff.
        if .IsNotStillPaused() then
            call PauseUnit(.uTarget, false)
        endif
        //Remove buff.
        call UnitRemoveAbility(.uTarget, .intId)
    endmethod

    //------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --
    
    private integer intPBIndex
    
    private static PauseBuff array inst[8190]
    private static integer intCountPB = 0

endstruct

//======================================================================================================//
//======================================================================================================//

struct HideBuff extends Buff

    //------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS B --

    //HideBuff constructor.
    public static method Create takes boolean stack, integer id, integer level, unit source, unit target, real duration returns Buff
        local HideBuff New = 0
        local HideBuff BUFF_Current = Buff.GetBuff(id, target)
        local boolean BOOL_Create = true

        //If the unit already has a Buff of the query's type stack it or replace it.
        if BUFF_Current != 0 then
            //Stack it - by augmenting it - or destroy it so it can be replaced.
            if stack then
                set BOOL_Create = false
                call BUFF_Current.StackBuff(level, 1)
                set New = BUFF_Current
            else
                call BUFF_Current.Destroy()
            endif
        endif

        //Create a new Buff if there isn't any yet.
        if BOOL_Create then

            set New = HideBuff.allocate()

            //Input values.
            //--HideBuff (B) values.
            //(There are none.)

            //--Buff (A) values.
            call New.CreateBuff(id, level, source, target, duration, 1)

            //Manage HideBuff objects (indexes).
            set New.intPBIndex = HideBuff.intCountPB
            set HideBuff.inst[HideBuff.intCountPB] = New
            set HideBuff.intCountPB = HideBuff.intCountPB + 1

        endif

        return New
    endmethod

    //HideBuff deconstructor.
    public method Destroy takes nothing returns nothing
        //Terminate effect.
        //This line HAS to be put before ALL data - Buff and Buff extension alike - clearing.
        call .effector.Destroy()

        //Nullify values.
        call .DestroyBuff()
        
        //Manage HideBuff objects (indexes).
        set HideBuff.intCountPB = HideBuff.intCountPB - 1
        set HideBuff.inst[HideBuff.intCountPB].intPBIndex = .intPBIndex
        set HideBuff.inst[.intPBIndex] = HideBuff.inst[HideBuff.intCountPB]
        set HideBuff.inst[HideBuff.intCountPB] = 0
    endmethod

    private method IsNotStillHidden takes nothing returns boolean
        local integer INT_PBIndex = 0

        loop
            exitwhen INT_PBIndex == HideBuff.intCountPB
            if HideBuff.inst[INT_PBIndex].intPBIndex != .intPBIndex and HideBuff.inst[INT_PBIndex].uTarget == .uTarget then
                return false
            endif
            set INT_PBIndex = INT_PBIndex + 1
        endloop

        return true
    endmethod

    //------------------------------------------------------------------//
    //Effector Actions

    public method Initiate takes Effector e returns nothing
        //Add buff.
        call UnitAddAbility(.uTarget, .intId)
        call SetUnitAbilityLevel(.uTarget, .intId, .intLevel)
        //Ownership target.
        call ShowUnit(.uTarget, false)
    endmethod

    public method Terminate takes Effector e returns nothing
        //Remove buff and unOwnership.
        if .IsNotStillHidden() then
            call ShowUnit(.uTarget, true)
        endif
        call UnitRemoveAbility(.uTarget, .intId)
    endmethod

    //------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --
    
    private integer intPBIndex
    
    private static HideBuff array inst[8190]
    private static integer intCountPB = 0

endstruct

//======================================================================================================//
//======================================================================================================//

globals
    private constant boolean gBOOL_ChangeColor = true //Change the color of the ownership-changed unit
                                                       //to the player color of the new player.
endglobals

struct OwnershipBuff extends Buff

    //------------------------------------------------------------------//
    //          -- SYSTEM FUNCTIONS B --

    public integer intControl

    public player pOriginal
    public player pSub

    //OwnershipBuff constructor.
    public static method Create takes boolean stack, integer id, integer level, unit source, unit target, real duration, integer control, player sub returns Buff
        local OwnershipBuff New = 0
        local OwnershipBuff OB_Current = OwnershipBuff.GetOwnership(target)
        local boolean BOOL_Create = true

        //If the unit is already dominated, ascertain if the incoming control is more powerful than the current.
        if OB_Current != 0 then
            //If the incoming control is more powerful than the current, effect it over the current.
            if control >= OB_Current.intControl then
                //If the incoming control is the same as the current and they stack, stack them; else, destroy the current
                //to allow the incoming to be effected.
                if stack and OB_Current.intId == id then
                    call OB_Current.StackBuff(level, 1)
                    set New = OB_Current
                    set BOOL_Create = false
                else
                    call OB_Current.Destroy()
                endif
            else
                set BOOL_Create = false
            endif
        endif

        if BOOL_Create then
            set New = OwnershipBuff.allocate()
            //Input values.
            //--OwnershipBuff (B) values.
            set New.intControl = control
            set New.pOriginal = GetOwningPlayer(target)
            set New.pSub = sub
        
            //--Buff (A) values.
            call New.CreateBuff(id, level, source, target, duration, 1)

            //Manage OwnershipBuff objects (indexes).
            set New.intOBIndex = OwnershipBuff.intCountOB
            set OwnershipBuff.inst[OwnershipBuff.intCountOB] = New
            set OwnershipBuff.intCountOB = OwnershipBuff.intCountOB + 1
        endif

        return New
    endmethod

    //OwnershipBuff deconstructor.
    public method Destroy takes nothing returns nothing
        //Terminate effect.
        //This line HAS to be put before ALL data - Buff and Buff extension alike - clearing.
        call .effector.Destroy()

        //Nullify values.
        set .pOriginal = null
        set .pSub = null

        call .DestroyBuff()

        //Manage OwnershipBuff objects (indexes).
        set OwnershipBuff.intCountOB = OwnershipBuff.intCountOB - 1
        set OwnershipBuff.inst[OwnershipBuff.intCountOB].intOBIndex = .intOBIndex
        set OwnershipBuff.inst[.intOBIndex] = OwnershipBuff.inst[OwnershipBuff.intCountOB]
        set OwnershipBuff.inst[OwnershipBuff.intCountOB] = 0
    endmethod

    private static method GetOwnership takes unit target returns OwnershipBuff
        local integer INT_OBIndex = 0

        loop
            exitwhen INT_OBIndex == OwnershipBuff.intCountOB
            if OwnershipBuff.inst[INT_OBIndex].uTarget == target then
                return OwnershipBuff.inst[INT_OBIndex]
            endif
            set INT_OBIndex = INT_OBIndex + 1
        endloop

        return 0
    endmethod

    //------------------------------------------------------------------//
    //Effector Actions

    public method Initiate takes Effector e returns nothing
        //Add buff.
        call UnitAddAbility(.uTarget, .intId)
        call SetUnitAbilityLevel(.uTarget, .intId, .intLevel)
        //Change owner.
        call SetUnitOwner(.uTarget, .pSub, gBOOL_ChangeColor)
    endmethod

    public method Terminate takes Effector e returns nothing
        //Remove buff and reset owner.
        call SetUnitOwner(.uTarget, .pOriginal, gBOOL_ChangeColor)
        call UnitRemoveAbility(.uTarget, .intId)
    endmethod

    //------------------------------------------------------------------//
    //          -- STRUCT FUNCTIONS --

    private integer intOBIndex

    private static OwnershipBuff array inst[8190]
    private static integer intCountOB = 0

endstruct

//======================================================================================================//
//======================================================================================================//

endlibrary
10-26-2008, 03:06 PM#2
tamisrah
Making units dodge is easy, you just add an ability based off evasion, but making a unit miss on attack needs in my opinion a damage detection system.

Regarding your design I would suggest to rather make small moduls: one doing buffs, one doing effects and one doing the damage stuff. Then you can use delegate/extend to put it together.