diff options
author | /dev/humancontroller <devhc@example.com> | 2014-07-13 17:15:05 +0200 |
---|---|---|
committer | /dev/humancontroller <devhc@example.com> | 2017-03-09 13:51:11 +0100 |
commit | 59875f1378dca6605cd0426eff89f850d8743c92 (patch) | |
tree | 386f33324df8e2c528b3237d86d4fb0c20a37aba | |
parent | 7224c7bf34cf7548f86a3af2247240705c0f4b4b (diff) |
fix noclipping players affecting other players
notably, other players were able to stand on the "center" of a noclipped player
set an r.contents value of 0 for noclipping clients, backing up the r.contents value in the new ent->client->cliprcontents field
-rw-r--r-- | src/game/g_client.c | 9 | ||||
-rw-r--r-- | src/game/g_cmds.c | 10 | ||||
-rw-r--r-- | src/game/g_combat.c | 5 | ||||
-rw-r--r-- | src/game/g_local.h | 1 | ||||
-rw-r--r-- | src/game/g_team.c | 6 |
5 files changed, 27 insertions, 4 deletions
diff --git a/src/game/g_client.c b/src/game/g_client.c index 76078040..548ec963 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1199,7 +1199,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles int i; clientPersistant_t saved; clientSession_t savedSess; - qboolean savedNoclip; + qboolean savedNoclip, savedCliprcontents; int persistant[ MAX_PERSISTANT ]; gentity_t *spawnPoint = NULL; int flags; @@ -1283,6 +1283,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles savedSess = client->sess; savedPing = client->ps.ping; savedNoclip = client->noclip; + savedCliprcontents = client->cliprcontents; for( i = 0; i < MAX_PERSISTANT; i++ ) persistant[ i ] = client->ps.persistant[ i ]; @@ -1294,6 +1295,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles client->sess = savedSess; client->ps.ping = savedPing; client->noclip = savedNoclip; + client->cliprcontents = savedCliprcontents; client->lastkilled_client = -1; for( i = 0; i < MAX_PERSISTANT; i++ ) @@ -1316,7 +1318,10 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles ent->client = &level.clients[ index ]; ent->takedamage = qtrue; ent->classname = "player"; - ent->r.contents = CONTENTS_BODY; + if( client->noclip ) + client->cliprcontents = CONTENTS_BODY; + else + ent->r.contents = CONTENTS_BODY; ent->clipmask = MASK_PLAYERSOLID; ent->die = player_die; ent->waterlevel = 0; diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 8ad781ab..caa5f990 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -544,12 +544,22 @@ void Cmd_Noclip_f( gentity_t *ent ) char *msg; if( ent->client->noclip ) + { msg = "noclip OFF\n"; + ent->r.contents = ent->client->cliprcontents; + } else + { msg = "noclip ON\n"; + ent->client->cliprcontents = ent->r.contents; + ent->r.contents = 0; + } ent->client->noclip = !ent->client->noclip; + if( ent->r.linked ) + trap_LinkEntity( ent ); + trap_SendServerCommand( ent - g_entities, va( "print \"%s\"", msg ) ); } diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 527e3068..0b61ce59 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -344,7 +344,10 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int self->takedamage = qfalse; // can still be gibbed self->s.weapon = WP_NONE; - self->r.contents = CONTENTS_CORPSE; + if( self->client->noclip ) + self->client->cliprcontents = CONTENTS_CORPSE; + else + self->r.contents = CONTENTS_CORPSE; self->s.angles[ PITCH ] = 0; self->s.angles[ ROLL ] = 0; diff --git a/src/game/g_local.h b/src/game/g_local.h index d319a5c2..081c47b8 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -362,6 +362,7 @@ struct gclient_s qboolean readyToExit; // wishes to leave the intermission qboolean noclip; + int cliprcontents; // the backup layer of ent->r.contents for when noclipping int lastCmdTime; // level.time of last usercmd_t, for EF_CONNECTION // we can't just use pers.lastCommand.time, because diff --git a/src/game/g_team.c b/src/game/g_team.c index f3ca0f84..ad29beaf 100644 --- a/src/game/g_team.c +++ b/src/game/g_team.c @@ -222,7 +222,11 @@ void G_ChangeTeam( gentity_t *ent, team_t newTeam ) if( !g_cheats.integer ) { - ent->client->noclip = qfalse; + if( ent->client->noclip ) + { + ent->client->noclip = qfalse; + ent->r.contents = ent->client->cliprcontents; + } ent->flags &= ~( FL_GODMODE | FL_NOTARGET ); } |