- Joined
- Apr 23, 2011
- Messages
- 460
I'm in the process of fixing up several spells, however I haven't time to test this spell properly and continue debugging. Can anyone find any obvious problems with the coding itself? Thought I'd post this while I work on other spells.
JASS:
library ArcaneLock uses TimerUtils, RegisterPlayerUnitEvent
globals
private constant integer SPELL_ID = 'ArcL'
private constant real RADIUS = 350.
private constant real DURATION = 6.
private constant integer BUFFLASTS = 4
private constant integer DUMM_ID = 'dumy'
private constant integer DUMM_SPELL = 'Alok'
private constant real MP_FACTOR = .025
private constant integer TIMEOUT = 5
private constant string EYECANDY = ""
private constant real DRAIN = .04
private group enumGroup = CreateGroup()
private group enumGroupSafe = CreateGroup()
endglobals
struct ArcaneLock
private real originX
private real originY
private unit caster
private group boundEnemies = CreateGroup()
private location origin
private timer looping = CreateTimer()
private integer counter
private integer timeout
private effect eyecandy
private timer buffLoop = CreateTimer()
private integer buffLeft
private method onDestroy takes nothing returns nothing
call DestroyGroup(this.boundEnemies)
set this.caster = null
set this.boundEnemies = null
set this.origin = null
set this.looping = null
set this.eyecandy = null
set this.buffLoop = null
endmethod
private static method getPointDistance takes location a, location b returns real
local real x = GetLocationX(b) - GetLocationX(a)
local real y = GetLocationY(b) - GetLocationY(a)
return SquareRoot(x * x + y * y)
endmethod
private method groupLoop takes nothing returns nothing
local unit enumUnit
call GroupEnumUnitsInRangeOfLoc(enumGroup, this.origin, RADIUS, null)
for enumUnit in enumGroup
if not IsUnitAlly(enumUnit, GetOwningPlayer(this.caster)) and not IsUnitInGroup(enumUnit, this.boundEnemies) then
call GroupAddUnit(this.boundEnemies, enumUnit)
endif
endfor
endmethod
private static method buffDrain takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit u
local group g = CreateGroup()
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
for u in g
if GetUnitAbilityLevel(u, DUMM_SPELL) > 0 and getPointDistance(GetUnitLoc(u), GetUnitLoc(this.caster)) < 250 then
call this.giveMana((GetUnitState(u, UNIT_STATE_MAX_MANA)*.03), 250)
endif
endfor
set this.buffLeft = this.buffLeft + 1
if this.buffLeft == BUFFLASTS then
call ReleaseTimer(this.buffLoop)
endif
if this.buffLoop == null then
call this.destroy()
endif
endmethod
private method giveBuff takes unit tar returns nothing
call SetUnitAbilityLevel(tar, DUMM_SPELL, 1)
endmethod
private method giveMana takes real mana, real radius returns nothing
local unit u
local group g = CreateGroup()
call GroupEnumUnitsInRange(g, GetUnitX(this.caster), GetUnitY(this.caster), radius, null)
for u in g
if IsUnitAlly(u, GetOwningPlayer(this.caster)) then
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + mana)
endif
endfor
call DestroyGroup(g)
set g = null
endmethod
private method unitLeaves takes nothing returns nothing
local unit u
local boolean rangeCheck
local real drain
for u in this.boundEnemies
if getPointDistance(Location(GetUnitX(u), GetUnitY(u)), this.origin) > RADIUS then
call SetUnitPositionLoc(u, this.origin)
endif
call GroupAddUnit(enumGroupSafe, u)
set drain = GetUnitState(u, UNIT_STATE_MAX_MANA) * DRAIN
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - drain)
call this.giveMana(drain, 350)
endfor
for u in enumGroupSafe
call GroupAddUnit(this.boundEnemies, u)
endfor
endmethod
private static method periodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit u
if this.counter == 5 then
set this.counter = 0
call this.unitLeaves()
set this.timeout = this.timeout + 1
if this.timeout == TIMEOUT then
call ReleaseTimer(this.looping)
call DestroyEffect(this.eyecandy)
for u in this.boundEnemies
call this.giveBuff(u)
call SetTimerData(this.buffLoop, this)
call TimerStart(this.buffLoop, 1., true, function thistype.buffDrain)
endfor
endif
endif
call this.groupLoop()
set this.counter = this.counter + 1
endmethod
private static method spell takes nothing returns nothing
local thistype this = thistype.create()
set this.caster = GetSpellAbilityUnit()
set this.origin = GetSpellTargetLoc()
set this.originX = GetLocationX(this.origin)
set this.originY = GetLocationY(this.origin)
set eyecandy = AddSpecialEffect(EYECANDY, this.originX, this.originY)
call SetTimerData(this.looping, this)
call TimerStart(this.looping, .2, true, function thistype.periodic)
endmethod
endstruct
endlibrary