/* * G_Match_NotReady */ void G_Match_NotReady( edict_t *ent ) { if( ent->s.team == TEAM_SPECTATOR ) { G_PrintMsg( ent, "Join the game first\n" ); return; } if( GS_MatchState() != MATCH_STATE_WARMUP && GS_MatchState() != MATCH_STATE_COUNTDOWN ) { G_PrintMsg( ent, "A match is not being setup.\n" ); return; } if( !level.ready[PLAYERNUM( ent )] ) { G_PrintMsg( ent, "You weren't ready.\n" ); return; } level.ready[PLAYERNUM( ent )] = false; G_PrintMsg( NULL, "%s%s is no longer ready.\n", ent->r.client->netname, S_COLOR_WHITE ); G_UpdatePlayerMatchMsg( ent ); G_Match_CheckReadys(); }
/* * G_Teams_JoinChallengersQueue */ void G_Teams_JoinChallengersQueue( edict_t *ent ) { int pos = 0; edict_t *e; if( !GS_HasChallengers() ) { ent->r.client->queueTimeStamp = 0; return; } if( ent->s.team != TEAM_SPECTATOR ) return; // enter the challengers queue if( !ent->r.client->queueTimeStamp ) { // enter the line ent->r.client->queueTimeStamp = game.realtime; for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ ) { if( !e->r.inuse || !e->r.client || trap_GetClientState( PLAYERNUM(e) ) < CS_SPAWNED ) continue; if( !e->r.client->queueTimeStamp || e->s.team != TEAM_SPECTATOR ) continue; // if there are other players with the same timestamp, increase ours if( e->r.client->queueTimeStamp >= ent->r.client->queueTimeStamp ) ent->r.client->queueTimeStamp = e->r.client->queueTimeStamp+1; if( e->r.client->queueTimeStamp < ent->r.client->queueTimeStamp ) pos++; } G_PrintMsg( ent, "%sYou entered the challengers queue in position %i\n", S_COLOR_CYAN, pos+1 ); G_UpdatePlayerMatchMsg( ent ); } }
/* * G_Match_Ready */ void G_Match_Ready( edict_t *ent ) { if( ent->r.svflags & SVF_FAKECLIENT && level.ready[PLAYERNUM( ent )] == true ) return; if( ent->s.team == TEAM_SPECTATOR ) { G_PrintMsg( ent, "Join the game first\n" ); return; } if( GS_MatchState() != MATCH_STATE_WARMUP ) { if( !( ent->r.svflags & SVF_FAKECLIENT ) ) G_PrintMsg( ent, "We're not in warmup.\n" ); return; } if( level.ready[PLAYERNUM( ent )] ) { G_PrintMsg( ent, "You are already ready.\n" ); return; } level.ready[PLAYERNUM( ent )] = true; G_PrintMsg( NULL, "%s%s is ready!\n", ent->r.client->netname, S_COLOR_WHITE ); G_UpdatePlayerMatchMsg( ent ); G_Match_CheckReadys(); }
/* * G_Teams_SetTeam - sets clients team without any checking */ void G_Teams_SetTeam( edict_t *ent, int team ) { assert( ent && ent->r.inuse && ent->r.client ); assert( team >= TEAM_SPECTATOR && team < GS_MAX_TEAMS ); // if player was on a team, send partial report to matchmaker if( ent->r.client->team != TEAM_SPECTATOR && ent->r.client->team != team && GS_MatchState() == MATCH_STATE_PLAYTIME ) { G_Printf("Sending teamchange to MM, team %d to team %d\n", ent->r.client->team, team ); G_AddPlayerReport( ent, false ); // trap_MR_SendPartialReport(); } // clear scores at changing team memset( &ent->r.client->level.stats, 0, sizeof( ent->r.client->level.stats ) ); memset( &ent->r.client->teamstate, 0, sizeof( ent->r.client->teamstate ) ); ent->r.client->team = team; ent->r.client->teamstate.timeStamp = level.time; G_Teams_UnInvitePlayer( team, ent ); G_ClientRespawn( ent, true ); // make ghost using G_ClientRespawn so team is updated at ghosting G_SpawnQueue_AddClient( ent ); level.ready[PLAYERNUM( ent )] = false; G_Match_CheckReadys(); G_UpdatePlayerMatchMsg( ent ); }
/* * G_Teams_LeaveChallengersQueue */ void G_Teams_LeaveChallengersQueue( edict_t *ent ) { if( !GS_HasChallengers() ) { ent->r.client->queueTimeStamp = 0; return; } if( ent->s.team != TEAM_SPECTATOR ) return; // exit the challengers queue if( ent->r.client->queueTimeStamp ) { ent->r.client->queueTimeStamp = 0; G_PrintMsg( ent, "%sYou left the challengers queue\n", S_COLOR_CYAN ); G_UpdatePlayerMatchMsg( ent ); } }
/* * ClientBegin * called when a client has finished connecting, and is ready * to be placed into the game. This will happen every level load. */ void ClientBegin( edict_t *ent ) { gclient_t *client = ent->r.client; const char *mm_login; memset( &client->ucmd, 0, sizeof( client->ucmd ) ); memset( &client->level, 0, sizeof( client->level ) ); client->level.timeStamp = level.time; G_Client_UpdateActivity( client ); // activity detected client->team = TEAM_SPECTATOR; G_ClientRespawn( ent, true ); // respawn as ghost ent->movetype = MOVETYPE_NOCLIP; // allow freefly G_UpdatePlayerMatchMsg( ent ); mm_login = Info_ValueForKey( client->userinfo, "cl_mm_login" ); if( mm_login && *mm_login && client->mm_session > 0 ) { G_PrintMsg( NULL, "%s" S_COLOR_WHITE " (" S_COLOR_YELLOW "%s" S_COLOR_WHITE ") entered the game\n", client->netname, mm_login ); } else { if( !level.gametype.disableObituaries || !(ent->r.svflags & SVF_FAKECLIENT ) ) G_PrintMsg( NULL, "%s" S_COLOR_WHITE " entered the game\n", client->netname ); } client->level.respawnCount = 0; // clear respawncount client->connecting = false; // schedule the next scoreboard update client->level.scoreboard_time = game.realtime + scoreboardInterval - ( game.realtime%scoreboardInterval ); AI_EnemyAdded( ent ); G_ClientEndSnapFrame( ent ); // make sure all view stuff is valid // let the gametype scripts now this client just entered the level G_Gametype_ScoreEvent( client, "enterGame", NULL ); }
/* * G_Chase_SetChaseActive */ static void G_Chase_SetChaseActive( edict_t *ent, bool active ) { ent->r.client->resp.chase.active = active; G_UpdatePlayerMatchMsg( ent ); }
/* * Cmd_Upstate_f * * Update client on the state of things */ static void Cmd_Upstate_f( edict_t *ent ) { G_UpdatePlayerMatchMsg( ent, true ); G_SetPlayerHelpMessage( ent, ent->r.client->level.helpmessage, true ); trap_GameCmd( ent, va( "qm %s", ent->r.client->level.quickMenuItems ) ); }