- Joined
- Oct 16, 2011
- Messages
- 308
Hi, I was wondering if anyone can help me make this cleaner and more efficient? The intended effect is to make an affected unit to keep moving towards a random point in the area.
JASS:
scope MentalDisarray
globals
private constant integer ABILITY_ID = 'A8U7'
private constant integer BUFF_ID = 'B8U7'
endglobals
private struct Data
unit e
real x
real y
real nx
real ny
timer cycle
static integer index = -1
static thistype array data
method destroy takes nothing returns nothing
call ReleaseTimer(this.cycle)
set this.e = null
set this.cycle = null
call this.deallocate()
endmethod
private static method runTimer takes nothing returns nothing
local Data this = GetTimerData(GetExpiredTimer())
local real ex = GetUnitX(this.e)
local real ey = GetUnitY(this.e)
local real angle = bj_RADTODEG * Atan2(this.ny - ey, this.nx - ex) + GetRandomReal(-60, 60)
local real distance = SquareRoot((this.nx - ex) * (this.nx - ex) + (this.ny - ey) * (this.ny - ey))
if GetUnitMoveSpeed(this.e) > 0 then
if distance <= 32 or not udg_UnitMoving[GetUnitUserData(this.e)] then
set this.nx = this.x + 64 * Cos(angle * bj_DEGTORAD)
set this.ny = this.y + 64 * Sin(angle * bj_DEGTORAD)
call IssuePointOrder(this.e, "move", this.nx, this.ny)
endif
elseif GetUnitCurrentOrder(this.e) != 851972 then
call IssueImmediateOrder(this.e, "stop")
endif
if GetUnitAbilityLevel(this.e, BUFF_ID) == 0 or GetWidgetLife(this.e) <= .405 then
call ReleaseTimer(GetExpiredTimer())
call this.destroy()
endif
endmethod
static method resetTimer takes unit e returns nothing
local integer i = 0
local Data this
loop
exitwhen i > index
set this = data[i]
if e == this.e then
call this.destroy()
set data[i] = data[index]
set index = index - 1
return
endif
set i = i + 1
endloop
endmethod
static method runEvent takes nothing returns nothing
local thistype this
call thistype.resetTimer(GetSpellTargetUnit())
set this = Data.allocate()
set this.e = GetSpellTargetUnit()
set this.x = GetUnitX(this.e)
set this.y = GetUnitY(this.e)
set this.nx = this.x + 64 * Cos(GetRandomReal(0, 360) * bj_DEGTORAD)
set this.ny = this.y + 64 * Sin(GetRandomReal(0, 360) * bj_DEGTORAD)
set index = index + 1
set data[index] = this
set this.cycle = NewTimerEx(this)
call TimerStart(this.cycle, .1, true, function thistype.runTimer)
if GetUnitMoveSpeed(this.e) > 0 then
call IssuePointOrder(this.e, "move", this.nx, this.ny)
else
call IssueImmediateOrder(this.e, "stop")
endif
endmethod
static method resumeEvent takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer i = 0
local Data this
loop
exitwhen i > index
set this = data[i]
if u == this.e then
if GetUnitMoveSpeed(this.e) > 0 then
if GetOrderPointX() != this.nx or GetOrderPointY() != this.ny then
call IssuePointOrder(this.e, "move", this.nx, this.ny)
endif
elseif GetIssuedOrderId() != 851972 then
call BlzUnitInterruptAttack(this.e)
call IssueImmediateOrder(this.e, "stop")
endif
endif
set i = i + 1
endloop
set u = null
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABILITY_ID, function thistype.runEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function thistype.resumeEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, function thistype.resumeEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function thistype.resumeEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, function thistype.resumeEvent)
set index = -1
endmethod
endstruct
endscope