mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 12:01:47 +00:00
Bring back camera turn prediction
REALLY complicated, because just emulating player turning in ticcmd code is broken.
This commit is contained in:
parent
5ae8664b70
commit
4b149c103c
6 changed files with 80 additions and 18 deletions
|
|
@ -52,6 +52,9 @@ typedef enum
|
|||
// ticcmd turning bits
|
||||
#define TICCMD_REDUCE 16
|
||||
|
||||
// ticcmd latency mask
|
||||
#define TICCMD_LATENCYMASK 0xFF
|
||||
|
||||
// ticcmd flags
|
||||
#define TICCMD_RECEIVED 1
|
||||
#define TICCMD_TYPING 2/* chat window or console open */
|
||||
|
|
|
|||
37
src/g_game.c
37
src/g_game.c
|
|
@ -871,6 +871,35 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect
|
|||
INT32 localaiming[MAXSPLITSCREENPLAYERS];
|
||||
angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
INT32 localsteering[MAXSPLITSCREENPLAYERS];
|
||||
INT32 localdelta[MAXSPLITSCREENPLAYERS];
|
||||
INT32 localstoredeltas[MAXSPLITSCREENPLAYERS][TICCMD_LATENCYMASK + 1];
|
||||
UINT8 localtic;
|
||||
|
||||
// Turning was removed from G_BuildTiccmd to prevent easy client hacking.
|
||||
// This brings back the camera prediction that was lost.
|
||||
static void G_DoAnglePrediction(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, player_t *player)
|
||||
{
|
||||
INT32 angleChange = 0;
|
||||
|
||||
localtic = cmd->latency;
|
||||
|
||||
while (realtics > 0)
|
||||
{
|
||||
localsteering[ssplayer - 1] = K_UpdateSteeringValue(localsteering[ssplayer - 1], cmd->turning);
|
||||
angleChange = K_GetKartTurnValue(player, localsteering[ssplayer - 1]) << TICCMD_REDUCE;
|
||||
|
||||
// Store the angle we applied to this tic, so we can revert it later.
|
||||
// If we trust the camera to do all of the work, then it can get out of sync fast.
|
||||
localstoredeltas[ssplayer - 1][cmd->latency] += angleChange;
|
||||
localdelta[ssplayer - 1] += angleChange;
|
||||
|
||||
realtics--;
|
||||
}
|
||||
|
||||
localangle[ssplayer - 1] = player->angleturn + localdelta[ssplayer - 1];
|
||||
}
|
||||
|
||||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
{
|
||||
const UINT8 forplayer = ssplayer-1;
|
||||
|
|
@ -896,8 +925,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
boolean *rd = &resetdown[forplayer];
|
||||
const boolean mouseaiming = player->spectator;
|
||||
|
||||
(void)realtics;
|
||||
|
||||
if (demo.playback) return;
|
||||
|
||||
// Is there any reason this can't just be I_BaseTiccmd?
|
||||
|
|
@ -1148,7 +1175,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
|
||||
// Send leveltime when this tic was generated to the server for control lag calculations.
|
||||
// Only do this when in a level. Also do this after the hook, so that it can't overwrite this.
|
||||
cmd->latency = (leveltime & 0xFF);
|
||||
cmd->latency = (leveltime & TICCMD_LATENCYMASK);
|
||||
}
|
||||
|
||||
if (cmd->forwardmove > MAXPLMOVE)
|
||||
|
|
@ -1161,6 +1188,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
else if (cmd->turning < -KART_FULLTURN)
|
||||
cmd->turning = -KART_FULLTURN;
|
||||
|
||||
G_DoAnglePrediction(cmd, realtics, ssplayer, player);
|
||||
|
||||
// Reset away view if a command is given.
|
||||
if ((cmd->forwardmove || cmd->buttons)
|
||||
&& !r_splitscreen && displayplayers[0] != consoleplayer && ssplayer == 1)
|
||||
|
|
@ -1925,7 +1954,7 @@ void G_Ticker(boolean run)
|
|||
else
|
||||
{
|
||||
//@TODO add a cvar to allow setting this max
|
||||
cmd->latency = min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1);
|
||||
cmd->latency = min(((leveltime & TICCMD_LATENCYMASK) - cmd->latency) & TICCMD_LATENCYMASK, MAXPREDICTTICS-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ INT32 PlayerJoyAxis(UINT8 player, axis_input_e axissel);
|
|||
|
||||
extern angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
|
||||
extern INT32 localsteering[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localdelta[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localstoredeltas[MAXSPLITSCREENPLAYERS][TICCMD_LATENCYMASK + 1];
|
||||
extern UINT8 localtic;
|
||||
|
||||
//
|
||||
// GAME
|
||||
|
|
|
|||
13
src/k_kart.c
13
src/k_kart.c
|
|
@ -8089,31 +8089,34 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
|
|||
return basedrift + (FixedMul(driftadjust * FRACUNIT, countersteer) / FRACUNIT);
|
||||
}
|
||||
|
||||
void K_UpdateSteeringValue(player_t *player, INT16 destSteering)
|
||||
INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering)
|
||||
{
|
||||
// player->steering is the turning value, but with easing applied.
|
||||
// Keeps micro-turning from old easing, but isn't controller dependent.
|
||||
|
||||
const INT16 amount = KART_FULLTURN/4;
|
||||
INT16 diff = destSteering - player->steering;
|
||||
INT16 diff = destSteering - inputSteering;
|
||||
INT16 outputSteering = inputSteering;
|
||||
|
||||
if (abs(diff) <= amount)
|
||||
{
|
||||
// Reached the intended value, set instantly.
|
||||
player->steering = destSteering;
|
||||
outputSteering = destSteering;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go linearly towards the value we wanted.
|
||||
if (diff < 0)
|
||||
{
|
||||
player->steering -= amount;
|
||||
outputSteering -= amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->steering += amount;
|
||||
outputSteering += amount;
|
||||
}
|
||||
}
|
||||
|
||||
return outputSteering;
|
||||
}
|
||||
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
|
|||
INT32 K_GetKartRingPower(player_t *player, boolean boosted);
|
||||
void K_UpdateDistanceFromFinishLine(player_t *const player);
|
||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||
void K_UpdateSteeringValue(player_t *player, INT16 destSteering);
|
||||
INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering);
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
||||
INT32 K_GetUnderwaterTurnAdjust(player_t *player);
|
||||
INT32 K_GetKartDriftSparkValue(player_t *player);
|
||||
|
|
|
|||
39
src/p_user.c
39
src/p_user.c
|
|
@ -1988,14 +1988,41 @@ static void P_3dMovement(player_t *player)
|
|||
static void P_UpdatePlayerAngle(player_t *player)
|
||||
{
|
||||
angle_t angleChange = ANGLE_MAX;
|
||||
UINT8 p = UINT8_MAX;
|
||||
UINT8 i;
|
||||
|
||||
K_UpdateSteeringValue(player, player->cmd.turning);
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
p = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
player->steering = K_UpdateSteeringValue(player->steering, player->cmd.turning);
|
||||
angleChange = K_GetKartTurnValue(player, player->steering) << TICCMD_REDUCE;
|
||||
|
||||
P_SetPlayerAngle(player, player->angleturn + angleChange);
|
||||
player->angleturn += angleChange;
|
||||
player->mo->angle = player->angleturn;
|
||||
|
||||
if (p != UINT8_MAX)
|
||||
{
|
||||
UINT8 lateTic = ((leveltime - player->cmd.latency) & TICCMD_LATENCYMASK);
|
||||
UINT8 clearTic = ((localtic + 1) & TICCMD_LATENCYMASK);
|
||||
|
||||
// Undo the ticcmd's old emulated angle,
|
||||
// now that we added the actual game logic angle.
|
||||
|
||||
while (lateTic != clearTic)
|
||||
{
|
||||
localdelta[p] -= localstoredeltas[p][lateTic];
|
||||
localstoredeltas[p][lateTic] = 0;
|
||||
|
||||
lateTic = (lateTic - 1) & TICCMD_LATENCYMASK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cv_allowmlook.value || player->spectator == false)
|
||||
{
|
||||
player->aiming = 0;
|
||||
|
|
@ -2006,13 +2033,9 @@ static void P_UpdatePlayerAngle(player_t *player)
|
|||
player->aiming = G_ClipAimingPitch((INT32 *)&player->aiming);
|
||||
}
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
if (p != UINT8_MAX)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
localaiming[i] = player->aiming;
|
||||
break;
|
||||
}
|
||||
localaiming[p] = player->aiming;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue