Skip to content

Commit

Permalink
Client: Fixing mobj/clmobj flags
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skyjake committed Mar 24, 2011
1 parent 36dbc2a commit f2109c0
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,4 +1,5 @@
.directory
.DS_Store

/doomsday/build/win32/license.txt
/doomsday/build/win32/license.txt
*.user.*
43 changes: 43 additions & 0 deletions doomsday/engine/portable/src/cl_main.c
Expand Up @@ -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.
*/
Expand All @@ -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();
Expand Down
6 changes: 5 additions & 1 deletion doomsday/engine/portable/src/cl_mobj.c
Expand Up @@ -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;
Expand Down
16 changes: 9 additions & 7 deletions doomsday/engine/portable/src/cl_player.c
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
}
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/src/p_maputil.c
Expand Up @@ -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)
{
Expand Down
5 changes: 3 additions & 2 deletions doomsday/plugins/common/src/d_netcl.c
Expand Up @@ -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.
Expand Down
34 changes: 34 additions & 0 deletions doomsday/plugins/common/src/p_user.c
Expand Up @@ -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
Expand All @@ -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.
Expand Down

0 comments on commit f2109c0

Please sign in to comment.