//! zinc
library CameraKeyboardMovement
{
//CONFIGURABLES
//How much a unit should turn around when pressing left/right. Leave the * bj_DEGTORAD, or it won't work.
//Default is the unit's turn speed, if you want to leave that, just set TURN_ANGLE to 0.
constant real TURN_ANGLE = 0 * bj_DEGTORAD;
//Animation that the unit get's when no key is pressed.
constant string ANIM_STOP = "stand";
//Default animation of a unit if none is found.
constant integer ANIM_DEFAULT = 6;
//Same for this library, because the cam variables are private. (And should stay so)
constant real LOOP_INTERVAL = 0.01,
UPDATE_INTERVAL = 0.2;
function CanUnitMove(unit who) -> boolean
{
return UnitAlive(who) && !IsUnitPaused(who) && !(GetUnitAbilityLevel(who, 'Bens') > 0) && /*
*/!(GetUnitAbilityLevel(who, 'Bena') > 0) && !(GetUnitAbilityLevel(who, 'Beng') > 0) && /*
*/!(GetUnitAbilityLevel(who, 'BSTN') > 0) && !(GetUnitAbilityLevel(who, 'BPSE') > 0);
}
//CONFIGURABLES
CAMERA TriggerCam = -1;
public CAMERA PlayerCameras[];
public function GetTriggerCam() -> CAMERA
{
return TriggerCam;
}
public module CameraKeyboardMovement
{
integer animationIndex = ANIM_DEFAULT;
real animationDur = 0;
private
{
boolean upPressed, downPressed, rightPressed, leftPressed, playAnimation;
trigger onKeyEvent;
real animationCount = 0;
}
method movementInit()
{
upPressed = false; downPressed = false; rightPressed = false; leftPressed = false; playAnimation = false;
onKeyEvent = CreateTrigger();
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_UP_DOWN);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_UP_UP);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_DOWN_DOWN);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_DOWN_UP);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_RIGHT_DOWN);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_RIGHT_UP);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_LEFT_DOWN);
TriggerRegisterPlayerEvent(onKeyEvent, applyFor, EVENT_PLAYER_ARROW_LEFT_UP);
PlayerCameras[GetPlayerId(applyFor)] = this;
registerKeyEvent(function()
{
TriggerCam = PlayerCameras[GetPlayerId(GetTriggerPlayer())];
if (GetTriggerEventId() == EVENT_PLAYER_ARROW_UP_DOWN) {
TriggerCam.upPressed = true;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_UP_UP) {
TriggerCam.upPressed = false;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_DOWN_DOWN) {
TriggerCam.downPressed = true;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_DOWN_UP) {
TriggerCam.downPressed = false;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_RIGHT_DOWN) {
TriggerCam.rightPressed = true;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_RIGHT_UP) {
TriggerCam.rightPressed = false;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_LEFT_DOWN) {
TriggerCam.leftPressed = true;
} else if (GetTriggerEventId() == EVENT_PLAYER_ARROW_LEFT_UP) {
TriggerCam.leftPressed = false;
}
});
}
method movement()
{
real x, y, ox, oy, facing, movespeed;
if (CanUnitMove(toFollow))
{
x = GetUnitX(toFollow); y = GetUnitY(toFollow); facing = GetUnitFacing(toFollow)*bj_DEGTORAD;
ox = x; oy = y;
movespeed = GetUnitMoveSpeed(toFollow);
if (upPressed && !downPressed)
{
playAnimation = true;
if (rightPressed && !leftPressed)
{
x += movespeed * LOOP_INTERVAL * Cos(facing - GetUnitDefaultTurnSpeed(toFollow));
y += movespeed * LOOP_INTERVAL * Sin(facing - GetUnitDefaultTurnSpeed(toFollow));
}
else if (!rightPressed && leftPressed)
{
x += movespeed * LOOP_INTERVAL * Cos(facing + GetUnitDefaultTurnSpeed(toFollow));
y += movespeed * LOOP_INTERVAL * Sin(facing + GetUnitDefaultTurnSpeed(toFollow));
}
else
{
x += movespeed * LOOP_INTERVAL * Cos(facing);
y += movespeed * LOOP_INTERVAL * Sin(facing);
}
SetUnitPosition(toFollow, x, y);
if (RAbsBJ(GetUnitX(toFollow) - x) > 0.5 || RAbsBJ(GetUnitY(toFollow) - y) > 0.5)
{
SetUnitPosition(toFollow, x, oy);
if (RAbsBJ(GetUnitX(toFollow) - x) > 0.5)
{
SetUnitPosition(toFollow, ox, y);
if (RAbsBJ(GetUnitY(toFollow) - y) > 0.5)
{
SetUnitPosition(toFollow, x, y);
}
}
}
}
else
{
if (playAnimation)
{
playAnimation = false;
SetUnitAnimation(toFollow, "stand");
}
}
if (rightPressed && !leftPressed)
{
if (TURN_ANGLE == 0)
{
SetUnitFacingTimed(toFollow, (facing - GetUnitDefaultTurnSpeed(toFollow)) * bj_RADTODEG, UPDATE_INTERVAL);
}
else
{
SetUnitFacingTimed(toFollow, (facing - TURN_ANGLE) * bj_RADTODEG, UPDATE_INTERVAL);
}
}
else if (!rightPressed && leftPressed)
{
if (TURN_ANGLE == 0)
{
SetUnitFacingTimed(toFollow, (facing + GetUnitDefaultTurnSpeed(toFollow)) * bj_RADTODEG, UPDATE_INTERVAL);
}
else
{
SetUnitFacingTimed(toFollow, (facing + TURN_ANGLE) * bj_RADTODEG, UPDATE_INTERVAL);
}
}
animationCount += LOOP_INTERVAL;
if (animationCount >= animationDur && playAnimation)
{
SetUnitAnimationByIndex(toFollow, animationIndex);
animationCount = 0;
}
}
}
method registerKeyEvent(code cb) -> triggeraction
{
return TriggerAddAction(onKeyEvent, cb);
}
method unregisterKeyEvent(triggeraction ta)
{
TriggerRemoveAction(onKeyEvent, ta);
}
}
}
//! endzinc
native UnitAlive takes unit whichUnit returns boolean