| 10-26-2008, 12:47 PM | #1 |
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 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 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 |
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. |
