From f2109c026bdb6767de5403554b5f8e4b8d605e27 Mon Sep 17 00:00:00 2001 From: skyjake Date: Thu, 24 Mar 2011 19:18:49 +0200 Subject: [PATCH] Client: Fixing mobj/clmobj flags Trying to make sense of when flags are set and unset. Added assertions for the solid and remote flags. The client is now able to move after respawning. The logic is still that the real mobj is solid and not remote, and handled by the client's game logic, while the clmobj is not solid and remote, and updated by the server when necessary. --- .gitignore | 3 +- doomsday/engine/portable/src/cl_main.c | 43 ++++++++++++++++++++++++ doomsday/engine/portable/src/cl_mobj.c | 6 +++- doomsday/engine/portable/src/cl_player.c | 16 +++++---- doomsday/engine/portable/src/p_maputil.c | 2 +- doomsday/plugins/common/src/d_netcl.c | 5 +-- doomsday/plugins/common/src/p_user.c | 34 +++++++++++++++++++ 7 files changed, 97 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 2de108bb23..2011dc353e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .directory .DS_Store -/doomsday/build/win32/license.txt \ No newline at end of file +/doomsday/build/win32/license.txt +*.user.* diff --git a/doomsday/engine/portable/src/cl_main.c b/doomsday/engine/portable/src/cl_main.c index 2df3b8510a..28c7479b1f 100644 --- a/doomsday/engine/portable/src/cl_main.c +++ b/doomsday/engine/portable/src/cl_main.c @@ -384,6 +384,45 @@ Con_Printf("Cl_GetPackets: Packet (type %i) was discarded!\n", } } +/** + * Check the state of the client on engineside. This is a debugging utility + * and only gets called when _DEBUG is defined. + */ +void Cl_Assertions(int plrNum) +{ + player_t *plr; + mobj_t *clmo, *mo; + clplayerstate_t *s; + + if(!isClient || !Cl_GameReady() || clientPaused) return; + if(plrNum < 0 || plrNum >= DDMAXPLAYERS) return; + + plr = &ddPlayers[plrNum]; + s = &clPlayerStates[plrNum]; + + // Must have a mobj! + if(!s->cmo || !plr->shared.mo) + return; + + clmo = &s->cmo->mo; + mo = plr->shared.mo; + + /* + Con_Message("Assert: client %i, clmo %i (flags 0x%x)\n", + plrNum, clmo->thinker.id, clmo->ddFlags); + */ + + // Make sure the flags are correctly set for a client. + if(mo->ddFlags & DDMF_REMOTE) + { + Con_Message("Cl_Assertions: client %i, mobj should not be remote!\n", plrNum); + } + if(clmo->ddFlags & DDMF_SOLID) + { + Con_Message("Cl_Assertions: client %i, clmobj should not be solid (when player is alive)!\n", plrNum); + } +} + /** * Client-side game ticker. */ @@ -407,6 +446,10 @@ void Cl_Ticker(void) for(i = 0; i < DDMAXPLAYERS; ++i) { Cl_UpdatePlayerPos(i); //P_GetDDPlayerIdx(mo->dPlayer)); + +#ifdef _DEBUG + Cl_Assertions(i); +#endif } //Cl_LocalCommand(); diff --git a/doomsday/engine/portable/src/cl_mobj.c b/doomsday/engine/portable/src/cl_mobj.c index 1d31c1dbd2..ba1b4b58a5 100644 --- a/doomsday/engine/portable/src/cl_mobj.c +++ b/doomsday/engine/portable/src/cl_mobj.c @@ -355,7 +355,11 @@ VERBOSE( Con_Message("Cl_UpdateRealPlayerMobj: mo=%p angle=%x\n", mo, mo->angle) mo->tics = clmo->tics; mo->state = clmo->state; //mo->nexttime = clmo->nexttime; - mo->ddFlags = clmo->ddFlags; +#define DDMF_KEEP_MASK (DDMF_REMOTE | DDMF_SOLID) + mo->ddFlags = (mo->ddFlags & DDMF_KEEP_MASK) | (clmo->ddFlags & ~DDMF_KEEP_MASK); +#ifdef _DEBUG + Con_Message("Cl_UpdateRealPlayerMobj: Setting mo flags to 0x%x\n", mo->ddFlags); +#endif mo->radius = clmo->radius; mo->height = clmo->height; mo->floorClip = clmo->floorClip; diff --git a/doomsday/engine/portable/src/cl_player.c b/doomsday/engine/portable/src/cl_player.c index 2a8370fc69..edaad8988e 100644 --- a/doomsday/engine/portable/src/cl_player.c +++ b/doomsday/engine/portable/src/cl_player.c @@ -405,6 +405,9 @@ void Cl_UpdatePlayerPos(int plrNum) clmo = &s->cmo->mo; mo = plr->shared.mo; + // The client mobj is never solid. + clmo->ddFlags &= ~DDMF_SOLID; + clmo->angle = mo->angle; // The player's client mobj is not linked to any lists, so position // can be updated without any hassles. @@ -773,13 +776,12 @@ void Cl_ReadPlayerDelta2(boolean skip) } #if _DEBUG -Con_Message("Cl_RdPlrD2: Pl%i: mobj=%i old=%ul\n", num, s->mobjId, - (unsigned int) old); -Con_Message(" x=%g y=%g z=%g fz=%g cz=%g\n", s->cmo->mo.pos[VX], - s->cmo->mo.pos[VY], s->cmo->mo.pos[VZ], - s->cmo->mo.floorZ, s->cmo->mo.ceilingZ); -Con_Message("Cl_RdPlrD2: pl=%i => moid=%i\n", - (skip? -1 : num), s->mobjId); + Con_Message("Cl_RdPlrD2: Pl%i: mobj=%i old=0x%p\n", num, s->mobjId, old); + Con_Message(" x=%g y=%g z=%g fz=%g cz=%g\n", s->cmo->mo.pos[VX], + s->cmo->mo.pos[VY], s->cmo->mo.pos[VZ], + s->cmo->mo.floorZ, s->cmo->mo.ceilingZ); + Con_Message("Cl_RdPlrD2: pl=%i => moid=%i\n", + (skip? -1 : num), s->mobjId); #endif } } diff --git a/doomsday/engine/portable/src/p_maputil.c b/doomsday/engine/portable/src/p_maputil.c index 9887d26e81..01698e6e88 100644 --- a/doomsday/engine/portable/src/p_maputil.c +++ b/doomsday/engine/portable/src/p_maputil.c @@ -740,7 +740,7 @@ void P_MobjLink(mobj_t* mo, byte flags) P_LinkToLines(mo); } - // If this is a player - perform addtional tests to see if they have + // If this is a player - perform additional tests to see if they have // entered or exited the void. if(mo->dPlayer) { diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index b9be3bd90c..c1f123699c 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -295,8 +295,9 @@ void NetCl_UpdatePlayerState2(byte *data, int plrNum) #endif #ifdef _DEBUG - Con_Message("NetCl_UpdatePlayerState2: New state = %i\n", - pl->playerState); + Con_Message("NetCl_UpdatePlayerState2: New state = %s\n", + pl->playerState == PST_LIVE? "PST_LIVE" : + pl->playerState == PST_DEAD? "PST_DEAD" : "PST_REBORN"); #endif // Set or clear the DEAD flag for this player. diff --git a/doomsday/plugins/common/src/p_user.c b/doomsday/plugins/common/src/p_user.c index e3c72b44c0..2a16dc18bd 100644 --- a/doomsday/plugins/common/src/p_user.c +++ b/doomsday/plugins/common/src/p_user.c @@ -1885,6 +1885,36 @@ void P_PlayerThinkUpdateControls(player_t* player) brain->mapMarkClearAll = (P_GetImpulseControlState(playerNum, CTL_MAP_MARK_CLEAR_ALL) != 0); } +/** + * Verify that the player state is valid. This is a debugging utility and + * only gets called when _DEBUG is defined. + */ +void P_PlayerThinkAssertions(player_t* player) +{ + int plrNum = player - players; + mobj_t* mo = player->plr->mo; + if(!mo) return; + + if(IS_CLIENT) + { + // Let's do some checks about the state of a client player. + if(player->playerState == PST_LIVE) + { + if(!(mo->ddFlags & DDMF_SOLID)) + { + Con_Message("P_PlayerThinkAssertions: player %i, mobj should be solid when alive!\n", plrNum); + } + } + else if(player->playerState == PST_DEAD) + { + if(mo->ddFlags & DDMF_SOLID) + { + Con_Message("P_PlayerThinkAssertions: player %i, mobj should not be solid when dead!\n", plrNum); + } + } + } +} + /** * Main thinker function for players. Handles both single player and * multiplayer games, as well as all the different types of players @@ -1911,6 +1941,10 @@ void P_PlayerThink(player_t *player, timespan_t ticLength) return; } +#ifdef _DEBUG + P_PlayerThinkAssertions(player); +#endif + P_PlayerThinkState(player); // Adjust turn angles and look direction. This is done in fractional time.