Moderator
M
Moderator
04:29, 20th Oct 2012
Magtheridon96: Approved.
Magtheridon96: Approved.
/*
Drain System v1.02
by Adiktuz
A system that handles draining abilities
Features:
->Can have a simultaneous life and mana drain
->Can have different values for the drain and the damage dealt to the drained unit
->Can set the attacktype and damagetype of the drain
How to use:
->Drain.methodName(parameters)
Methods that can be used for drains
life(unit u1, unit u2, real lifedrain, real duration, real breakpoint, string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
mana(unit u1, unit u2, real manadrain, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
lifeMana(unit u1, unit u2, real lifedrain, real manadrain, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
lifeEx(unit u1, unit u2, real lifedrain, real lifedamage, real duration, real breakpoint, string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
manaEx(unit u1, unit u2, real manadrain, real manadamage, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
lifeManaEx(unit u1, unit u2, real lifedrain, real lifedamage, real manadrain, real manadamage, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey)
Parameters:
unit u1 -> the caster
unit u2 -> the target
real lifedrain -> the amount of life added to u1 per second
real lifedamage -> the amount of life damage to u2 per second
real manadrain -> the amount of mana added to u1 per second
real manadamage -> the amount of mana damage to u2 per second
real duration -> the maximum duration of the drain
real breakpoint -> the maximum range of the drain
string lfx -> the string path of the lightning effect
string e1 -> the special effect to be attached to u1 for the duration of the drain
string e2 -> the special effect to be attached to u2 for the duration of the drain
string apoint1 -> the attachment point of e1
string apoint2 -> the attachment point of e2
attacktype at -> the attack type of the life damage
damagetype dt -> the damage type of the life damage
Note: all of these methods return the instance of the drain so you can save it in a variable
To forcibly stop a drain:
remove(integer eventtype)
integer eventtype -> determines if the drain is broken,ended or target died
-> if 1, it is broken
-> if 2, it ended
-> if 3, target died
-> use any other number if no event response should be run
Extra/Interface/Events:
registerUpdateEvent(integer eventkey, code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain with the
same eventkey as the one registered is updated (every T32_PERIOD)
registerEndEvent(integer eventkey, code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain with the
same eventkey as the one registered ends (duration ends)
registerBreakEvent(integer eventkey, code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain with the
same eventkey as the one registered is broken (the breakpoint is reached)
registerDeathEvent(integer eventkey, code ToDo) returns nothing
-> allows you to register an action that will be run whenever target unit dies
registerSelfDeathEvent(integer eventkey, code ToDo) returns nothing
-> allows you to register an action that will be run whenever the casting unit dies
NOTE: If you're going to use the next five functions/methods, make sure you set the
corresponding boolean at the globals block to true
registerGlobalUpdateEvent(code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain
is updated (every T32_PERIOD)
registerGlobalEndEvent(code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain ends
registerGlobalBreakEvent(code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain breaks
registerGlobalDeathEvent(code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain target dies
registerGlobalSelfDeathEvent(code ToDo) returns nothing
-> allows you to register an action that will be run whenever a drain user dies
To obtain the instance that run the events:
getTriggeringDrain()
See the example triggers for a better idea on how to use it
*/
library DrainSystem requires LightningSystem
globals
//Set to true if you're gonna use the global update event handler
private constant boolean USE_GLOBAL_UPDATE = false
//Set to true if you're gonna use the global end event handler
private constant boolean USE_GLOBAL_END = false
//Set to true if you're gonna use the global break event handler
private constant boolean USE_GLOBAL_BREAK = false
//Set to true if you're gonna use the global death event handler
private constant boolean USE_GLOBAL_DEATH = false
//Set to true if you're gonna use the global selfdeath event handler
private constant boolean USE_GLOBAL_SELFDEATH = false
//hbase eight of lightning for normal units
private constant real zbuffer = 50.0
//base height of lightning for flying units
//negative because flying units seem to have a default positive buffer for the lightning z
private constant real flyzbuffer = -100.0
private Table UpdateTable
private Table EndTable
private Table BreakTable
private Table DeathTable
private Table SelfDeathTable
private trigger globalUpdate
private trigger globalEnd
private trigger globalBreak
private trigger globalDeath
private trigger globalSelfDeath
endglobals
private module init
static method onInit takes nothing returns nothing
set UpdateTable = Table.create()
set EndTable = Table.create()
set BreakTable = Table.create()
set DeathTable = Table.create()
set SelfDeathTable = Table.create()
static if USE_GLOBAL_UPDATE then
set globalUpdate = CreateTrigger()
endif
static if USE_GLOBAL_END then
set globalEnd = CreateTrigger()
endif
static if USE_GLOBAL_BREAK then
set globalBreak = CreateTrigger()
endif
static if USE_GLOBAL_DEATH then
set globalDeath = CreateTrigger()
endif
static if USE_GLOBAL_SELFDEATH then
set globalSelfDeath = CreateTrigger()
endif
endmethod
endmodule
struct Drain extends array
Lightning light
unit u1
unit u2
real duration
real lifedrain
real manadrain
real lifedamage
real manadamage
real breakpoint
effect e1
effect e2
integer eventkey
string apoint1
string apoint2
attacktype at
damagetype dt
boolean isLife
boolean isMana
static thistype instance
private static integer instanceCount = 0
private static thistype recycle = 0
private thistype recycleNext
static method registerSelfDeathEvent takes integer eventkey, code toDo returns nothing
if not SelfDeathTable.handle.has(eventkey) then
set SelfDeathTable.trigger[eventkey] = CreateTrigger()
endif
call TriggerAddCondition(SelfDeathTable.trigger[eventkey],Filter(toDo))
endmethod
static method registerDeathEvent takes integer eventkey, code toDo returns nothing
if not DeathTable.handle.has(eventkey) then
set DeathTable.trigger[eventkey] = CreateTrigger()
endif
call TriggerAddCondition(DeathTable.trigger[eventkey],Filter(toDo))
endmethod
static method registerEndEvent takes integer eventkey, code toDo returns nothing
if not EndTable.handle.has(eventkey) then
set EndTable.trigger[eventkey] = CreateTrigger()
endif
call TriggerAddCondition(EndTable.trigger[eventkey],Filter(toDo))
endmethod
static method registerBreakEvent takes integer eventkey, code toDo returns nothing
if not BreakTable.handle.has(eventkey) then
set BreakTable.trigger[eventkey] = CreateTrigger()
endif
call TriggerAddCondition(BreakTable.trigger[eventkey],Filter(toDo))
endmethod
static method registerUpdateEvent takes integer eventkey, code toDo returns nothing
if not UpdateTable.handle.has(eventkey) then
set UpdateTable.trigger[eventkey] = CreateTrigger()
endif
call TriggerAddCondition(UpdateTable.trigger[eventkey],Filter(toDo))
endmethod
static method registerGlobalEndEvent takes code toDo returns nothing
call TriggerAddCondition(globalEnd,Filter(toDo))
endmethod
static method registerGlobalUpdateEvent takes code toDo returns nothing
call TriggerAddCondition(globalUpdate,Filter(toDo))
endmethod
static method registerGlobalBreakEvent takes code toDo returns nothing
call TriggerAddCondition(globalBreak,Filter(toDo))
endmethod
static method registerGlobalDeathEvent takes code toDo returns nothing
call TriggerAddCondition(globalDeath,Filter(toDo))
endmethod
static method registerGlobalSelfDeathEvent takes code toDo returns nothing
call TriggerAddCondition(globalSelfDeath,Filter(toDo))
endmethod
static method getZ takes unit u returns real
if IsUnitType(u,UNIT_TYPE_FLYING) then
return flyzbuffer
endif
return zbuffer
endmethod
static method getTriggeringDrain takes nothing returns thistype
return instance
endmethod
method remove takes integer eventtype returns nothing
call this.light.remove()
call DestroyEffect(this.e1)
call DestroyEffect(this.e2)
set instance = this
if eventtype == 1 then
if BreakTable.handle.has(this.eventkey) then
call TriggerEvaluate(BreakTable.trigger[this.eventkey])
endif
static if USE_GLOBAL_BREAK then
call TriggerEvaluate(globalBreak)
endif
elseif eventtype == 2 then
if EndTable.handle.has(this.eventkey) then
call TriggerEvaluate(EndTable.trigger[this.eventkey])
endif
static if USE_GLOBAL_END then
call TriggerEvaluate(globalEnd)
endif
elseif eventtype == 3 then
if DeathTable.handle.has(this.eventkey) then
call TriggerEvaluate(DeathTable.trigger[this.eventkey])
endif
static if USE_GLOBAL_DEATH then
call TriggerEvaluate(globalDeath)
endif
elseif eventtype == 4 then
if SelfDeathTable.handle.has(this.eventkey) then
call TriggerEvaluate(SelfDeathTable.trigger[this.eventkey])
endif
static if USE_GLOBAL_SELFDEATH then
call TriggerEvaluate(globalSelfDeath)
endif
endif
call this.stopPeriodic()
set .recycleNext=recycle
set recycle=this
endmethod
static method new takes nothing returns thistype
local thistype this = recycle
if (this == 0) then
set instanceCount = instanceCount + 1
return instanceCount
endif
set recycle = recycle.recycleNext
return this
endmethod
method periodic takes nothing returns nothing
set this.duration = this.duration - T32_PERIOD
set instance = this
if UpdateTable.handle.has(this.eventkey) then
call TriggerEvaluate(UpdateTable.trigger[this.eventkey])
endif
static if USE_GLOBAL_UPDATE then
call TriggerEvaluate(globalUpdate)
endif
if this.isLife then
call SetWidgetLife(this.u1,GetWidgetLife(this.u1) + this.lifedrain)
call UnitDamageTarget(this.u1,this.u2,this.lifedamage,false,false,this.at,this.dt,null)
endif
if this.isMana then
call SetUnitState(this.u1, UNIT_STATE_MANA, GetUnitState(this.u1,UNIT_STATE_MANA) + this.manadrain)
call SetUnitState(this.u2, UNIT_STATE_MANA, GetUnitState(this.u2,UNIT_STATE_MANA) - this.manadamage)
endif
if this.duration <= 0.0 then
call this.remove(2)
elseif ((GetUnitX(this.u1) - GetUnitX(this.u2))*(GetUnitX(this.u1) - GetUnitX(this.u2)) + (GetUnitY(this.u1) - GetUnitY(this.u2))*(GetUnitY(this.u1) - GetUnitY(this.u2))) > this.breakpoint then
call this.remove(1)
elseif GetWidgetLife(this.u2) < .405 or IsUnitType(this.u2,UNIT_TYPE_DEAD) then
call this.remove(3)
elseif GetWidgetLife(this.u1) < .405 or IsUnitType(this.u1,UNIT_TYPE_DEAD) then
call this.remove(4)
endif
endmethod
implement T32x
static method life takes unit u1, unit u2, real lifedrain, real duration, real breakpoint, string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = lifedrain*T32_PERIOD
set this.manadrain = 0.0
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.at = at
set this.dt = dt
set this.lifedamage = this.lifedrain
set this.manadamage = this.manadrain
set this.isLife = true
set this.isMana = false
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
static method mana takes unit u1, unit u2, real manadrain, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = 0.0
set this.manadrain = manadrain*T32_PERIOD
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.at = at
set this.dt = dt
set this.lifedamage = this.lifedrain
set this.manadamage = this.manadrain
set this.isLife = false
set this.isMana = true
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
static method lifeMana takes unit u1, unit u2, real lifedrain, real manadrain, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = lifedrain*T32_PERIOD
set this.manadrain = manadrain*T32_PERIOD
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.lifedamage = this.lifedrain
set this.manadamage = this.manadrain
set this.isLife = true
set this.isMana = true
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
static method lifeEx takes unit u1, unit u2, real lifedrain, real lifedamage, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = lifedrain*T32_PERIOD
set this.manadrain = 0.0
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.at = at
set this.dt = dt
set this.lifedamage = lifedamage*T32_PERIOD
set this.manadamage = this.manadrain
set this.isLife = true
set this.isMana = false
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
static method manaEx takes unit u1, unit u2, real manadrain, real manadamage, real duration,real breakpoint,string lfx, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = 0.0
set this.manadrain = manadrain*T32_PERIOD
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.at = at
set this.dt = dt
set this.lifedamage = this.lifedrain
set this.manadamage = manadamage*T32_PERIOD
set this.isLife = false
set this.isMana = true
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
static method lifeManaEx takes unit u1, unit u2, real lifedrain, real lifedamage, real manadrain, real manadamage,real breakpoint,string lfx, real duration, string e1, string e2, string apoint1, string apoint2, attacktype at, damagetype dt,integer eventkey returns thistype
local thistype this = thistype.new()
set this.u1 = u1
set this.u2 = u2
set this.lifedrain = lifedrain*T32_PERIOD
set this.manadrain = manadrain*T32_PERIOD
set this.duration = duration
set this.breakpoint = breakpoint*breakpoint
set this.eventkey = eventkey
set this.e1 = AddSpecialEffectTarget(e1,u1,apoint1)
set this.e2 = AddSpecialEffectTarget(e2,u2,apoint2)
set this.lifedamage = lifedamage*T32_PERIOD
set this.manadamage = manadamage*T32_PERIOD
set this.isLife = true
set this.isMana = true
set this.light = Lightning.unitToUnit(u1,u2,thistype.getZ(u1),thistype.getZ(u2),false,0.0,lfx,this.eventkey)
call this.startPeriodic()
return this
endmethod
implement init
endstruct
endlibrary
library FoD initializer init requires DrainSystem
globals
private constant integer abil = 'A000'
private constant string fx = "Abilities\\Spells\\Other\\SoulBurn\\SoulBurnbuff.mdl"
private constant string fx2 = "Abilities\\Spells\\Human\\InnerFire\\InnerFireTarget.mdl"
private constant string drainfx = "AFOD"
private constant string point = "overhead"
private constant string point2 = "overhead"
private unit u = null
endglobals
private function drain takes nothing returns nothing
set u = GetTriggerUnit()
call Drain.lifeEx(u,GetSpellTargetUnit(),GetUnitAbilityLevel(u,abil)*GetHeroStr(u,true),GetUnitAbilityLevel(u,abil)*GetHeroInt(u,true), 5.0,800.0,drainfx,fx2,fx,point2,point,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DIVINE,abil)
endfunction
private function break takes nothing returns nothing
call BJDebugMsg("Finger of death was broken.")
endfunction
private function end takes nothing returns nothing
call SetUnitState(Drain.getTriggeringDrain().u2,UNIT_STATE_MANA,0.0)
endfunction
private function init takes nothing returns nothing
call RegisterSpellEffectEvent(abil,function drain)
call Drain.registerBreakEvent(abil,function break)
call Drain.registerEndEvent(abil,function end)
endfunction
endlibrary
library ForkedDrain initializer init requires DrainSystem
globals
private constant integer abil = 'A001'
private constant string fx = "Abilities\\Spells\\Other\\Drain\\DrainTarget.mdl"
private constant string fx2 = "Abilities\\Spells\\Other\\Drain\\DrainTarget.mdl"
private constant string drainfx = "DRAB"
private constant string point = "overhead"
private constant string point2 = "overhead"
private constant real radius = 150.0
private constant integer TARGETS = 2
private integer maxtargs
private integer curtargs = 1
private unit u = null
private unit tmpU = null
private unit tmpUo = null
private group tmpGroup = CreateGroup()
private integer level
endglobals
private function filter takes nothing returns boolean
set tmpU = GetFilterUnit()
if IsUnitEnemy(tmpU,GetOwningPlayer(u)) and GetWidgetLife(tmpU) > .405 and (not IsUnitType(tmpU,UNIT_TYPE_STRUCTURE)) and curtargs < maxtargs and tmpU != tmpUo then
call Drain.life(u,tmpU,level*20,5.0,800.0,drainfx,fx2,fx,point2,point,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DIVINE,abil)
set curtargs = curtargs + 1
endif
return false
endfunction
private function drain takes nothing returns nothing
set u = GetTriggerUnit()
set level = GetUnitAbilityLevel(u,abil)
set tmpUo = GetSpellTargetUnit()
call Drain.life(u,tmpUo,level*20,5.0,800.0,drainfx,fx2,fx,point2,point,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DIVINE,abil)
set maxtargs = TARGETS*level
call GroupEnumUnitsInRange(tmpGroup, GetUnitX(tmpUo), GetUnitY(tmpUo), radius*level, Filter(function filter))
set curtargs = 1
endfunction
private function dead takes nothing returns nothing
call BJDebugMsg(GetUnitName(Drain.getTriggeringDrain().u2) + " has died from Forked Drain.")
endfunction
private function init takes nothing returns nothing
call RegisterSpellEffectEvent(abil,function drain)
call Drain.registerDeathEvent(abil,function dead)
endfunction
endlibrary