Files
Client_RPG/client.cs
T

1425 lines
27 KiB
C#

// Client_RPG - top-down camera, click-to-move, and RPG windows for GameMode_RPG.
// Camera v3: on dedicated servers the host owns the Camera transform; the client only
// sends RPG_CamSync (yaw/dist) and uses stock moveMap + RPGClient_Input (no extra ActionMaps).
exec("./ui.cs");
// The server probes with RPG_Probe; reply with serverCmdRPG_Hello(2) to play.
$RPGClient::Version = 2;
$RPGClient::Active = 0;
$RPGClient::Yaw = 0;
$RPGClient::Dist = 14;
$RPGClient::TopDownPitch = 1.22;
$RPGClient::Pitch = 1.22;
$RPGClient::PitchMin = 0.55;
$RPGClient::PitchMax = 1.38;
$RPGClient::PitchSpeed = 0.025;
$RPGClient::DistMin = 8;
$RPGClient::DistMax = 30;
$RPGClient::OrbitInit = 0;
$RPGClient::HudPlaced = 0;
$RPGClient::PlayBooted = 0;
$RPGClient::CamTickOn = 0;
$RPGClient::PanX = 0;
$RPGClient::PanY = 0;
$RPGClient::PanMax = 48;
$RPGClient::YawSpeed = 0.045;
$RPGClient::ZoomSpeed = 0.12;
$RPGClient::CamTickSched = 0;
$RPGClient::LastCamSync = 0;
$RPGClient::CamSyncMs = 100;
$RPGClient::TopDownFov = 0.85;
$RPGClient::MvF = 0;
$RPGClient::MvB = 0;
$RPGClient::MvL = 0;
$RPGClient::MvR = 0;
$RPGClient::CamModeReady = 0;
$RPGClient::HelloPending = 0;
$RPGClient::HelloLast = "";
$RPGClient::TopDownWatchSched = 0;
$RPGClient::CamSched = 0;
$RPGClient::LastClickTime = 0;
$RPGClient::ChatOpen = 0;
$RPGClient::WantCursor = 1;
function RPGClient_NormScreenPos(%pos)
{
if (!isObject(Canvas))
{
return "0.5 0.5";
}
%ext = Canvas.getExtent();
%w = getWord(%ext, 0);
%h = getWord(%ext, 1);
if (%w < 1)
{
%w = 1;
}
if (%h < 1)
{
%h = 1;
}
%x = getWord(%pos, 0) / %w;
%y = getWord(%pos, 1) / %h;
return RPGClient_ClampNorm(%x, %y);
}
function RPGClient_ClampNorm(%x, %y)
{
if (%x < 0)
{
%x = 0;
}
if (%x > 1)
{
%x = 1;
}
if (%y < 0)
{
%y = 0;
}
if (%y > 1)
{
%y = 1;
}
return %x SPC %y;
}
function RPGClient_NormPos(%ctrl, %pos)
{
if (isObject(Canvas))
{
return RPGClient_NormScreenPos(%pos);
}
if (!isObject(%ctrl))
{
return "0.5 0.5";
}
%ext = %ctrl.getExtent();
%w = getWord(%ext, 0);
%h = getWord(%ext, 1);
if (%w < 1)
{
%w = 1;
}
if (%h < 1)
{
%h = 1;
}
%x = getWord(%pos, 0) / %w;
%y = 1 - getWord(%pos, 1) / %h;
if (%x < 0)
{
%x = 0;
}
if (%x > 1)
{
%x = 1;
}
if (%y < 0)
{
%y = 0;
}
if (%y > 1)
{
%y = 1;
}
return %x SPC %y;
}
function RPGClient_Aspect()
{
if (!isObject(Canvas))
{
return 1.333;
}
%ext = Canvas.getExtent();
%w = getWord(%ext, 0);
%h = getWord(%ext, 1);
return %h > 0 ? %w / %h : 1.333;
}
function RPGClient_V3Len(%x, %y, %z)
{
return mSqrt(%x * %x + %y * %y + %z * %z);
}
function RPGClient_V3Norm(%x, %y, %z)
{
%l = RPGClient_V3Len(%x, %y, %z);
if (%l < 0.0001)
{
return "0 0 0";
}
return (%x / %l) @ " " @ (%y / %l) @ " " @ (%z / %l);
}
function RPGClient_V3Cross(%ax, %ay, %az, %bx, %by, %bz)
{
return (%ay * %bz - %az * %by) @ " " @ (%az * %bx - %ax * %bz) @ " " @ (%ax * %by - %ay * %bx);
}
function RPGClient_EyeRay(%nx, %ny)
{
%conn = RPGClient_GetConn();
%body = RPGClient_BodyForCamera(%conn);
if (!isObject(%body))
{
return "";
}
%p = %body.getPosition();
%cx = getWord(%p, 0) + $RPGClient::PanX;
%cy = getWord(%p, 1) + $RPGClient::PanY;
%cz = getWord(%p, 2) + 1.5;
%yaw = $RPGClient::Yaw;
%dist = $RPGClient::Dist;
%pitch = $RPGClient::Pitch > 0 ? $RPGClient::Pitch : $RPGClient::TopDownPitch;
%bx = -mCos(%yaw) * mCos(%pitch) * %dist;
%by = -mSin(%yaw) * mCos(%pitch) * %dist;
%bz = mSin(%pitch) * %dist;
%ex = %cx + %bx;
%ey = %cy + %by;
%ez = %cz + %bz;
%fx = %cx - %ex;
%fy = %cy - %ey;
%fz = %cz - %ez;
%fwd = RPGClient_V3Norm(%fx, %fy, %fz);
%fw = getWord(%fwd, 0);
%fh = getWord(%fwd, 1);
%ff = getWord(%fwd, 2);
%right = RPGClient_V3Norm(getWord(RPGClient_V3Cross(%fw, %fh, %ff, 0, 0, 1), 0), getWord(RPGClient_V3Cross(%fw, %fh, %ff, 0, 0, 1), 1), getWord(RPGClient_V3Cross(%fw, %fh, %ff, 0, 0, 1), 2));
%rw = getWord(%right, 0);
%rh = getWord(%right, 1);
%rf = getWord(%right, 2);
%up = RPGClient_V3Norm(getWord(RPGClient_V3Cross(%rw, %rh, %rf, %fw, %fh, %ff), 0), getWord(RPGClient_V3Cross(%rw, %rh, %rf, %fw, %fh, %ff), 1), getWord(RPGClient_V3Cross(%rw, %rh, %rf, %fw, %fh, %ff), 2));
%uw = getWord(%up, 0);
%uh = getWord(%up, 1);
%uf = getWord(%up, 2);
%fov = mTan($RPGClient::TopDownFov * 0.5);
%aspect = RPGClient_Aspect();
%rx = (%nx - 0.5) * 2 * %fov * %aspect;
%ry = (0.5 - %ny) * 2 * %fov;
%dx = %fw + %rw * %rx + %uw * %ry;
%dy = %fh + %rh * %rx + %uh * %ry;
%dz = %ff + %rf * %rx + %uf * %ry;
%dir = RPGClient_V3Norm(%dx, %dy, %dz);
%dw = getWord(%dir, 0);
%dh = getWord(%dir, 1);
%df = getWord(%dir, 2);
%eye = %ex @ " " @ %ey @ " " @ %ez;
return %eye TAB (%ex + %dw * 250) @ " " @ (%ey + %dh * 250) @ " " @ (%ez + %df * 250);
}
function RPGClient_PickGround(%nx, %ny)
{
%conn = RPGClient_GetConn();
%body = RPGClient_BodyForCamera(%conn);
if (!isObject(%body))
{
return "";
}
%ray = RPGClient_EyeRay(%nx, %ny);
if (%ray $= "")
{
return "";
}
%eye = getField(%ray, 0) SPC getField(%ray, 1) SPC getField(%ray, 2);
%end = getField(%ray, 3) SPC getField(%ray, 4) SPC getField(%ray, 5);
%ex = getWord(%eye, 0);
%ey = getWord(%eye, 1);
%ez = getWord(%eye, 2);
%dx = getWord(%end, 0) - %ex;
%dy = getWord(%end, 1) - %ey;
%dz = getWord(%end, 2) - %ez;
%dir = RPGClient_V3Norm(%dx, %dy, %dz);
%dzw = getWord(%dir, 2);
%refZ = getWord(%body.getPosition(), 2);
if (mAbs(%dzw) < 0.02)
{
return "";
}
%t = (%refZ - %ez) / %dzw;
if (%t < 0 || %t > 400)
{
return "";
}
return (%ex + getWord(%dir, 0) * %t) @ " " @ (%ey + getWord(%dir, 1) * %t) @ " " @ %refZ;
}
function RPGClient_SendClick(%button, %pos, %guiNorm)
{
if (!isObject(ServerConnection))
{
return;
}
%now = getSimTime();
if (%now - $RPGClient::LastClickTime < 80)
{
return;
}
$RPGClient::LastClickTime = %now;
%norm = %guiNorm ? RPGClient_NormPos(RPGClient_Mouse, %pos) : RPGClient_NormScreenPos(%pos);
%nx = getWord(%norm, 0);
%ny = getWord(%norm, 1);
commandToServer('RPG_Click', %button, %nx, %ny, RPGClient_Aspect(), $RPGClient::Yaw, $RPGClient::Dist, $RPGClient::Pitch, $RPGClient::PanX, $RPGClient::PanY);
if (%button == 0)
{
%gnd = RPGClient_PickGround(%nx, %ny);
if (%gnd !$= "")
{
commandToServer('RPG_Go', getWord(%gnd, 0), getWord(%gnd, 1), getWord(%gnd, 2));
}
}
}
function RPGClient_Mouse::onMouseDown(%this, %mod, %pos, %clicks)
{
if (!$RPGClient::Active)
{
return;
}
RPGClient_SendClick(0, %pos, 1);
}
function RPGClient_Mouse::onRightMouseDown(%this, %mod, %pos, %clicks)
{
if (!$RPGClient::Active)
{
return;
}
RPGClient_SendClick(1, %pos, 1);
}
function RPGClient_Mouse::onWake(%this)
{
if (isObject(Canvas))
{
%ext = Canvas.getExtent();
%this.resize(0, 0, getWord(%ext, 0), getWord(%ext, 1));
}
}
function RPGClient_ClampPan()
{
%max = $RPGClient::PanMax;
if ($RPGClient::PanX > %max)
{
$RPGClient::PanX = %max;
}
if ($RPGClient::PanX < -%max)
{
$RPGClient::PanX = -%max;
}
if ($RPGClient::PanY > %max)
{
$RPGClient::PanY = %max;
}
if ($RPGClient::PanY < -%max)
{
$RPGClient::PanY = -%max;
}
}
function RPGClient_ViewTransform(%body, %yaw, %dist, %panX, %panY)
{
%p = %body.getPosition();
%cx = getWord(%p, 0) + %panX;
%cy = getWord(%p, 1) + %panY;
%cz = getWord(%p, 2) + 1.5;
%pitch = $RPGClient::Pitch > 0 ? $RPGClient::Pitch : $RPGClient::TopDownPitch;
%bx = -mCos(%yaw) * mCos(%pitch) * %dist;
%by = -mSin(%yaw) * mCos(%pitch) * %dist;
%bz = mSin(%pitch) * %dist;
%ex = %cx + %bx;
%ey = %cy + %by;
%ez = %cz + %bz;
%eye = %ex @ " " @ %ey @ " " @ %ez;
%euler = (-%pitch) @ " 0 " @ (%yaw + $pi);
%rot = eulerRadToMatrix(%euler);
return %eye @ " " @ %rot;
}
function RPGClient_EnsureCursor()
{
if (!$RPGClient::Active || !isObject(Canvas) || !$RPGClient::WantCursor)
{
return;
}
if (Canvas.isCursorOn())
{
return;
}
lockMouse(0);
cursorOn();
}
function RPGClient_RaiseMouseOverlay()
{
if (!isObject(RPGClient_Mouse) || !isObject(PlayGui))
{
return;
}
PlayGui.pushToFront(RPGClient_Mouse);
}
function RPGClient_NetCam()
{
return $RPGClient::Active && isObject(ServerConnection);
}
function RPGClient_CameraTick()
{
$RPGClient::CamTickSched = 0;
RPGClient_PollChatOpen();
if (!isObject(ServerConnection) || !$RPGClient::CamTickOn)
{
return;
}
%spin = $RPGClient::YawSpeed * 2.5;
%tilt = $RPGClient::PitchSpeed * 2.5;
%zoom = $RPGClient::ZoomSpeed * 2.5;
%changed = 0;
if ($RPGClient::MvL > 0)
{
$RPGClient::Yaw = $RPGClient::Yaw - %spin * $RPGClient::MvL;
%changed = 1;
}
if ($RPGClient::MvR > 0)
{
$RPGClient::Yaw = $RPGClient::Yaw + %spin * $RPGClient::MvR;
%changed = 1;
}
if ($RPGClient::MvF > 0)
{
$RPGClient::Pitch = getMin($RPGClient::PitchMax, $RPGClient::Pitch + %tilt * $RPGClient::MvF);
%changed = 1;
}
if ($RPGClient::MvB > 0)
{
$RPGClient::Pitch = getMax($RPGClient::PitchMin, $RPGClient::Pitch - %tilt * $RPGClient::MvB);
%changed = 1;
}
if (%changed || $RPGClient::MvF || $RPGClient::MvB || $RPGClient::MvL || $RPGClient::MvR)
{
RPGClient_ApplyCamera(0);
}
$RPGClient::CamTickSched = schedule(50, 0, RPGClient_CameraTick);
}
function RPGClient_StartCameraTick()
{
cancel($RPGClient::CamTickSched);
$RPGClient::CamTickSched = schedule(50, 0, RPGClient_CameraTick);
}
function RPGClient_InPlay()
{
return isObject(ServerConnection) && ($RPGClient::Server || $RPGClient::Active);
}
function RPGClient_TextTyping()
{
return $RPGClient::ChatOpen;
}
function RPGClient_SetChatOpen(%open)
{
$RPGClient::ChatOpen = %open ? 1 : 0;
}
function RPGClient_PollChatOpen()
{
if (!$RPGClient::ChatOpen || !isObject(newChatText))
{
return;
}
if (!newChatText.isVisible())
{
$RPGClient::ChatOpen = 0;
}
}
function RPGClient_RpgKeys()
{
return $RPGClient::Active && !RPGClient_TextTyping();
}
function RPGClient_CamInputAllowed()
{
if (!RPGClient_RpgKeys())
{
return 0;
}
if (!$RPGClient::CamTickOn)
{
$RPGClient::CamTickOn = 1;
}
return 1;
}
function RPGClient_BootPlay()
{
if (!isObject(ServerConnection))
{
return;
}
$RPGClient::Server = 1;
$RPGClient::Active = 1;
$RPGClient::CamTickOn = 1;
$RPGClient::PlayBooted = 1;
if ($RPGClient::Dist < 6)
{
$RPGClient::Dist = 14;
}
RPGClient_StockMoveMapBinds();
RPGClient_EnsureOverlay();
RPGClient_BindKeys();
RPGClient_StartCameraTick();
RPGClient_ScheduleCamera();
RPGClient_EnsureCursor();
}
function RPGClient_KeyMvForward(%val)
{
if (!isObject(ServerConnection))
{
return;
}
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
$RPGClient::CamTickOn = 1;
RPGClient_StartCameraTick();
}
$RPGClient::MvF = %val;
}
function RPGClient_KeyMvBackward(%val)
{
if (!isObject(ServerConnection))
{
return;
}
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
$RPGClient::CamTickOn = 1;
RPGClient_StartCameraTick();
}
$RPGClient::MvB = %val;
}
function RPGClient_KeyMvLeft(%val)
{
if (!isObject(ServerConnection))
{
return;
}
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
$RPGClient::CamTickOn = 1;
RPGClient_StartCameraTick();
}
$RPGClient::MvL = %val;
}
function RPGClient_KeyMvRight(%val)
{
if (!isObject(ServerConnection))
{
return;
}
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
$RPGClient::CamTickOn = 1;
RPGClient_StartCameraTick();
}
$RPGClient::MvR = %val;
}
function RPGClient_StockMoveMapBinds()
{
if (!isObject(moveMap))
{
return;
}
moveMap.bind(keyboard, w, moveforward);
moveMap.bind(keyboard, s, movebackward);
moveMap.bind(keyboard, a, moveleft);
moveMap.bind(keyboard, d, moveright);
moveMap.bind(keyboard, left, invLeft);
moveMap.bind(keyboard, right, invRight);
moveMap.bind(keyboard, equals, RPGClient_ZoomIn);
moveMap.bind(keyboard, minus, RPGClient_ZoomOut);
moveMap.bind(keyboard, "[", RPGClient_ZoomIn);
moveMap.bind(keyboard, "]", RPGClient_ZoomOut);
}
function RPGClient_RestoreMoveMap()
{
RPGClient_StockMoveMapBinds();
}
function RPGClient_SendClickFromCursor(%button)
{
if (!$RPGClient::Active || !isObject(Canvas))
{
return;
}
RPGClient_SendClick(%button, Canvas.getCursorPos(), 0);
}
function RPGClient_EnsureOverlay()
{
if (!isObject(PlayGui))
{
return;
}
if (!isObject(RPGClient_Mouse))
{
new GuiMouseEventCtrl(RPGClient_Mouse)
{
className = "RPGClient_Mouse";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 480";
profile = "GuiDefaultProfile";
visible = "1";
enabled = "1";
modal = "0";
};
PlayGui.add(RPGClient_Mouse);
}
RPGClient_RaiseMouseOverlay();
if (isObject(RPGClient_Mouse) && isObject(Canvas))
{
%ext = Canvas.getExtent();
RPGClient_Mouse.resize(0, 0, getWord(%ext, 0), getWord(%ext, 1));
}
if ($RPGClient::Active)
{
RPGClient_StockMoveMapBinds();
}
$enableDirectInput = 1;
activateDirectInput();
$mvFreeLook = 0;
$firstPerson = 0;
if (isObject(Canvas) && $RPGClient::WantCursor && !Canvas.isCursorOn())
{
Canvas.cursorOn();
}
if (isObject(PlayGui))
{
PlayGui.killToolHud();
}
}
function RPGClient_EnableOverlay()
{
RPGClient_EnsureOverlay();
}
function RPGClient_ToggleCursor(%val)
{
if (!$RPGClient::Active || !%val)
{
return;
}
ToggleCursor(%val);
if (isObject(Canvas))
{
$RPGClient::WantCursor = Canvas.isCursorOn();
if ($RPGClient::WantCursor)
{
RPGClient_RaiseMouseOverlay();
}
}
}
function RPGClient_DisableOverlay()
{
cancel($RPGClient::CamSched);
$RPGClient::CamSched = 0;
cancel($RPGClient::CamTickSched);
$RPGClient::CamTickSched = 0;
$RPGClient::MvF = 0;
$RPGClient::MvB = 0;
$RPGClient::MvL = 0;
$RPGClient::MvR = 0;
if (isObject(RPGClient_Mouse))
{
RPGClient_Mouse.delete();
}
$RPGClient::Active = 0;
$RPGClient::OrbitInit = 0;
$RPGClient::HudPlaced = 0;
$RPGClient::PlayBooted = 0;
$RPGClient::CamTickOn = 0;
$RPGClient::ChatOpen = 0;
RPGClient_RestoreMoveMap();
}
function RPGClient_Hud_Place()
{
if (!isObject(RPGClient_Hud) || !isObject(Canvas))
{
return;
}
%ext = Canvas.getExtent();
%w = getWord(%ext, 0);
%h = getWord(%ext, 1);
if (%h < 1)
{
return;
}
%pw = %w > 520 ? 520 : %w - 16;
%px = mFloor((%w - %pw) * 0.5);
%py = %h - 108;
if (%py < 8)
{
%py = 8;
}
RPGClient_Hud.resize(%px, %py, %pw, 20);
$RPGClient::HudPlaced = 1;
}
function RPGClient_ApplyCamera(%forceSync)
{
%now = getSimTime();
%doSync = %forceSync || %now - $RPGClient::LastCamSync >= $RPGClient::CamSyncMs;
if (!%doSync || !isObject(ServerConnection))
{
return;
}
$RPGClient::LastCamSync = %now;
commandToServer('RPG_CamSync', $RPGClient::Yaw, $RPGClient::Dist, $RPGClient::PanX, $RPGClient::PanY, $RPGClient::Pitch);
if (RPGClient_NetCam())
{
return;
}
%conn = RPGClient_GetConn();
if (!isObject(%conn))
{
return;
}
%body = RPGClient_BodyForCamera(%conn);
if (!isObject(%body))
{
return;
}
%cam = %conn.Camera;
if (!isObject(%cam))
{
%cam = %conn.camera;
}
if (!isObject(%cam))
{
return;
}
%conn.setControlObject(%cam);
$mvFreeLook = 0;
$firstPerson = 0;
%xfm = RPGClient_ViewTransform(%body, $RPGClient::Yaw, $RPGClient::Dist, $RPGClient::PanX, $RPGClient::PanY);
%cam.unmountImage(0);
if (!$RPGClient::OrbitInit)
{
%cam.setMode("Corpse", %body);
%cam.mode = "Corpse";
%cam.thirdPersonOnly = 1;
$RPGClient::OrbitInit = 1;
}
%cam.setOrbitMode(%body, %xfm, 0, 32, $RPGClient::Dist);
%cam.setTransform(%xfm);
%cam.setOrbitDist($RPGClient::Dist);
}
function RPGClient_ScheduleCamera()
{
cancel($RPGClient::CamSched);
RPGClient_ApplyCamera(1);
}
function RPGClient_YawLeft(%val)
{
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
return;
}
$RPGClient::MvL = %val;
}
function RPGClient_YawRight(%val)
{
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
return;
}
$RPGClient::MvR = %val;
}
function RPGClient_ZoomIn(%val)
{
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
return;
}
if (%val)
{
$RPGClient::Dist = getMax($RPGClient::DistMin, $RPGClient::Dist - 2.5);
RPGClient_ApplyCamera(1);
}
}
function RPGClient_ZoomOut(%val)
{
if (!RPGClient_CamInputAllowed())
{
return;
}
if (!$RPGClient::CamTickOn)
{
return;
}
if (%val)
{
$RPGClient::Dist = getMin($RPGClient::DistMax, $RPGClient::Dist + 2.5);
RPGClient_ApplyCamera(1);
}
}
function RPGClient_CanSendCmd()
{
return isObject(ServerConnection) || isObject(localClientConnection);
}
function RPGClient_GetConn()
{
if (isObject(ServerConnection))
{
return ServerConnection;
}
if (isObject(localClientConnection))
{
return localClientConnection;
}
return 0;
}
function RPGClient_BodyForCamera(%conn)
{
if (!isObject(%conn))
{
return 0;
}
%body = %conn.Player;
if (!isObject(%body))
{
%body = %conn.player;
}
if (!isObject(%body))
{
%co = %conn.getControlObject();
if (isObject(%co) && %co.getClassName() $= "Camera" && isObject(%co.getOrbitObject()))
{
%body = %co.getOrbitObject();
}
}
if (!isObject(%body) && isObject(%conn.Camera) && isObject(%conn.Camera.getOrbitObject()))
{
%body = %conn.Camera.getOrbitObject();
}
return %body;
}
function RPGClient_SendHello()
{
if ($RPGClient::Server)
{
return;
}
if (!RPGClient_CanSendCmd())
{
return;
}
%now = getSimTime();
if ($RPGClient::HelloLast !$= "" && %now - $RPGClient::HelloLast < 900)
{
return;
}
$RPGClient::HelloLast = %now;
commandToServer('RPG_Hello', $RPGClient::Version);
commandToServer('RPGHello', $RPGClient::Version);
commandToServer('Message', "/rpg clienthello " @ $RPGClient::Version);
}
function clientCmdRPG_Probe()
{
RPGClient_SendHello();
}
function clientCmdRPG_Welcome(%serverProto, %accepted)
{
if (%accepted && %serverProto == $RPGClient::Version)
{
$RPGClient::HelloPending = 0;
$RPGClient::Server = 1;
schedule(0, 0, RPGClient_BootPlay);
schedule(2500, 0, RPGClient_TopDownWatch);
}
else if (!%accepted)
{
echo("Client_RPG: server rejected handshake (server proto " @ %serverProto @ ")");
schedule(1500, 0, RPGClient_SendHello);
}
}
function RPGClient_TopDownWatch()
{
$RPGClient::TopDownWatchSched = 0;
if ($RPGClient::Active || $RPGClient::Server || !RPGClient_CanSendCmd())
{
return;
}
$RPGClient::HelloLast = "";
RPGClient_SendHello();
$RPGClient::TopDownWatchSched = schedule(2500, 0, RPGClient_TopDownWatch);
}
function RPGClient_EnsurePlayGui()
{
if (!isObject(PlayGui) || !isObject(Canvas))
{
return 0;
}
if (Canvas.getContent() != PlayGui.getId())
{
Canvas.setContent(PlayGui);
}
return 1;
}
function clientCmdRPG_Camera(%yaw, %dist, %pitch)
{
$RPGClient::Yaw = %yaw;
if (%dist > 0)
{
$RPGClient::Dist = %dist;
}
if (%pitch > 0)
{
$RPGClient::Pitch = %pitch;
}
$RPGClient::PanX = 0;
$RPGClient::PanY = 0;
$RPGClient::CamTickOn = 1;
RPGClient_StartCameraTick();
RPGClient_ApplyCamera(1);
}
function clientCmdRPG_TopDown(%on, %yaw, %dist)
{
if (%on)
{
$RPGClient::Server = 1;
$RPGClient::Active = 1;
$RPGClient::PlayBooted = 1;
if (%dist > 0)
{
$RPGClient::Dist = %dist;
}
$RPGClient::Yaw = %yaw;
if (!RPGClient_EnsurePlayGui())
{
RPGClient_BootPlay();
schedule(200, 0, clientCmdRPG_TopDown, %on, %yaw, %dist);
return;
}
cancel($RPGClient::TopDownWatchSched);
$RPGClient::TopDownWatchSched = 0;
if (%dist > 0)
{
$RPGClient::Dist = %dist;
}
else if ($RPGClient::Dist < 6)
{
$RPGClient::Dist = 14;
}
$RPGClient::Yaw = %yaw;
$RPGClient::OrbitInit = 0;
$RPGClient::HudPlaced = 0;
$RPGClient::CamTickOn = 1;
RPGClient_EnsureOverlay();
RPGClient_BindKeys();
RPGClient_StartCameraTick();
schedule(500, 0, RPGClient_EnsureOverlay);
schedule(1500, 0, RPGClient_EnsureOverlay);
RPGClient_EnsureCursor();
RPGClient_Hud_Ensure();
}
else
{
$RPGClient::Server = 0;
$RPGClient::PlayBooted = 0;
RPGClient_DisableOverlay();
RPGClient_UnbindKeys();
}
}
function clientCmdRPG_Hud(%hp, %maxHp, %silver, %load, %cap, %skillId, %skillValue, %blocking, %tHp, %tMax)
{
RPGClient_BootPlay();
RPGClient_Hud_Update(%hp, %maxHp, %silver, %load, %cap, %skillId, %skillValue, %tHp, %tMax);
}
function clientCmdRPG_HudOff()
{
RPGClient_Hud_Hide();
}
function clientCmdRPG_Notify(%text, %sec)
{
if (%text !$= "")
{
RPGClient_Notify_Show(%text, %sec);
}
}
function clientCmdRPG_Dialog(%title, %body, %sec)
{
RPGClient_Dialog_Show(%title, %body, %sec);
}
function clientCmdRPG_ListBegin(%title, %page, %pages)
{
RPGClient_List_Begin(%title, %page, %pages);
}
function clientCmdRPG_ListRow(%row)
{
RPGClient_List_Row(%row);
}
function clientCmdRPG_ListEnd()
{
RPGClient_List_End();
}
// --- HUD / list / dialog (Phase 4): thin windows on PlayGui ---
function RPGClient_Hud_Ensure()
{
if (isObject(RPGClient_Hud))
{
return;
}
new GuiTextCtrl(RPGClient_Hud)
{
horizSizing = "absolute";
vertSizing = "absolute";
position = "8 400";
extent = "520 20";
profile = "ChatHudMessageProfile";
text = "";
};
PlayGui.add(RPGClient_Hud);
RPGClient_Hud_Place();
}
function RPGClient_Hud_Update(%hp, %maxHp, %silver, %load, %cap, %skillId, %skillValue, %tHp, %tMax)
{
if (!$RPGClient::Active)
{
return;
}
RPGClient_Hud_Ensure();
if (!$RPGClient::HudPlaced)
{
RPGClient_Hud_Place();
}
%t = "";
if (%tMax > 0)
{
%t = " | Target " @ %tHp @ "/" @ %tMax;
}
RPGClient_Hud.setText("HP " @ %hp @ "/" @ %maxHp @ %t @ " | " @ %silver @ " silver | load " @ %load @ "/" @ %cap @ " | " @ %skillId @ " " @ %skillValue);
}
function RPGClient_Hud_Hide()
{
if (isObject(RPGClient_Hud))
{
RPGClient_Hud.setText("");
}
}
function RPGClient_Notify_Show(%text, %sec)
{
RPGClient_Hud_Ensure();
RPGClient_Hud.setText(%text);
if (%sec > 0)
{
schedule(%sec * 1000, RPGClient_Hud, setText, "");
}
}
function RPGClient_Dialog_Show(%title, %body, %sec)
{
messageBoxOK(%title, %body, "");
}
function RPGClient_List_Begin(%title, %page, %pages)
{
$RPGClient::ListBody = "";
$RPGClient::ListTitle = %title @ " (" @ (%page + 1) @ "/" @ %pages @ ")";
}
function RPGClient_List_Row(%row)
{
$RPGClient::ListBody = $RPGClient::ListBody @ %row @ "\n";
}
function RPGClient_List_End()
{
if ($RPGClient::ListBody !$= "")
{
messageBoxOK($RPGClient::ListTitle, $RPGClient::ListBody, "");
}
}
package RPGClient_BlockMouseFire
{
function mouseFire(%val)
{
if ($RPGClient::Active)
{
if (%val)
{
RPGClient_SendClickFromCursor(0);
}
return;
}
Parent::mouseFire(%val);
}
function altTrigger(%val)
{
if ($RPGClient::Active)
{
if (%val)
{
RPGClient_SendClickFromCursor(1);
}
return;
}
Parent::altTrigger(%val);
}
};
activatePackage(RPGClient_BlockMouseFire);
package RPGClient_PageKeys
{
function PageUpNewChatHud(%val)
{
if (RPGClient_RpgKeys() && %val)
{
RPGClient_ZoomIn(1);
return;
}
Parent::PageUpNewChatHud(%val);
}
function PageDownNewChatHud(%val)
{
if (RPGClient_RpgKeys() && %val)
{
RPGClient_ZoomOut(1);
return;
}
Parent::PageDownNewChatHud(%val);
}
};
activatePackage(RPGClient_PageKeys);
package RPGClient_Input
{
function moveforward(%val)
{
if ($RPGClient::Active)
{
RPGClient_KeyMvForward(%val);
return;
}
Parent::moveforward(%val);
}
function movebackward(%val)
{
if ($RPGClient::Active)
{
RPGClient_KeyMvBackward(%val);
return;
}
Parent::movebackward(%val);
}
function moveleft(%val)
{
if ($RPGClient::Active)
{
RPGClient_KeyMvLeft(%val);
return;
}
Parent::moveleft(%val);
}
function moveright(%val)
{
if ($RPGClient::Active)
{
RPGClient_KeyMvRight(%val);
return;
}
Parent::moveright(%val);
}
function invLeft(%val)
{
if (RPGClient_RpgKeys())
{
RPGClient_YawLeft(%val);
return;
}
Parent::invLeft(%val);
}
function invRight(%val)
{
if (RPGClient_RpgKeys())
{
RPGClient_YawRight(%val);
return;
}
Parent::invRight(%val);
}
function scrollInventory(%val)
{
if (RPGClient_RpgKeys() && %val != 0)
{
if (%val > 0)
{
$RPGClient::Dist = getMax($RPGClient::DistMin, $RPGClient::Dist - 0.5 * %val);
}
else
{
$RPGClient::Dist = getMin($RPGClient::DistMax, $RPGClient::Dist - 0.5 * %val);
}
RPGClient_ApplyCamera(1);
return;
}
Parent::scrollInventory(%val);
}
function yaw(%val)
{
if (RPGClient_CamInputAllowed() && %val != 0)
{
%sens = $pref::Input::MouseSensitivity;
$RPGClient::Yaw = $RPGClient::Yaw + %val * %sens * 0.004;
RPGClient_ApplyCamera(0);
return;
}
Parent::yaw(%val);
}
};
activatePackage(RPGClient_Input);
package RPGClient_ZoomKeys
{
function shiftBrickUp(%val)
{
if (RPGClient_RpgKeys() && %val)
{
RPGClient_ZoomIn(1);
return;
}
Parent::shiftBrickUp(%val);
}
function shiftBrickDown(%val)
{
if (RPGClient_RpgKeys() && %val)
{
RPGClient_ZoomOut(1);
return;
}
Parent::shiftBrickDown(%val);
}
};
activatePackage(RPGClient_ZoomKeys);
package RPGClient_MapStack
{
function noHudGui::onWake(%this)
{
Parent::onWake(%this);
if ($RPGClient::Active)
{
schedule(0, 0, RPGClient_EnsureOverlay);
}
}
};
activatePackage(RPGClient_MapStack);
package RPGClient_Cursor
{
function ToggleCursor(%val)
{
Parent::ToggleCursor(%val);
if ($RPGClient::Active && isObject(Canvas))
{
$RPGClient::WantCursor = Canvas.isCursorOn();
if ($RPGClient::WantCursor)
{
RPGClient_RaiseMouseOverlay();
}
}
}
function escapeMenu::toggle(%this)
{
if (%this.isAwake())
{
Canvas.popDialog(%this);
if ($RPGClient::Active)
{
schedule(0, 0, RPGClient_EnsureCursor);
schedule(0, 0, RPGClient_EnsureOverlay);
}
return;
}
if (Canvas.getContent().getName() $= "LoadingGui")
{
disconnect();
return;
}
Canvas.pushDialog(%this);
if ($RPGClient::Active)
{
RPGClient_SetChatOpen(0);
}
}
};
activatePackage(RPGClient_Cursor);
package RPGClient_ViewLock
{
function toggleFirstPerson(%val)
{
if ($RPGClient::Active)
{
return;
}
Parent::toggleFirstPerson(%val);
}
function toggleFreeLook(%val)
{
if ($RPGClient::Active)
{
return;
}
Parent::toggleFreeLook(%val);
}
function dropCameraAtPlayer(%val)
{
if ($RPGClient::Active)
{
return;
}
Parent::dropCameraAtPlayer(%val);
}
};
activatePackage(RPGClient_ViewLock);
package RPGClient_Cleanup
{
function disconnectedCleanup(%doReconnect)
{
RPGClient_DisableOverlay();
RPGClient_UnbindKeys();
$RPGClient::Server = 0;
$RPGClient::HelloPending = 0;
$RPGClient::HelloLast = "";
cancel($RPGClient::TopDownWatchSched);
$RPGClient::TopDownWatchSched = 0;
$RPGClient::Server = 0;
$RPGClient::PlayBooted = 0;
$RPGClient::CamTickOn = 0;
RPGClient_RestoreMoveMap();
Parent::disconnectedCleanup(%doReconnect);
}
};
activatePackage(RPGClient_Cleanup);
package RPGClient_Mission
{
function onMissionDownloadComplete()
{
Parent::onMissionDownloadComplete();
schedule(250, 0, RPGClient_SendHello);
}
};
activatePackage(RPGClient_Mission);
package RPGClient_ChatKeys
{
function GlobalChat(%val)
{
Parent::GlobalChat(%val);
if ($RPGClient::Active && %val)
{
RPGClient_SetChatOpen(1);
}
}
function TeamChat(%val)
{
Parent::TeamChat(%val);
if ($RPGClient::Active && %val)
{
RPGClient_SetChatOpen(1);
}
}
};
activatePackage(RPGClient_ChatKeys);
echo("Client_RPG loaded (protocol " @ $RPGClient::Version @ ")");