void G_ChangeTeam( gentity_t *ent, team_t newTeam ) { team_t oldTeam = (team_t) ent->client->pers.team; if ( oldTeam == newTeam ) { return; } G_LeaveTeam( ent ); ent->client->pers.teamChangeTime = level.time; ent->client->pers.team = newTeam; ent->client->pers.teamInfo = level.startTime - 1; ent->client->pers.classSelection = PCL_NONE; ClientSpawn( ent, nullptr, nullptr, nullptr ); if ( oldTeam == TEAM_HUMANS && newTeam == TEAM_ALIENS ) { // Convert from human to alien credits ent->client->pers.credit = ( int )( ent->client->pers.credit * ALIEN_MAX_CREDITS / HUMAN_MAX_CREDITS + 0.5f ); } else if ( oldTeam == TEAM_ALIENS && newTeam == TEAM_HUMANS ) { // Convert from alien to human credits ent->client->pers.credit = ( int )( ent->client->pers.credit * HUMAN_MAX_CREDITS / ALIEN_MAX_CREDITS + 0.5f ); } if ( !g_cheats.integer ) { if ( ent->client->noclip ) { ent->client->noclip = false; ent->r.contents = ent->client->cliprcontents; } ent->flags &= ~( FL_GODMODE | FL_NOTARGET ); } // Copy credits to ps for the client ent->client->ps.persistant[ PERS_CREDIT ] = ent->client->pers.credit; // Update PERS_UNLOCKABLES in the same frame as PERS_TEAM to prevent bad status change notifications ent->client->ps.persistant[ PERS_UNLOCKABLES ] = BG_UnlockablesMask( newTeam ); ClientUserinfoChanged( ent->client->ps.clientNum, false ); G_UpdateTeamConfigStrings(); Beacon::PropagateAll( ); G_LogPrintf( "ChangeTeam: %d %s: %s^* switched teams", ( int )( ent - g_entities ), BG_TeamName( newTeam ), ent->client->pers.netname ); G_namelog_update_score( ent->client ); TeamplayInfoMessage( ent ); }
/* ================== 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 ); }
/* ================= G_ChangeTeam ================= */ void G_ChangeTeam( gentity_t *ent, team_t newTeam ) { team_t oldTeam = ent->client->pers.teamSelection; if ( oldTeam == newTeam ) { return; } G_LeaveTeam( ent ); ent->client->pers.teamChangeTime = level.time; ent->client->pers.teamSelection = newTeam; ent->client->pers.classSelection = PCL_NONE; ClientSpawn( ent, NULL, NULL, NULL ); if ( oldTeam == TEAM_HUMANS && newTeam == TEAM_ALIENS ) { // Convert from human to alien credits ent->client->pers.credit = ( int )( ent->client->pers.credit * ALIEN_MAX_CREDITS / HUMAN_MAX_CREDITS + 0.5f ); } else if ( oldTeam == TEAM_ALIENS && newTeam == TEAM_HUMANS ) { // Convert from alien to human credits ent->client->pers.credit = ( int )( ent->client->pers.credit * HUMAN_MAX_CREDITS / ALIEN_MAX_CREDITS + 0.5f ); } if ( !g_cheats.integer ) { if ( ent->client->noclip ) { ent->client->noclip = qfalse; ent->r.contents = ent->client->cliprcontents; } ent->flags &= ~( FL_GODMODE | FL_NOTARGET ); } // Copy credits to ps for the client ent->client->ps.persistant[ PERS_CREDIT ] = ent->client->pers.credit; ClientUserinfoChanged( ent->client->ps.clientNum, qfalse ); G_UpdateTeamConfigStrings(); G_LogPrintf( "ChangeTeam: %d %s: %s" S_COLOR_WHITE " switched teams\n", ( int )( ent - g_entities ), BG_TeamName( newTeam ), ent->client->pers.netname ); G_namelog_update_score( ent->client ); TeamplayInfoMessage( ent ); }
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 ); }