- Joined
- Sep 9, 2007
- Messages
- 6,759
library CustomAura requires GroupUtils, Table optional CABuff
globals
private constant real PERIOD = 0.0375
endglobals
private interface eventHandler
method onLoop takes nothing returns nothing defaults nothing
method onRegister takes unit theUnit returns nothing defaults nothing
method onUnregister takes unit theUnit returns nothing defaults nothing
method onStart takes nothing returns nothing defaults nothing
method onEnd takes nothing returns nothing defaults nothing
method getRadius takes nothing returns real defaults 0.
method unitFilter takes unit theUnit returns boolean defaults true
endinterface
struct CustomAura extends eventHandler
public unit theUnit = null
private group affect = null
private group last = null
public boolean isAlive = true
public boolean isPaused = false
private boolean hasStarted = false
//: == ---------------------------- ----------------------------
//: # Indexing & Structstuff
//: == ---------------------------- ----------------------------
private integer index = 0
private static thistype curInstance = 0
private static timer t = null
private static integer a = 0
private static thistype array i
implement TableMacros
public static method create takes unit theUnit returns thistype
local thistype this = thistype.allocate()
set .affect = NewGroup()
set .last = NewGroup()
set .theUnit = theUnit
set .index = thistype.a
set thistype.i[.index] = this
set thistype.a = thistype.a +1
if thistype.a == 1 then
call TimerStart(thistype.t, PERIOD, true, function thistype.run)
endif
return this
endmethod
public method isUnitAffected takes unit theUnit returns boolean
return IsUnitInGroup(theUnit, .affect)
endmethod
public method affectUnit takes unit theUnit returns nothing
call GroupAddUnit(.affect, theUnit)
if not IsUnitInGroup(theUnit, .last) then
call .onRegister(theUnit)
endif
endmethod
public method unaffectUnit takes unit theUnit returns nothing
if not IsUnitInGroup(theUnit, .affect) then
call GroupRemoveUnit(.last, theUnit)
call .onUnregister(theUnit)
endif
endmethod
private static method unaffectAllEnum takes nothing returns nothing
local thistype this = thistype.curInstance
call .unaffectUnit(GetEnumUnit())
endmethod
public method unaffectAll takes nothing returns nothing
set thistype.curInstance = this
call GroupClear(.affect)
call ForGroup(.last, function thistype.unaffectAllEnum)
endmethod
private static method tryRegister takes nothing returns boolean
local thistype this = thistype.curInstance
local unit u = GetFilterUnit()
if .unitFilter(u) then
call .affectUnit(u)
endif
set u = null
return false
endmethod
private static method tryUnregister takes nothing returns nothing
local thistype this = thistype.curInstance
local unit u = GetEnumUnit()
call .unaffectUnit(u)
set u = null
endmethod
private method move takes nothing returns nothing
call .onLoop()
if .isPaused then
return
endif
if not .hasStarted then
set .hasStarted = true
call .onStart()
endif
call GroupAddGroup(.affect, .last)
call GroupClear(.affect)
call GroupEnumUnitsInRange(.affect, GetUnitX(.theUnit), GetUnitY(.theUnit), .getRadius(), Condition(function thistype.tryRegister))
call ForGroup(.last, function thistype.tryUnregister)
endmethod
private static method onInit takes nothing returns nothing
set thistype.t = CreateTimer()
endmethod
public static method run takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= thistype.a
if thistype.i[i].isAlive and thistype.i[i] != 0 then
set thistype.curInstance = thistype.i[i]
call thistype.i[i].move()
else
if thistype.i[i] != 0 then
call thistype.i[i].destroy()
endif
set thistype.a = thistype.a -1
set thistype.i[i] = thistype.i[thistype.a]
set thistype.i[i].index = i
set i = i -1
endif
set i = i +1
endloop
if thistype.a == 0 then
call PauseTimer(thistype.t)
endif
endmethod
private method onDestroy takes nothing returns nothing
call GroupClear(.affect)
call ForGroup(.last, function thistype.tryUnregister)
call ReleaseGroup(.affect)
call ReleaseGroup(.last)
call .onEnd()
endmethod
endstruct
endlibrary
library CABuff initializer init requires CustomDummy
globals
private unit CASTER = null
endglobals
private function init takes nothing returns nothing
set CASTER = CreateDummy(Player(PLAYER_NEUTRAL_PASSIVE), 0., 0.)
call UnitAddAbility(CASTER, 'Aloc')
endfunction
module CABuff
private integer theSpell = 0
private integer theLevel = 0
private integer theBuff = 0
public method setBuff takes integer theSpell, integer theLevel, integer theBuff returns nothing
set .theSpell = theSpell
set .theLevel = theLevel
set .theBuff = theBuff
endmethod
public method addBuff takes unit theUnit returns nothing
call SetUnitX(CASTER, GetUnitX(theUnit))
call SetUnitY(CASTER, GetUnitY(theUnit))
call SetUnitOwner(CASTER, GetOwningPlayer(.theUnit), false)
call UnitAddAbility(CASTER, .theSpell)
call SetUnitAbilityLevel(CASTER, .theSpell, .theLevel)
call IssueTargetOrder(CASTER, "slow", theUnit)
call UnitRemoveAbility(CASTER, .theSpell)
endmethod
public method removeBuff takes unit theUnit returns nothing
call UnitRemoveAbility(theUnit, .theBuff)
endmethod
endmodule
endlibrary
library CABonus
module CABonus
public integer hp = 0
public integer mp = 0
public integer amr = 0
public integer dmg = 0
public integer as = 0
public integer mr = 0
public integer lf = 0
public integer str = 0
public integer agi = 0
public integer int = 0
public integer sr = 0
public method addBonus takes unit theUnit returns nothing
if .hp != 0 then
call AddUnitBonus(theUnit, BONUS_LIFE, .hp)
endif
if .mp != 0 then
call AddUnitBonus(theUnit, BONUS_MANA, .mp)
endif
if .amr != 0 then
call AddUnitBonus(theUnit, BONUS_ARMOR, .amr)
endif
if .dmg != 0 then
call AddUnitBonus(theUnit, BONUS_DAMAGE, .dmg)
endif
if .as != 0 then
call AddUnitBonus(theUnit, BONUS_ATTACK_SPEED, .as)
endif
if .mr != 0 then
call AddUnitBonus(theUnit, BONUS_MANA_REGEN_PERCENT, .mr)
endif
if .lf != 0 then
call AddUnitBonus(theUnit, BONUS_LIFE_REGEN, .lf)
endif
if .str != 0 then
call AddUnitBonus(theUnit, BONUS_STRENGTH, .str)
endif
if .agi != 0 then
call AddUnitBonus(theUnit, BONUS_AGILITY, .agi)
endif
if .int != 0 then
call AddUnitBonus(theUnit, BONUS_INTELLIGENCE, .int)
endif
if .sr!= 0 then
call AddUnitBonus(theUnit, BONUS_SIGHT_RANGE, .sr)
endif
endmethod
public method removeBonus takes unit theUnit returns nothing
if .hp != 0 then
call AddUnitBonus(theUnit, BONUS_LIFE, -.hp)
endif
if .mp != 0 then
call AddUnitBonus(theUnit, BONUS_MANA, -.mp)
endif
if .amr != 0 then
call AddUnitBonus(theUnit, BONUS_ARMOR, -.amr)
endif
if .dmg != 0 then
call AddUnitBonus(theUnit, BONUS_DAMAGE, -.dmg)
endif
if .as != 0 then
call AddUnitBonus(theUnit, BONUS_ATTACK_SPEED, -.as)
endif
if .mr != 0 then
call AddUnitBonus(theUnit, BONUS_MANA_REGEN_PERCENT, -.mr)
endif
if .lf != 0 then
call AddUnitBonus(theUnit, BONUS_LIFE_REGEN, -.lf)
endif
if .str != 0 then
call AddUnitBonus(theUnit, BONUS_STRENGTH, -.str)
endif
if .agi != 0 then
call AddUnitBonus(theUnit, BONUS_AGILITY, -.agi)
endif
if .int != 0 then
call AddUnitBonus(theUnit, BONUS_INTELLIGENCE, -.int)
endif
if .sr!= 0 then
call AddUnitBonus(theUnit, BONUS_SIGHT_RANGE, -.sr)
endif
endmethod
endmodule
endlibrary
library ExampleAura requires CustomAura
globals
private constant integer BUFF_ID = 'buf1'
private constant integer BUFF_SPELL = 'spl1'
endglobals
private struct aura extends CustomAura
implement optional CABuff
implement optional CABonus
private static method new takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer i = GetHandleId(u)
local integer l = GetUnitAbilityLevel(u, GetLearnedSkill())
local thistype this = thistype.load(i)
if this == 0 then
set this = thistype.create(u)
set .ID = i
call .save()
else
call .unaffectAll()
endif
call .setBuff(BUFF_SPELL, l, BUFF_ID)
set .dmg = - l * 2
return false
endmethod
method onRegister takes unit theUnit returns nothing
call .addBuff(theUnit)
call .addBonus(theUnit)
endmethod
method onUnregister takes unit theUnit returns nothing
call .removeBuff(theUnit)
call .removeBonus(theUnit)
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.405
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
call TriggerAddCondition(t, Condition(function thistype.new))
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i +1
endloop
endmethod
endstruct
endlibrary
public method addBuff takes unit theUnit returns nothing
call SetUnitX(CASTER, GetUnitX(theUnit))
call SetUnitY(CASTER, GetUnitY(theUnit))
call SetUnitOwner(CASTER, GetOwningPlayer(.theUnit), false)
call UnitAddAbility(CASTER, .theSpell)
call SetUnitAbilityLevel(CASTER, .theSpell, .theLevel)
call IssueTargetOrder(CASTER, "slow", theUnit)
call UnitRemoveAbility(CASTER, .theSpell)
endmethod
You only need to remove the implement CABuff and implement CABonus to remove it (aswell as set .dmg = X and call .setBuff()). I wanted to give an example how to use the addons.but few things bother me:
first, you mention that CABuff, CustomDummy, and CABonus is optional, yet your example shows that those are required for the aura to be working...
could you make an example of the aura not using those optional library?
or you could just combine it into one single library?
You mean slow? Well I could change it, I don't know whether I should. Please also check my signature for the download link so we could maybe move the discussion to there.this is on your CABuff library, there is a hardcoded value on there that you might want to change that.
struct CustomAura extends eventHandler
public unit theUnit = null
private group affect = null
private group last = null
public boolean isAlive = true
public boolean isPaused = false
private boolean hasStarted = false
//: == ---------------------------- ----------------------------
//: # Indexing & Structstuff
//: == ---------------------------- ----------------------------
private integer index = 0
private static thistype curInstance = 0
private static timer t = null
private static integer a = 0
private static thistype array i
implement TableMacros
public method isUnitAffected takes unit theUnit returns boolean
return IsUnitInGroup(theUnit, .affect)
endmethod
public method affectUnit takes unit theUnit returns nothing
call GroupAddUnit(.affect, theUnit)
if not IsUnitInGroup(theUnit, .last) then
call .onRegister(theUnit)
endif
endmethod
public method unaffectUnit takes unit theUnit returns nothing
if not IsUnitInGroup(theUnit, .affect) then
call GroupRemoveUnit(.last, theUnit)
call .onUnregister(theUnit)
endif
endmethod
private static method unaffectAllEnum takes nothing returns nothing
local thistype this = thistype.curInstance
call .unaffectUnit(GetEnumUnit())
endmethod
public method unaffectAll takes nothing returns nothing
set thistype.curInstance = this
call GroupClear(.affect)
call ForGroup(.last, function thistype.unaffectAllEnum)
endmethod
private static method tryRegister takes nothing returns boolean
local thistype this = thistype.curInstance
local unit u = GetFilterUnit()
if .unitFilter(u) then
call .affectUnit(u)
endif
set u = null
return false
endmethod
private static method tryUnregister takes nothing returns nothing
local thistype this = thistype.curInstance
local unit u = GetEnumUnit()
call .unaffectUnit(u)
set u = null
endmethod
private method move takes nothing returns nothing
call .onLoop()
if .isPaused then
return
endif
if not .hasStarted then
set .hasStarted = true
call .onStart()
endif
call GroupAddGroup(.affect, .last)
call GroupClear(.affect)
call GroupEnumUnitsInRange(.affect, GetUnitX(.theUnit), GetUnitY(.theUnit), .getRadius(), Condition(function thistype.tryRegister))
call ForGroup(.last, function thistype.tryUnregister)
endmethod
public static method run takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= thistype.a
if thistype.i[i].isAlive and thistype.i[i] != 0 then
set thistype.curInstance = thistype.i[i]
call thistype.i[i].move()
else
if thistype.i[i] != 0 then
call thistype.i[i].destroy()
endif
set thistype.a = thistype.a -1
set thistype.i[i] = thistype.i[thistype.a]
set thistype.i[i].index = i
set i = i -1
endif
set i = i +1
endloop
if thistype.a == 0 then
call PauseTimer(thistype.t)
endif
endmethod
public static method create takes unit theUnit returns thistype
local thistype this = thistype.allocate()
set .affect = NewGroup()
set .last = NewGroup()
set .theUnit = theUnit
set .index = thistype.a
set thistype.i[.index] = this
set thistype.a = thistype.a +1
if thistype.a == 1 then
call TimerStart(thistype.t, PERIOD, true, function thistype.run)
endif
return this
endmethod
private static method onInit takes nothing returns nothing
set thistype.t = CreateTimer()
endmethod
private method onDestroy takes nothing returns nothing
call GroupClear(.affect)
call ForGroup(.last, function thistype.tryUnregister)
call ReleaseGroup(.affect)
call ReleaseGroup(.last)
call .onEnd()
endmethod
endstruct