From 67eef5a37f96fd68a25493f72b02195f8cb8f53f Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 28 May 2020 11:03:35 +0200 Subject: [PATCH] Fix potential desynch when a player spawns --- src/d_clisrv.c | 49 +++------------ src/d_clisrv.h | 4 +- src/d_player.h | 3 + src/g_demo.c | 2 +- src/g_game.c | 53 ++++++++++++---- src/g_game.h | 1 + src/lua_mobjlib.c | 5 +- src/m_cheat.c | 11 +++- src/p_inter.c | 10 +--- src/p_local.h | 4 ++ src/p_map.c | 21 +------ src/p_mobj.c | 6 +- src/p_polyobj.c | 5 +- src/p_saveg.c | 9 ++- src/p_spec.c | 31 +++------- src/p_telept.c | 10 +--- src/p_tick.c | 4 +- src/p_user.c | 150 ++++++++++++++++++++-------------------------- 18 files changed, 158 insertions(+), 220 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ed0b8e528..c01ca35db 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -522,6 +522,9 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->pflags = (UINT32)LONG(players[i].pflags); //pflags_t rsp->panim = (UINT8)players[i].panim; //panim_t + rsp->angleturn = (INT16)SHORT(players[i].angleturn); + rsp->oldrelangleturn = (INT16)SHORT(players[i].oldrelangleturn); + rsp->aiming = (angle_t)LONG(players[i].aiming); rsp->currentweapon = LONG(players[i].currentweapon); rsp->ringweapons = LONG(players[i].ringweapons); @@ -663,6 +666,9 @@ static void resynch_read_player(resynch_pak *rsp) players[i].pflags = (UINT32)LONG(rsp->pflags); //pflags_t players[i].panim = (UINT8)rsp->panim; //panim_t + players[i].angleturn = (INT16)SHORT(rsp->angleturn); + players[i].oldrelangleturn = (INT16)SHORT(rsp->oldrelangleturn); + players[i].aiming = (angle_t)LONG(rsp->aiming); players[i].currentweapon = LONG(rsp->currentweapon); players[i].ringweapons = LONG(rsp->ringweapons); @@ -3346,6 +3352,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) displayplayer = newplayernum; secondarydisplayplayer = newplayernum; DEBFILE("spawning me\n"); + ticcmd_oldangleturn[0] = newplayer->oldrelangleturn; } else { @@ -3353,7 +3360,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) DEBFILE("spawning my brother\n"); if (botingame) newplayer->bot = 1; + ticcmd_oldangleturn[1] = newplayer->oldrelangleturn; } + P_ForceLocalAngle(newplayer, (angle_t)(newplayer->angleturn << 16)); D_SendPlayerConfig(); addedtogame = true; @@ -3361,11 +3370,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) { if (newplayer->mo) { - if (!splitscreenplayer) - localangle = newplayer->mo->angle; - else - localangle2 = newplayer->mo->angle; - newplayer->viewheight = 41*newplayer->height/48; if (newplayer->mo->eflags & MFE_VERTICALFLIP) @@ -4721,41 +4725,6 @@ static void Local_Maketic(INT32 realtics) localcmds2.angleturn |= TICCMD_RECEIVED; } -// This function is utter bullshit and is responsible for -// the random desynch that happens when a player spawns. -// This is because ticcmds are resent to clients if a packet -// was dropped, and thus modifying them can lead to several -// clients having their ticcmds set to different values. -void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle) -{ - tic_t tic; - UINT8 numadjust = 0; - - (void)x; - (void)y; - - // Revisionist history: adjust the angles in the ticcmds received - // for this player, because they actually preceded the player - // spawning, but will be applied afterwards. - - for (tic = server ? maketic : (neededtic - 1); tic >= gametic; tic--) - { - if (numadjust++ == BACKUPTICS) - { - DEBFILE(va("SV_SpawnPlayer: All netcmds for player %d adjusted!\n", playernum)); - // We already adjusted them all, waste of time doing the same thing over and over - // This shouldn't happen normally though, either gametic was 0 (which is handled now anyway) - // or maketic >= gametic + BACKUPTICS - // -- Monster Iestyn 16/01/18 - break; - } - netcmds[tic%BACKUPTICS][playernum].angleturn = (INT16)((angle>>16) | TICCMD_RECEIVED); - - if (!tic) // failsafe for gametic == 0 -- Monster Iestyn 16/01/18 - break; - } -} - // create missed tic static void SV_Maketic(void) { diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 463240a2a..25274e97c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -171,6 +171,9 @@ typedef struct UINT32 pflags; // pflags_t UINT8 panim; // panim_t + INT16 angleturn; + INT16 oldrelangleturn; + angle_t aiming; INT32 currentweapon; INT32 ringweapons; @@ -534,7 +537,6 @@ void NetUpdate(void); void SV_StartSinglePlayerServer(void); boolean SV_SpawnServer(void); -void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle); void SV_StopServer(void); void SV_ResetServer(void); void CL_AddSplitscreenPlayer(void); diff --git a/src/d_player.h b/src/d_player.h index e5c7e7298..745f7b42f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,6 +332,9 @@ typedef struct player_s angle_t viewrollangle; + INT16 angleturn; + INT16 oldrelangleturn; + // Mouse aiming, where the guy is looking at! // It is updated with cmd->aiming. angle_t aiming; diff --git a/src/g_demo.c b/src/g_demo.c index a901e8dea..b070cbd51 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -165,7 +165,6 @@ void G_LoadMetal(UINT8 **buffer) void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) { UINT8 ziptic; - (void)playernum; if (!demo_p || !demo_start) return; @@ -183,6 +182,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) oldcmd.aiming = READINT16(demo_p); G_CopyTiccmd(cmd, &oldcmd, 1); + players[playernum].angleturn = cmd->angleturn; if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) { diff --git a/src/g_game.c b/src/g_game.c index 5bcf9f580..2560c2b32 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1065,6 +1065,7 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn +INT16 ticcmd_oldangleturn[2]; boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) @@ -1140,7 +1141,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG) && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) {//@TODO splitscreen player - cmd->angleturn = (INT16)(*myangle >> 16); + cmd->angleturn = ticcmd_oldangleturn[forplayer]; cmd->aiming = G_ClipAimingPitch(myaiming); return; } @@ -1361,7 +1362,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (controlstyle == CS_SIMPLE && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { CV_SetValue(&cv_directionchar[forplayer], 2); - *myangle = player->mo->angle; + cmd->angleturn = (INT16)((player->mo->angle - *myangle) >> 16); *myaiming = 0; if (cv_cam_lockonboss[forplayer].value) @@ -1430,7 +1431,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else if (anglediff < -maxturn) anglediff = -maxturn; - *myangle += anglediff; + cmd->angleturn = (INT16)(cmd->angleturn + (anglediff >> 16)); } } } @@ -1567,19 +1568,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) B_HandleFlightIndicator(player); } else if (player->bot == 2) - *myangle = localangle; // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + cmd->angleturn = (INT16)((localangle - *myangle) >> 16); + + *myangle += (cmd->angleturn<<16); if (controlstyle == CS_LMAOGALOG) { + angle_t angle; + if (player->awayviewtics) - cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); + angle = player->awayviewmobj->angle; else - cmd->angleturn = (INT16)(thiscam->angle >> 16); + angle = thiscam->angle; + + cmd->angleturn = (INT16)((angle - (ticcmd_oldangleturn[forplayer] << 16)) >> 16); } else { - *myangle += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(*myangle >> 16); - // Adjust camera angle by player input if (controlstyle == CS_SIMPLE && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { @@ -1589,13 +1594,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); fixed_t factor; + INT16 camadjust; if ((sine > 0) == (cmd->sidemove > 0)) sine = 0; // Prevent jerking right when braking from going left, or vice versa factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); - *myangle -= cmd->sidemove * factor * camadjustfactor; + camadjust = (cmd->sidemove * factor * camadjustfactor) >> 16; + + *myangle -= camadjust << 16; + cmd->angleturn = (INT16)(cmd->angleturn - camadjust); } if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) @@ -1632,9 +1641,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { angle_t controlangle; INT32 anglediff; + INT16 camadjust; if ((cmd->forwardmove || cmd->sidemove) && !(player->pflags & PF_SPINNING)) - controlangle = (cmd->angleturn<<16) + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + controlangle = *myangle + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); else controlangle = player->drawangle + drawangleoffset; @@ -1651,7 +1661,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) anglediff = FixedMul(anglediff, sine); } - *myangle += FixedMul(anglediff, camadjustfactor); + camadjust = FixedMul(anglediff, camadjustfactor) >> 16; + + *myangle += camadjust << 16; + cmd->angleturn = (INT16)(cmd->angleturn + camadjust); } } } @@ -1665,6 +1678,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) LUAh_ViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } + + cmd->angleturn = (INT16)(cmd->angleturn + ticcmd_oldangleturn[forplayer]); + ticcmd_oldangleturn[forplayer] = cmd->angleturn; } ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) @@ -2205,11 +2221,16 @@ void G_Ticker(boolean run) buf = gametic % BACKUPTICS; - // read/write demo and check turbo cheat for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) + { G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); + + players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; + players[i].oldrelangleturn = players[i].cmd.angleturn; + players[i].cmd.angleturn = players[i].angleturn; + } } // do main actions @@ -2392,6 +2413,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) SINT8 pity; INT16 rings; INT16 spheres; + INT16 playerangleturn; + INT16 oldrelangleturn; score = players[player].score; lives = players[player].lives; @@ -2403,6 +2426,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) spectator = players[player].spectator; outofcoop = players[player].outofcoop; pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); + playerangleturn = players[player].angleturn; + oldrelangleturn = players[player].oldrelangleturn; if (!betweenmaps) pflags |= (players[player].pflags & PF_FINISHED); @@ -2474,6 +2499,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->quittime = quittime; p->spectator = spectator; p->outofcoop = outofcoop; + p->angleturn = playerangleturn; + p->oldrelangleturn = oldrelangleturn; // save player config truth reborn p->skincolor = skincolor; diff --git a/src/g_game.h b/src/g_game.h index df0c9392e..21fa682b7 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -93,6 +93,7 @@ typedef enum // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); +extern INT16 ticcmd_oldangleturn[2]; extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 81729b788..62b5d736f 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -449,10 +449,7 @@ static int mobj_set(lua_State *L) return UNIMPLEMENTED; case mobj_angle: mo->angle = luaL_checkangle(L, 3); - if (mo->player == &players[consoleplayer]) - localangle = mo->angle; - else if (mo->player == &players[secondarydisplayplayer]) - localangle2 = mo->angle; + P_SetPlayerAngle(mo->player, mo->angle); break; case mobj_rollangle: mo->rollangle = luaL_checkangle(L, 3); diff --git a/src/m_cheat.c b/src/m_cheat.c index 156c5db16..98e309a55 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -555,7 +555,8 @@ void Command_Teleport_f(void) p->mo->flags2 &= ~MF2_OBJECTFLIP; } - localangle = p->mo->angle = p->drawangle = FixedAngle(mt->angle<mo->angle = p->drawangle = FixedAngle(mt->angle<mo->angle); } else // scan the thinkers to find starposts... { @@ -619,7 +620,8 @@ void Command_Teleport_f(void) p->mo->flags2 &= ~MF2_OBJECTFLIP; } - localangle = p->mo->angle = p->drawangle = mo2->angle; + p->mo->angle = p->drawangle = mo2->angle; + P_SetPlayerAngle(p, p->mo->angle); } CONS_Printf(M_GetText("Teleporting to checkpoint %d, %d...\n"), starpostnum, starpostpath); @@ -673,7 +675,10 @@ void Command_Teleport_f(void) i = COM_CheckParm("-ang"); if (i) - localangle = p->drawangle = p->mo->angle = FixedAngle(atoi(COM_Argv(i + 1))<drawangle = p->mo->angle = FixedAngle(atoi(COM_Argv(i + 1))<mo->angle); + } i = COM_CheckParm("-aim"); if (i) diff --git a/src/p_inter.c b/src/p_inter.c index 3d2c5e45e..052ecc0da 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1143,10 +1143,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->angle = special->angle; - if (player == &players[consoleplayer]) - localangle = toucher->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = toucher->angle; + P_SetPlayerAngle(player, toucher->angle); P_ResetPlayer(player); @@ -1564,10 +1561,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) #if 0 // camera redirection - deemed unnecessary toucher->angle = special->angle; - if (player == &players[consoleplayer]) - localangle = toucher->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = toucher->angle; + P_SetPlayerAngle(player, toucher->angle); #endif S_StartSound(toucher, special->info->attacksound); // home run diff --git a/src/p_local.h b/src/p_local.h index becb045f7..e89343ca8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -138,6 +138,10 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_ResetPlayer(player_t *player); boolean P_PlayerCanDamage(player_t *player, mobj_t *thing); boolean P_IsLocalPlayer(player_t *player); +void P_SetPlayerAngle(player_t *player, angle_t angle); +angle_t P_GetLocalAngle(player_t *player); +void P_SetLocalAngle(player_t *player, angle_t angle); +void P_ForceLocalAngle(player_t *player, angle_t angle); boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 6e4992473..e3038e87f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -372,12 +372,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->angle = object->player->drawangle = spring->angle; if (!demoplayback || P_ControlStyle(object->player) == CS_LMAOGALOG) - { - if (object->player == &players[consoleplayer]) - localangle = spring->angle; - else if (object->player == &players[secondarydisplayplayer]) - localangle2 = spring->angle; - } + P_SetPlayerAngle(object->player, spring->angle); } if (object->player->pflags & PF_GLIDING) @@ -1310,12 +1305,7 @@ static boolean PIT_CheckThing(mobj_t *thing) thing->angle = tmthing->angle; if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) - { - if (thing->player == &players[consoleplayer]) - localangle = thing->angle; - else if (thing->player == &players[secondarydisplayplayer]) - localangle2 = thing->angle; - } + P_SetPlayerAngle(thing->player, thing->angle); return true; } @@ -3409,12 +3399,7 @@ isblocking: { slidemo->angle = climbangle; /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ + P_SetPlayerAngle(slidemo->player, slidemo->angle);*/ if (!slidemo->player->climbing) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 4124c47a9..3d50b0439 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11388,10 +11388,7 @@ void P_AfterPlayerSpawn(INT32 playernum) player_t *p = &players[playernum]; mobj_t *mobj = p->mo; - if (playernum == consoleplayer) - localangle = mobj->angle; - else if (playernum == secondarydisplayplayer) - localangle2 = mobj->angle; + P_SetPlayerAngle(p, mobj->angle); p->viewheight = 41*p->height/48; @@ -11408,7 +11405,6 @@ void P_AfterPlayerSpawn(INT32 playernum) HU_Start(); } - SV_SpawnPlayer(playernum, mobj->x, mobj->y, mobj->angle); p->drawangle = mobj->angle; if (camera.chase) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 3b6195285..ca21a36cc 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1156,10 +1156,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; - if (mo->player == &players[consoleplayer]) - localangle += delta; - else if (mo->player == &players[secondarydisplayplayer]) - localangle2 += delta; + P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index bec64ed35..a4cdd5148 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -103,6 +103,8 @@ static void P_NetArchivePlayers(void) // no longer send ticcmds, player name, skin, or color + WRITEINT16(save_p, players[i].angleturn); + WRITEINT16(save_p, players[i].oldrelangleturn); WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].viewrollangle); @@ -311,6 +313,8 @@ static void P_NetUnArchivePlayers(void) // sending player names, skin and color should not be necessary at all! // (that data is handled in the server config now) + players[i].angleturn = READINT16(save_p); + players[i].oldrelangleturn = READINT16(save_p); players[i].aiming = READANGLE(save_p); players[i].drawangle = READANGLE(save_p); players[i].viewrollangle = READANGLE(save_p); @@ -2547,11 +2551,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) i = READUINT8(save_p); mobj->player = &players[i]; mobj->player->mo = mobj; - // added for angle prediction - if (consoleplayer == i) - localangle = mobj->angle; - if (secondarydisplayplayer == i) - localangle2 = mobj->angle; } if (diff & MD_MOVEDIR) mobj->movedir = READANGLE(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index d45a33c47..85546a97a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4602,12 +4602,7 @@ DoneSection2: player->mo->angle = player->drawangle = lineangle; if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); if (!(lines[i].flags & ML_EFFECT4)) { @@ -8865,24 +8860,12 @@ void T_Pusher(pusher_t *p) if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { - if (thing->player == &players[consoleplayer]) - { - if (thing->angle - localangle > ANGLE_180) - localangle -= (localangle - thing->angle) / 8; - else - localangle += (thing->angle - localangle) / 8; - } - else if (thing->player == &players[secondarydisplayplayer]) - { - if (thing->angle - localangle2 > ANGLE_180) - localangle2 -= (localangle2 - thing->angle) / 8; - else - localangle2 += (thing->angle - localangle2) / 8; - } - /*if (thing->player == &players[consoleplayer]) - localangle = thing->angle; - else if (thing->player == &players[secondarydisplayplayer]) - localangle2 = thing->angle;*/ + angle_t angle = thing->player->angleturn << 16; + if (thing->angle - angle > ANGLE_180) + P_SetPlayerAngle(thing->player, angle - (angle - thing->angle) / 8); + else + P_SetPlayerAngle(thing->player, angle + (thing->angle - angle) / 8); + //P_SetPlayerAngle(thing->player, thing->angle); } } diff --git a/src/p_telept.c b/src/p_telept.c index 600d40c88..f6feddf4b 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -63,10 +63,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, thing->reactiontime = TICRATE/2; // don't move for about half a second // absolute angle position - if (thing == players[consoleplayer].mo) - localangle = angle; - if (thing == players[secondarydisplayplayer].mo) - localangle2 = angle; + P_SetPlayerAngle(thing->player, angle); // move chasecam at new player location if (splitscreen && camera2.chase @@ -165,10 +162,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle thing->player->drawangle += (angle - thing->angle); // absolute angle position - if (thing->player == &players[consoleplayer]) - localangle = angle; - if (thing->player == &players[secondarydisplayplayer]) - localangle2 = angle; + P_SetPlayerAngle(thing->player, angle); // move chasecam at new player location if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer]) diff --git a/src/p_tick.c b/src/p_tick.c index 7ea6edb2d..55b545856 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -770,7 +770,9 @@ void P_PreTicker(INT32 frames) memcpy(&temptic, &players[i].cmd, sizeof(ticcmd_t)); memset(&players[i].cmd, 0, sizeof(ticcmd_t)); // correct angle on spawn... - players[i].cmd.angleturn = temptic.angleturn; + players[i].angleturn += temptic.angleturn - players[i].oldrelangleturn; + players[i].oldrelangleturn = temptic.angleturn; + players[i].cmd.angleturn = players[i].angleturn; P_PlayerThink(&players[i]); diff --git a/src/p_user.c b/src/p_user.c index ca1001f57..c22e29397 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3557,22 +3557,11 @@ static void P_DoClimbing(player_t *player) #define CLIMBCONEMAX FixedAngle(90*FRACUNIT) if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { - if (player == &players[consoleplayer]) - { - angle_t angdiff = localangle - player->mo->angle; - if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) - localangle = player->mo->angle + CLIMBCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) - localangle = player->mo->angle - CLIMBCONEMAX; - } - else if (player == &players[secondarydisplayplayer]) - { - angle_t angdiff = localangle2 - player->mo->angle; - if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) - localangle2 = player->mo->angle + CLIMBCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) - localangle2 = player->mo->angle - CLIMBCONEMAX; - } + angle_t angdiff = P_GetLocalAngle(player) - player->mo->angle; + if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) + P_SetLocalAngle(player, player->mo->angle + CLIMBCONEMAX); + else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) + P_SetLocalAngle(player, player->mo->angle - CLIMBCONEMAX); } if (player->climbing == 0) @@ -4358,12 +4347,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; // Adjust the local control angle. - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); player->climbing = 0; // Stop climbing, duh! P_InstaThrust(player->mo, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); // Jump off the wall. @@ -4686,12 +4670,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } else { @@ -5311,9 +5290,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) /*if (!demoplayback) { if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) - localangle = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle);; else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); }*/ } break; @@ -5718,10 +5697,7 @@ static void P_2dMovement(player_t *player) player->mo->angle = ANGLE_180; } - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); if (player->pflags & PF_GLIDING) movepushangle = player->mo->angle; @@ -7558,10 +7534,7 @@ static void P_NiGHTSMovement(player_t *player) else player->mo->rollangle = rollangle; - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); // Check for crushing in our new location if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) @@ -8510,10 +8483,7 @@ static void P_MovePlayer(player_t *player) player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); // Update the local angle control. - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); } if (player->climbing == 1) @@ -8789,11 +8759,7 @@ static void P_DoZoomTube(player_t *player) if (player->mo->tracer) { player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); - - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); } } @@ -9250,12 +9216,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target { source->player->drawangle = source->angle; if (!demoplayback || P_ControlStyle(source->player) == CS_LMAOGALOG) - { - if (source->player == &players[consoleplayer]) - localangle = source->angle; - else if (source->player == &players[secondarydisplayplayer]) - localangle2 = source->angle; - } + P_SetPlayerAngle(source->player, source->angle); } // change slope @@ -9696,7 +9657,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) if ((thiscam == &camera && G_ControlStyle(1) == CS_SIMPLE) || (thiscam == &camera2 && G_ControlStyle(2) == CS_SIMPLE)) { - thiscam->angle = (thiscam == &camera) ? localangle : localangle2; + thiscam->angle = P_GetLocalAngle(player); thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; } else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog[0].value)) @@ -9897,9 +9858,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player == &players[consoleplayer]) { if (focusangle >= localangle) - localangle += abs((signed)(focusangle - localangle))>>5; + P_ForceLocalAngle(player, localangle + (abs((signed)(focusangle - localangle))>>5)); else - localangle -= abs((signed)(focusangle - localangle))>>5; + P_ForceLocalAngle(player, localangle - (abs((signed)(focusangle - localangle))>>5)); } } else @@ -10873,21 +10834,13 @@ static void P_MinecartThink(player_t *player) if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) { - angle_t *ang = NULL; + angdiff = P_GetLocalAngle(player) - minecart->angle; + if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) + P_SetLocalAngle(player, minecart->angle + MINECARTCONEMAX); + else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) + P_SetLocalAngle(player, minecart->angle - MINECARTCONEMAX); - if (player == &players[consoleplayer]) - ang = &localangle; - else if (player == &players[secondarydisplayplayer]) - ang = &localangle2; - if (ang) - { - angdiff = *ang - minecart->angle; - if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) - *ang = minecart->angle + MINECARTCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) - *ang = minecart->angle - MINECARTCONEMAX; - } } } @@ -10964,10 +10917,7 @@ static void P_MinecartThink(player_t *player) if (angdiff && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) // maintain relative angle on turns { player->mo->angle += angdiff; - if (player == &players[consoleplayer]) - localangle += angdiff; - else if (player == &players[secondarydisplayplayer]) - localangle2 += angdiff; + P_SetPlayerAngle(player, (angle_t)(player->angleturn << 16) + angdiff); } // Sideways detection @@ -12520,12 +12470,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->angle = tails->angle; if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) @@ -12609,12 +12554,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->angle += cmd->sidemove< ANGLE_MAX if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; // Adjust the local control angle. - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } } break; @@ -12826,3 +12766,43 @@ void P_PlayerAfterThink(player_t *player) } } } + +void P_SetPlayerAngle(player_t *player, angle_t angle) +{ + INT16 delta = (INT16)(angle >> 16) - player->angleturn; + + P_ForceLocalAngle(player, P_GetLocalAngle(player) + (delta << 16)); + player->angleturn += delta; +} + +void P_SetLocalAngle(player_t *player, angle_t angle) +{ + INT16 delta = (INT16)((angle - P_GetLocalAngle(player)) >> 16); + + P_ForceLocalAngle(player, P_GetLocalAngle(player) + (angle_t)(delta << 16)); + + if (player == &players[consoleplayer]) + ticcmd_oldangleturn[0] += delta; + else if (player == &players[secondarydisplayplayer]) + ticcmd_oldangleturn[1] += delta; +} + +angle_t P_GetLocalAngle(player_t *player) +{ + if (player == &players[consoleplayer]) + return localangle; + else if (player == &players[secondarydisplayplayer]) + return localangle2; + else + return 0; +} + +void P_ForceLocalAngle(player_t *player, angle_t angle) +{ + angle = angle >> 16 << 16; + + if (player == &players[consoleplayer]) + localangle = angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = angle; +}