library Knockback requires DequeueStruct
globals
//*********************
//* Configuration
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
private constant real LOOP_REF = 0.03125
//*
//*
//*****************************************************************************
endglobals
globals
private keyword allocate
private keyword deallocate
private real g_x = 0.
private real g_y = 0.
private item g_item = null
private timer g_timer = CreateTimer()
endglobals
struct knockback extends array
implement DequeueStruct
readonly unit subject
readonly real velocity
readonly real friction
private real rotationCos
private real rotationSin
private real time
private static method onRef takes nothing returns nothing
local thistype kb = 0
local unit u
local real x
local real y
local real iX
local real iY
local real vel
loop
set kb = kb.next()
exitwhen kb == 0
set vel= kb.velocity
set u = kb.subject
set x = GetUnitX(u) + vel * kb.rotationCos
set y = GetUnitY(u) + vel * kb.rotationSin
//use an item to check the pathability of the new coordinate and
//move the unit if the point is available.
call SetItemPosition(g_item, x, y)
set iX = GetWidgetX(g_item) - x
set iY = GetWidgetY(g_item) - y
if (iX*iX + iY*iY <= 32) then
call SetUnitX(u, x)
call SetUnitY(u, y)
endif
set kb.velocity = vel + kb.friction
set kb.time = kb.time - LOOP_REF
if (kb.time <= 0.00) then
call kb.deallocate()
if (thistype.getLength() == 0) then
call PauseTimer(g_timer)
endif
endif
endloop
call SetItemPosition(g_item, g_x, g_y)
call SetItemVisible(g_item, false)
set u = null
endmethod
static method create takes unit u, real angle, real distance, real time returns thistype
local thistype kb = thistype.allocate()
set kb.subject = u
set kb.rotationCos = Cos(angle)
set kb.rotationSin = Sin(angle)
set kb.time = time
set kb.velocity = (2 * distance/time) * LOOP_REF
set kb.friction = (-kb.velocity/time) * LOOP_REF * LOOP_REF
if (thistype.getLength() == 1) then
call TimerStart(g_timer, LOOP_REF, true, function thistype.onRef)
endif
return kb
endmethod
private static method onInit takes nothing returns nothing
//the item will be have maintained invisibility as to not interfere with
//in-game actions, such as a unit picking the item up.
set g_x = GetRectMaxX(bj_mapInitialPlayableArea)
set g_y = GetRectMaxY(bj_mapInitialPlayableArea)
set g_item = CreateItem('afac', g_x, g_y)
call SetItemVisible(g_item, false)
endmethod
endstruct
endlibrary