//***************************************************************************** // void DUEL_DoWinSequence( ULONG ulPlayer ) { ULONG ulIdx; // Put the duel state in the win sequence state. if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) DUEL_SetState( DS_WINSEQUENCE ); // Tell clients to do the win sequence. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_DoGameModeWinSequence( ulPlayer ); if ( NETWORK_GetState( ) != NETSTATE_SERVER ) { char szString[64]; DHUDMessageFadeOut *pMsg; screen->SetFont( BigFont ); sprintf( szString, "%s \\c-WINS!", players[ulPlayer].userinfo.netname ); V_ColorizeString( szString ); // Display "%s WINS!" HUD message. pMsg = new DHUDMessageFadeOut( szString, 160.4f, 75.0f, 320, 200, CR_RED, 3.0f, 2.0f ); StatusBar->AttachMessage( pMsg, 'CNTR' ); screen->SetFont( SmallFont ); } // Award a victory or perfect medal to the winner. if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) { LONG lMedal; // If the duel loser doesn't have any frags, give the winner a "Perfect!". if ( players[g_ulDuelLoser].fragcount <= 0 ) lMedal = MEDAL_PERFECT; else lMedal = MEDAL_VICTORY; // Give the player the medal. MEDAL_GiveMedal( ulPlayer, lMedal ); if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_GivePlayerMedal( ulPlayer, lMedal ); } for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if (( playeringame[ulIdx] ) && ( players[ulIdx].pSkullBot )) players[ulIdx].pSkullBot->PostEvent( BOTEVENT_DUEL_WINSEQUENCE ); } }
//***************************************************************************** // void DUEL_StartCountdown( ULONG ulTicks ) { ULONG ulIdx; if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) { // First, reset everyone's fragcount. PLAYER_ResetAllPlayersFragcount( ); // If we're the server, tell clients to reset everyone's fragcount. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_ResetAllPlayersFragcount( ); // Also, tell bots that a duel countdown is starting. for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if ( playeringame[ulIdx] ) { if ( players[ulIdx].pSkullBot ) players[ulIdx].pSkullBot->PostEvent( BOTEVENT_DUEL_STARTINGCOUNTDOWN ); } } // Put the duel in a countdown state. DUEL_SetState( DS_COUNTDOWN ); } // Set the duel countdown ticks. DUEL_SetCountdownTicks( ulTicks ); // Announce that the fight will soon start. ANNOUNCER_PlayEntry( cl_announcer, "PrepareToFight" ); // Reset announcer "frags left" variables. ANNOUNCER_AllowNumFragsAndPointsLeftSounds( ); // Reset the first frag awarded flag. g_bFirstFragAwarded = false; // Tell clients to start the countdown. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_DoGameModeCountdown( ulTicks ); }
//***************************************************************************** // void DUEL_DoFight( void ) { ULONG ulIdx; DHUDMessageFadeOut *pMsg; // No longer waiting to duel. if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) DUEL_SetState( DS_INDUEL ); // Make sure this is 0. Can be non-zero in network games if they're slightly out of sync. g_ulDuelCountdownTicks = 0; // Reset level time to 0. level.time = 0; for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { // Since the level time is being reset, also reset the last frag/excellent time for // each player. players[ulIdx].ulLastExcellentTick = 0; players[ulIdx].ulLastFragTick = 0; players[ulIdx].ulLastBFGFragTick = 0; players[ulIdx].ulDeathsWithoutFrag = 0; players[ulIdx].ulFragsWithoutDeath = 0; players[ulIdx].ulRailgunShots = 0; } // Tell clients to "fight!". if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_DoGameModeFight( 0 ); if ( NETWORK_GetState( ) != NETSTATE_SERVER ) { // Play fight sound. ANNOUNCER_PlayEntry( cl_announcer, "Fight" ); screen->SetFont( BigFont ); // Display "FIGHT!" HUD message. pMsg = new DHUDMessageFadeOut( "FIGHT!", 160.4f, 75.0f, 320, 200, CR_RED, 2.0f, 1.0f ); StatusBar->AttachMessage( pMsg, 'CNTR' ); screen->SetFont( SmallFont ); } // Display a little thing in the server window so servers can know when matches begin. else Printf( "FIGHT!\n" ); // Reset the map. if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) GAME_ResetMap( ); if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) { // Respawn the players. for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if (( playeringame[ulIdx] ) && ( PLAYER_IsTrueSpectator( &players[ulIdx] ) == false )) { if ( players[ulIdx].mo ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_DestroyThing( players[ulIdx].mo ); players[ulIdx].mo->Destroy( ); players[ulIdx].mo = NULL; } // Set the player's state to PST_REBORNNOINVENTORY so they everything is cleared (weapons, etc.) players[ulIdx].playerstate = PST_REBORNNOINVENTORY; G_DeathMatchSpawnPlayer( ulIdx, true ); if ( players[ulIdx].pSkullBot ) players[ulIdx].pSkullBot->PostEvent( BOTEVENT_DUEL_FIGHT ); } } } SCOREBOARD_RefreshHUD( ); }
//***************************************************************************** // void JOINQUEUE_PopQueue( LONG lNumSlots ) { ULONG ulIdx; // Nothing to do if there's nobody waiting in the queue. if ( g_lJoinQueue[0].ulPlayer == MAXPLAYERS ) return; // [BB] Players are not allowed to join. if ( GAMEMODE_PreventPlayersFromJoining() ) return; // Try to find the next person in line. ulIdx = 0; while ( 1 ) { // Found end of list. if (( ulIdx == MAXPLAYERS ) || ( g_lJoinQueue[ulIdx].ulPlayer == MAXPLAYERS ) || ( lNumSlots == 0 )) { break; } // [BB] Since we possibly just let somebody waiting in line join, check if more persons are allowed to join now. if ( GAMEMODE_PreventPlayersFromJoining() ) break; // Found a player waiting in line. They will now join the game! if ( playeringame[g_lJoinQueue[ulIdx].ulPlayer] ) { // [K6] Reset their AFK timer now - they may have been waiting in the queue silently and we don't want to kick them. SERVER_GetClient( g_lJoinQueue[ulIdx].ulPlayer )->lLastActionTic = gametic; PLAYER_SpectatorJoinsGame ( &players[g_lJoinQueue[ulIdx].ulPlayer] ); // [BB/Spleen] The "lag interval" is only half of the "spectate info send" interval. Account for this here. if (( gametic - SERVER_GetClient( g_lJoinQueue[ulIdx].ulPlayer )->ulLastCommandTic ) <= 2*TICRATE ) SERVER_GetClient( g_lJoinQueue[ulIdx].ulPlayer )->ulClientGameTic += ( gametic - SERVER_GetClient( g_lJoinQueue[ulIdx].ulPlayer )->ulLastCommandTic ); if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS ) { if ( TEAM_CheckIfValid ( g_lJoinQueue[ulIdx].ulTeam ) ) PLAYER_SetTeam( &players[g_lJoinQueue[ulIdx].ulPlayer], g_lJoinQueue[ulIdx].ulTeam, true ); else PLAYER_SetTeam( &players[g_lJoinQueue[ulIdx].ulPlayer], TEAM_ChooseBestTeamForPlayer( ), true ); } // Begin the duel countdown. if ( duel ) { // [BB] Skip countdown and map reset if the map is supposed to be a lobby. if ( GAMEMODE_IsLobbyMap( ) ) DUEL_SetState( DS_INDUEL ); else if ( sv_duelcountdowntime > 0 ) DUEL_StartCountdown(( sv_duelcountdowntime * TICRATE ) - 1 ); else DUEL_StartCountdown(( 10 * TICRATE ) - 1 ); } // Begin the LMS countdown. else if ( lastmanstanding ) { if ( sv_lmscountdowntime > 0 ) LASTMANSTANDING_StartCountdown(( sv_lmscountdowntime * TICRATE ) - 1 ); else LASTMANSTANDING_StartCountdown(( 10 * TICRATE ) - 1 ); } else { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "%s \\c-joined the game.\n", players[g_lJoinQueue[ulIdx].ulPlayer].userinfo.netname ); else Printf( "%s \\c-joined the game.\n", players[g_lJoinQueue[ulIdx].ulPlayer].userinfo.netname ); } JOINQUEUE_RemovePlayerAtPosition ( ulIdx ); if ( lNumSlots > 0 ) lNumSlots--; } else ulIdx++; } // If we're the server, tell everyone their new position in line. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetQueuePosition( ); }
//***************************************************************************** // void JOINQUEUE_PlayerLeftGame( bool bWantPop ) { bool bPop = true; // If we're in a duel, revert to the "waiting for players" state. // [BB] But only do so if there are less then two duelers left (probably JOINQUEUE_PlayerLeftGame was called mistakenly). if ( duel && ( DUEL_CountActiveDuelers( ) < 2 ) ) DUEL_SetState( DS_WAITINGFORPLAYERS ); // If only one (or zero) person is left, go back to "waiting for players". if ( lastmanstanding ) { // Someone just won by default! if (( GAME_CountLivingAndRespawnablePlayers( ) == 1 ) && ( LASTMANSTANDING_GetState( ) == LMSS_INPROGRESS )) { LONG lWinner; lWinner = LASTMANSTANDING_GetLastManStanding( ); if ( lWinner != -1 ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "%s \\c-wins!\n", players[lWinner].userinfo.netname ); else { Printf( "%s \\c-wins!\n", players[lWinner].userinfo.netname ); if ( lWinner == consoleplayer ) ANNOUNCER_PlayEntry( cl_announcer, "YouWin" ); } // Give the winner a win. PLAYER_SetWins( &players[lWinner], players[lWinner].ulWins + 1 ); // Pause for five seconds for the win sequence. LASTMANSTANDING_DoWinSequence( lWinner ); } // Join queue will be popped upon state change. bPop = false; GAME_SetEndLevelDelay( 5 * TICRATE ); } else if ( SERVER_CalcNumNonSpectatingPlayers( MAXPLAYERS ) <= 1 ) LASTMANSTANDING_SetState( LMSS_WAITINGFORPLAYERS ); } if ( teamlms ) { // Someone just won by default! if (( LASTMANSTANDING_GetState( ) == LMSS_INPROGRESS ) && LASTMANSTANDING_TeamsWithAlivePlayersOn( ) <= 1) { LONG lWinner; lWinner = LASTMANSTANDING_TeamGetLastManStanding( ); if ( lWinner != -1 ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "%s \\c-wins!\n", TEAM_GetName( lWinner )); else { Printf( "%s \\c-wins!\n", TEAM_GetName( lWinner )); if ( players[consoleplayer].bOnTeam && ( lWinner == (LONG)players[consoleplayer].ulTeam )) ANNOUNCER_PlayEntry( cl_announcer, "YouWin" ); } // Give the team a win. TEAM_SetWinCount( lWinner, TEAM_GetWinCount( lWinner ) + 1, false ); // Pause for five seconds for the win sequence. LASTMANSTANDING_DoWinSequence( lWinner ); } // Join queue will be popped upon state change. bPop = false; GAME_SetEndLevelDelay( 5 * TICRATE ); } else if ( TEAM_TeamsWithPlayersOn( ) <= 1 ) LASTMANSTANDING_SetState( LMSS_WAITINGFORPLAYERS ); } // If we're in possession mode, revert to the "waiting for players" state // [BB] when there are less than two players now. if ( possession && ( SERVER_CalcNumNonSpectatingPlayers( MAXPLAYERS ) < 2 )) POSSESSION_SetState( PSNS_WAITINGFORPLAYERS ); if ( teampossession && ( TEAM_TeamsWithPlayersOn( ) <= 1 ) ) POSSESSION_SetState( PSNS_WAITINGFORPLAYERS ); // If we're in invasion mode, revert to the "waiting for players" state. if ( invasion && ( SERVER_CalcNumNonSpectatingPlayers( MAXPLAYERS ) < 1 )) INVASION_SetState( IS_WAITINGFORPLAYERS ); // If we're in survival co-op mode, revert to the "waiting for players" state. if ( survival && ( SERVER_CalcNumNonSpectatingPlayers( MAXPLAYERS ) < 1 )) SURVIVAL_SetState( SURVS_WAITINGFORPLAYERS ); // Potentially let one person join the game. if ( bPop && bWantPop ) JOINQUEUE_PopQueue( 1 ); }