Fix cam jitter, zoom sync, click pick (client scalars + server click cam)

This commit is contained in:
RallyBlock committed 2026-11-10 02:04:33 -05:00
1 parent 59b7b3e4df
commit 43d8fddbc2
1 file changed
+130 -57
+130 -57
View File
@@ -26,6 +26,8 @@ $RPGClient::YawSpeed = 0.045;
$RPGClient::ZoomSpeed = 0.12; $RPGClient::ZoomSpeed = 0.12;
$RPGClient::CamTickSched = 0; $RPGClient::CamTickSched = 0;
$RPGClient::LastCamSync = 0; $RPGClient::LastCamSync = 0;
$RPGClient::CamSyncMs = 100;
$RPGClient::TopDownFov = 0.85;
$RPGClient::MvF = 0; $RPGClient::MvF = 0;
$RPGClient::MvB = 0; $RPGClient::MvB = 0;
$RPGClient::MvL = 0; $RPGClient::MvL = 0;
@@ -135,6 +137,113 @@ function RPGClient_Aspect()
return %h > 0 ? %w / %h : 1.333; 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) function RPGClient_SendClick(%button, %pos)
{ {
if (!isObject(ServerConnection)) if (!isObject(ServerConnection))
@@ -148,8 +257,18 @@ function RPGClient_SendClick(%button, %pos)
} }
$RPGClient::LastClickTime = %now; $RPGClient::LastClickTime = %now;
%norm = RPGClient_NormScreenPos(%pos); %norm = RPGClient_NormScreenPos(%pos);
commandToServer('RPG_Click', %button, getWord(%norm, 0), getWord(%norm, 1), RPGClient_Aspect()); %nx = getWord(%norm, 0);
schedule(1, 0, RPGClient_ApplyCamera, 1); %ny = getWord(%norm, 1);
if (%button == 0)
{
%gnd = RPGClient_PickGround(%nx, %ny);
if (%gnd !$= "")
{
commandToServer('RPG_Go', getWord(%gnd, 0), getWord(%gnd, 1), getWord(%gnd, 2));
return;
}
}
commandToServer('RPG_Click', %button, %nx, %ny, RPGClient_Aspect(), $RPGClient::Yaw, $RPGClient::Dist, $RPGClient::Pitch, $RPGClient::PanX, $RPGClient::PanY);
} }
function RPGClient_Mouse::onMouseDown(%this, %mod, %pos, %clicks) function RPGClient_Mouse::onMouseDown(%this, %mod, %pos, %clicks)
@@ -250,26 +369,6 @@ function RPGClient_CameraTick()
%tilt = $RPGClient::PitchSpeed * 2.5; %tilt = $RPGClient::PitchSpeed * 2.5;
%zoom = $RPGClient::ZoomSpeed * 2.5; %zoom = $RPGClient::ZoomSpeed * 2.5;
%changed = 0; %changed = 0;
if ($mvLeftAction > 0)
{
$RPGClient::Yaw = $RPGClient::Yaw - %spin * $mvLeftAction;
%changed = 1;
}
if ($mvRightAction > 0)
{
$RPGClient::Yaw = $RPGClient::Yaw + %spin * $mvRightAction;
%changed = 1;
}
if ($mvForwardAction > 0)
{
$RPGClient::Pitch = getMin($RPGClient::PitchMax, $RPGClient::Pitch + %tilt * $mvForwardAction);
%changed = 1;
}
if ($mvBackwardAction > 0)
{
$RPGClient::Pitch = getMax($RPGClient::PitchMin, $RPGClient::Pitch - %tilt * $mvBackwardAction);
%changed = 1;
}
if ($RPGClient::MvL > 0) if ($RPGClient::MvL > 0)
{ {
$RPGClient::Yaw = $RPGClient::Yaw - %spin * $RPGClient::MvL; $RPGClient::Yaw = $RPGClient::Yaw - %spin * $RPGClient::MvL;
@@ -290,14 +389,17 @@ function RPGClient_CameraTick()
$RPGClient::Pitch = getMax($RPGClient::PitchMin, $RPGClient::Pitch - %tilt * $RPGClient::MvB); $RPGClient::Pitch = getMax($RPGClient::PitchMin, $RPGClient::Pitch - %tilt * $RPGClient::MvB);
%changed = 1; %changed = 1;
} }
RPGClient_ApplyCamera(%changed || $RPGClient::MvF || $RPGClient::MvB || $RPGClient::MvL || $RPGClient::MvR); if (%changed || $RPGClient::MvF || $RPGClient::MvB || $RPGClient::MvL || $RPGClient::MvR)
$RPGClient::CamTickSched = schedule(32, 0, RPGClient_CameraTick); {
RPGClient_ApplyCamera(0);
}
$RPGClient::CamTickSched = schedule(50, 0, RPGClient_CameraTick);
} }
function RPGClient_StartCameraTick() function RPGClient_StartCameraTick()
{ {
cancel($RPGClient::CamTickSched); cancel($RPGClient::CamTickSched);
$RPGClient::CamTickSched = schedule(32, 0, RPGClient_CameraTick); $RPGClient::CamTickSched = schedule(50, 0, RPGClient_CameraTick);
} }
function RPGClient_InPlay() function RPGClient_InPlay()
@@ -383,10 +485,6 @@ function RPGClient_KeyMvForward(%val)
return; return;
} }
$RPGClient::MvF = %val; $RPGClient::MvF = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_KeyMvBackward(%val) function RPGClient_KeyMvBackward(%val)
@@ -405,10 +503,6 @@ function RPGClient_KeyMvBackward(%val)
return; return;
} }
$RPGClient::MvB = %val; $RPGClient::MvB = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_KeyMvLeft(%val) function RPGClient_KeyMvLeft(%val)
@@ -427,10 +521,6 @@ function RPGClient_KeyMvLeft(%val)
return; return;
} }
$RPGClient::MvL = %val; $RPGClient::MvL = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_KeyMvRight(%val) function RPGClient_KeyMvRight(%val)
@@ -449,10 +539,6 @@ function RPGClient_KeyMvRight(%val)
return; return;
} }
$RPGClient::MvR = %val; $RPGClient::MvR = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_StockMoveMapBinds() function RPGClient_StockMoveMapBinds()
@@ -597,7 +683,7 @@ function RPGClient_Hud_Place()
function RPGClient_ApplyCamera(%forceSync) function RPGClient_ApplyCamera(%forceSync)
{ {
%now = getSimTime(); %now = getSimTime();
%doSync = %forceSync || %now - $RPGClient::LastCamSync >= 40; %doSync = %forceSync || %now - $RPGClient::LastCamSync >= $RPGClient::CamSyncMs;
if (!%doSync || !isObject(ServerConnection)) if (!%doSync || !isObject(ServerConnection))
{ {
return; return;
@@ -647,11 +733,7 @@ function RPGClient_ApplyCamera(%forceSync)
function RPGClient_ScheduleCamera() function RPGClient_ScheduleCamera()
{ {
cancel($RPGClient::CamSched); cancel($RPGClient::CamSched);
$RPGClient::CamSched = schedule(50, 0, RPGClient_ApplyCamera, 0); RPGClient_ApplyCamera(1);
schedule(200, 0, RPGClient_ApplyCamera, 0);
schedule(500, 0, RPGClient_ApplyCamera, 0);
schedule(1200, 0, RPGClient_ApplyCamera, 0);
schedule(2500, 0, RPGClient_ApplyCamera, 0);
} }
function RPGClient_YawLeft(%val) function RPGClient_YawLeft(%val)
@@ -665,10 +747,6 @@ function RPGClient_YawLeft(%val)
return; return;
} }
$RPGClient::MvL = %val; $RPGClient::MvL = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_YawRight(%val) function RPGClient_YawRight(%val)
@@ -682,10 +760,6 @@ function RPGClient_YawRight(%val)
return; return;
} }
$RPGClient::MvR = %val; $RPGClient::MvR = %val;
if (%val)
{
RPGClient_ApplyCamera(1);
}
} }
function RPGClient_ZoomIn(%val) function RPGClient_ZoomIn(%val)
@@ -883,7 +957,6 @@ function clientCmdRPG_TopDown(%on, %yaw, %dist)
RPGClient_StartCameraTick(); RPGClient_StartCameraTick();
schedule(500, 0, RPGClient_EnsureOverlay); schedule(500, 0, RPGClient_EnsureOverlay);
schedule(1500, 0, RPGClient_EnsureOverlay); schedule(1500, 0, RPGClient_EnsureOverlay);
RPGClient_ScheduleCamera();
RPGClient_EnsureCursor(); RPGClient_EnsureCursor();
RPGClient_Hud_Ensure(); RPGClient_Hud_Ensure();
} }
@@ -1156,7 +1229,7 @@ package RPGClient_Input
{ {
%sens = $pref::Input::MouseSensitivity; %sens = $pref::Input::MouseSensitivity;
$RPGClient::Yaw = $RPGClient::Yaw + %val * %sens * 0.004; $RPGClient::Yaw = $RPGClient::Yaw + %val * %sens * 0.004;
RPGClient_ApplyCamera(1); RPGClient_ApplyCamera(0);
return; return;
} }
Parent::yaw(%val); Parent::yaw(%val);