library Movement requires Keys, MovingSystem, IsDestructableTree
globals
private boolean B
private rect R = Rect(0,0,0,0)
endglobals
private function NoTreesEnum takes nothing returns nothing
set B = false
endfunction
private function NoTreesFilter takes nothing returns boolean
return IsTreeAlive(GetFilterDestructable())
endfunction
private function NoTrees takes real x, real y, real radius returns boolean
call SetRect(R, x-radius, y-radius, x+radius, y+radius)
set B = true
call EnumDestructablesInRect(R, Filter(function NoTreesFilter), function NoTreesEnum)
return B
endfunction
private struct MoveQueue extends array
real angle
static integer max = -1
method destroy takes nothing returns nothing
local integer index = this
loop
exitwhen index+1 >= max
set thistype[index].angle = thistype[index+1].angle
set index = index + 1
endloop
set max = max - 1
endmethod
endstruct
private struct Movement
private static real angle = 270
private static integer keys = 0
private static integer maxQueue = 0
private static real speed = 128
private static real uSpeed = 350
private static real walkTime = speed/(uSpeed+5)
private static integer standIndex = 0
private static integer moveIndex = 10
private static real halfway = 180*bj_DEGTORAD
private static real full = 360*bj_DEGTORAD
private static boolean stopped = true
private static unit u
private static method onStop takes nothing returns nothing
local real x
local real y
set stopped = MoveQueue.max == -1
if stopped then
call SetUnitAnimationByIndex(u, standIndex)
call DestroyTimer(GetExpiredTimer())
else
set x = GetUnitX(u)
set y = GetUnitY(u)
if NoTrees(x+speed*Cos(MoveQueue[0].angle),y+speed*Sin(MoveQueue[0].angle),speed) then
call MoveUnit(u, x, y, MoveQueue[0].angle, uSpeed, speed)
call TimerStart(GetExpiredTimer(), walkTime, false, function thistype.onStop)
else
set stopped = true
call SetUnitAnimationByIndex(u, standIndex)
call DestroyTimer(GetExpiredTimer())
endif
call MoveQueue[0].destroy()
endif
if keys > 0 then
call onKeyHit.evaluate()
endif
endmethod
private static method onKeyHit takes nothing returns nothing
local integer index = KEY_UP
local real x
local real y
set keys = 0
set angle = 0
loop
if KEY[index] then
set angle = angle + KEY_ANGLE[index]
set keys = keys + 1
endif
exitwhen index == 3
set index = index + 1
endloop
if KEY[KEY_RIGHT] then
if keys > 0 then
if angle / keys <= halfway then
set angle = angle + 0
else
set angle = angle + full
endif
else
set angle = KEY_ANGLE[KEY_RIGHT]
endif
set keys = keys + 1
endif
if keys == 0 then
return
endif
set angle = angle / keys
set x = GetUnitX(u)
set y = GetUnitY(u)
if NoTrees(x+speed*Cos(angle),y+speed*Sin(angle),speed) then
if stopped then
call SetUnitAnimationByIndex(u, moveIndex)
call MoveUnit(u, x, y, angle, uSpeed, speed)
set stopped = false
call TimerStart(CreateTimer(), walkTime, false, function thistype.onStop)
elseif MoveQueue.max < maxQueue then
set MoveQueue.max = MoveQueue.max + 1
set MoveQueue[MoveQueue.max].angle = angle
endif
endif
endmethod
implement KeyInput
private static method delayedInit takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
set u = ADVENTURER
call SetCameraTargetController(u, 0, 0, false)
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0, false, function thistype.delayedInit)
endmethod
endstruct
endlibrary