/* ================== G_LeaveTeam ================== */ void G_LeaveTeam( gentity_t *self ) { team_t team = self->client->pers.teamSelection; gentity_t *ent; int i; if ( team == TEAM_ALIENS ) { G_RemoveFromSpawnQueue( &level.alienSpawnQueue, self->client->ps.clientNum ); } else if ( team == TEAM_HUMANS ) { G_RemoveFromSpawnQueue( &level.humanSpawnQueue, self->client->ps.clientNum ); } else { if ( self->client->sess.spectatorState == SPECTATOR_FOLLOW ) { G_StopFollowing( self ); } return; } // stop any following clients G_StopFromFollowing( self ); G_Vote( self, team, qfalse ); self->suicideTime = 0; for ( i = 0; i < level.num_entities; i++ ) { ent = &g_entities[ i ]; if ( !ent->inuse ) { continue; } if ( ent->client && ent->client->pers.connected == CON_CONNECTED ) { // cure poison if ( ent->client->ps.stats[ STAT_STATE ] & SS_POISONED && ent->client->lastPoisonClient == self ) { ent->client->ps.stats[ STAT_STATE ] &= ~SS_POISONED; } } else if ( ent->s.eType == ET_MISSILE && ent->r.ownerNum == self->s.number ) { G_FreeEntity( ent ); } } // cut all relevant zap beams G_ClearPlayerZapEffects( self ); G_namelog_update_score( self->client ); }
/* =========== ClientDisconnect Called when a player drops from the server. Will not be called between levels. This should NOT be called directly by any game logic, call trap_DropClient(), which will call this and do server system housekeeping. ============ */ void ClientDisconnect( int clientNum ) { gclient_t *client; gentity_t *ent; gentity_t *tent; int i; ent = g_entities + clientNum; if( !ent->client || ent->client->pers.connected == CON_DISCONNECTED ) return; G_LeaveTeam( ent ); G_namelog_disconnect( ent->client ); G_Vote( ent, TEAM_NONE, qfalse ); // stop any following clients for( i = 0; i < level.maxclients; i++ ) { client = &level.clients[ i ]; // remove any /ignore settings for this clientNum Com_ClientListRemove( &client->sess.ignoreList, clientNum ); // clear impregnatedBy for everyone impregnated by this player if( client->isImpregnated && client->impregnatedBy == clientNum ) client->impregnatedBy = -2; } // send effect if they were completely connected if( ent->client->pers.connected == CON_CONNECTED && ent->client->sess.spectatorState == SPECTATOR_NOT ) { tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT ); tent->s.clientNum = ent->s.clientNum; } G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s^7\"\n", clientNum, ent->client->pers.ip.str, ent->client->pers.guid, ent->client->pers.netname ); trap_UnlinkEntity( ent ); ent->s.modelindex = 0; ent->inuse = qfalse; ent->classname = "disconnected"; ent->client->pers.connected = CON_DISCONNECTED; ent->client->sess.spectatorState = ent->client->ps.persistant[ PERS_SPECSTATE ] = SPECTATOR_NOT; trap_SetConfigstring( CS_PLAYERS + clientNum, ""); CalculateRanks( ); }
/* =========== ClientDisconnect Called when a player drops from the server. Will not be called between levels. This should NOT be called directly by any game logic, call trap_DropClient(), which will call this and do server system housekeeping. ============ */ void ClientDisconnect( int clientNum ) { gentity_t *ent; gentity_t *tent; int i; ent = g_entities + clientNum; if ( !ent->client || ent->client->pers.connected == CON_DISCONNECTED ) { return; } G_LeaveTeam( ent ); G_namelog_disconnect( ent->client ); G_Vote( ent, TEAM_NONE, false ); // stop any following clients for ( i = 0; i < level.maxclients; i++ ) { // remove any /ignore settings for this clientNum Com_ClientListRemove( &level.clients[ i ].sess.ignoreList, clientNum ); } // send effect if they were completely connected if ( ent->client->pers.connected == CON_CONNECTED && ent->client->sess.spectatorState == SPECTATOR_NOT ) { tent = G_NewTempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT ); tent->s.clientNum = ent->s.clientNum; } G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s^7\"", clientNum, ent->client->pers.ip.str, ent->client->pers.guid, ent->client->pers.netname ); ent->client->pers.connected = CON_DISCONNECTED; ent->client->sess.spectatorState = SPECTATOR_NOT; ent->client->ps.persistant[ PERS_SPECSTATE ] = SPECTATOR_NOT; G_FreeEntity(ent); ent->classname = "disconnected"; ent->client = level.clients + clientNum; trap_SetConfigstring( CS_PLAYERS + clientNum, "" ); CalculateRanks(); Beacon::PropagateAll(); }
/* =========== ClientDisconnect Called when a player drops from the server. Will not be called between levels. This should NOT be called directly by any game logic, call trap_DropClient(), which will call this and do server system housekeeping. ============ */ void ClientDisconnect( int clientNum ) { gentity_t *ent; gentity_t *tent; int i; ent = g_entities + clientNum; if( !ent->client ) return; G_admin_namelog_update( ent->client, qtrue ); G_LeaveTeam( ent ); G_Vote( ent, qfalse ); // stop any following clients for( i = 0; i < level.maxclients; i++ ) { // remove any /ignore settings for this clientNum BG_ClientListRemove( &level.clients[ i ].sess.ignoreList, clientNum ); } // send effect if they were completely connected if( ent->client->pers.connected == CON_CONNECTED && ent->client->sess.spectatorState == SPECTATOR_NOT ) { tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT ); tent->s.clientNum = ent->s.clientNum; } if( ent->client->pers.connection ) ent->client->pers.connection->clientNum = -1; G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s\"\n", clientNum, ent->client->pers.ip, ent->client->pers.guid, ent->client->pers.netname ); trap_UnlinkEntity( ent ); ent->s.modelindex = 0; ent->inuse = qfalse; ent->classname = "disconnected"; ent->client->pers.connected = CON_DISCONNECTED; ent->client->sess.spectatorState = ent->client->ps.persistant[ PERS_SPECSTATE ] = SPECTATOR_NOT; trap_SetConfigstring( CS_PLAYERS + clientNum, ""); CalculateRanks( ); }
void G_LeaveTeam( gentity_t *self ) { team_t team = (team_t) self->client->pers.team; gentity_t *ent; int i; #ifdef UNREALARENA if ( TEAM_Q == team || TEAM_U == team ) #else if ( TEAM_ALIENS == team || TEAM_HUMANS == team ) #endif { G_RemoveFromSpawnQueue( &level.team[ team ].spawnQueue, self->client->ps.clientNum ); } else { if ( self->client->sess.spectatorState == SPECTATOR_FOLLOW ) { G_StopFollowing( self ); } return; } // stop any following clients G_StopFromFollowing( self ); G_Vote( self, team, false ); #ifndef UNREALARENA self->suicideTime = 0; #endif for ( i = 0; i < level.num_entities; i++ ) { ent = &g_entities[ i ]; if ( !ent->inuse ) { continue; } if ( ent->client && ent->client->pers.connected == CON_CONNECTED ) { #ifndef UNREALARENA // cure poison if ( ( ent->client->ps.stats[ STAT_STATE ] & SS_POISONED ) && ent->client->lastPoisonClient == self ) { ent->client->ps.stats[ STAT_STATE ] &= ~SS_POISONED; } #endif } else if ( ent->s.eType == entityType_t::ET_MISSILE && ent->r.ownerNum == self->s.number ) { G_FreeEntity( ent ); } } // cut all relevant zap beams G_ClearPlayerZapEffects( self ); Beacon::DeleteTags( self ); Beacon::RemoveOrphaned( self->s.number ); G_namelog_update_score( self->client ); }