//***************************************************************************** // void medal_TriggerMedal( ULONG ulPlayer, ULONG ulMedal ) { player_t *pPlayer; pPlayer = &players[ulPlayer]; // Servers don't actually spawn medals. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) return; // Shouldn't happen... if ( pPlayer->mo == NULL ) return; // Make sure this medal is valid. if ( ulMedal >= NUM_MEDALS || !g_MedalQueue[ulPlayer][0].ulTick ) return; // Medals don't override carrier symbols. if ( !medal_PlayerHasCarrierIcon( ulPlayer) ) { if ( pPlayer->pIcon ) pPlayer->pIcon->Destroy( ); // Spawn the medal as an icon above the player and set its properties. pPlayer->pIcon = Spawn<AFloatyIcon>( pPlayer->mo->x, pPlayer->mo->y, pPlayer->mo->z, NO_REPLACE ); if ( pPlayer->pIcon ) { pPlayer->pIcon->SetState( pPlayer->pIcon->SpawnState + g_Medals[ulMedal].usFrame ); // [BB] Instead of MEDAL_ICON_DURATION only use the remaining ticks of the medal as ticks for the icon. // It is possible that the medal is just restored because the player respawned or that the medal was // suppressed by a carrier icon. pPlayer->pIcon->lTick = g_MedalQueue[ulPlayer][0].ulTick; pPlayer->pIcon->SetTracer( pPlayer->mo ); } } // [BB] Only announce the medal when it reaches the top of the queue. Otherwise it could be // announced multiple times (for instance when a carrier dies). if ( g_MedalQueue[ulPlayer][0].ulTick == MEDAL_ICON_DURATION ) { // Also, locally play the announcer sound associated with this medal. // [Dusk] Check coop spy too if ( pPlayer->mo->CheckLocalView( consoleplayer ) ) { if ( g_Medals[ulMedal].szAnnouncerEntry[0] ) ANNOUNCER_PlayEntry( cl_announcer, (const char *)g_Medals[ulMedal].szAnnouncerEntry ); } // If a player besides the console player got the medal, play the remote sound. else { // Play the sound effect associated with this medal type. if ( g_Medals[ulMedal].szSoundName[0] != '\0' ) S_Sound( pPlayer->mo, CHAN_AUTO, g_Medals[ulMedal].szSoundName, 1, ATTN_NORM ); } } }
//***************************************************************************** //***************************************************************************** // static void callvote_EndVote( void ) { char szString[32]; DHUDMessageFadeOut *pMsg; if ( g_VoteState != VOTESTATE_INVOTE ) return; g_VoteState = VOTESTATE_VOTECOMPLETED; g_ulVoteCompletedTicks = VOTE_PASSED_TIME * TICRATE; // If we're the server, inform the clients that the vote has ended. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_VoteEnded( g_bVotePassed ); else { if ( g_bVotePassed ) sprintf( szString, "VOTE PASSED!" ); else sprintf( szString, "VOTE FAILED!" ); // Display "%s WINS!" HUD message. pMsg = new DHUDMessageFadeOut( BigFont, szString, 160.4f, 14.0f, 320, 200, CR_RED, 3.0f, 2.0f ); StatusBar->AttachMessage( pMsg, MAKE_ID('C','N','T','R') ); } // Log to the console. Printf( "Vote %s!\n", g_bVotePassed ? "passed" : "failed" ); // Play the announcer sound associated with this event. if ( g_bVotePassed ) ANNOUNCER_PlayEntry( cl_announcer, "VotePassed" ); else ANNOUNCER_PlayEntry( cl_announcer, "VoteFailed" ); }
void GiveSpawner (player_t *player, const PClass *type, int amount) { if (player->mo == NULL || player->health <= 0) { return; } AInventory *item = static_cast<AInventory *> (Spawn (type, player->mo->x, player->mo->y, player->mo->z, NO_REPLACE)); if (item != NULL) { if (amount > 0) { if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup))) { if (static_cast<ABasicArmorPickup*>(item)->SaveAmount != 0) { static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount; } else { static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount; } } else if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))) { static_cast<ABasicArmorBonus*>(item)->SaveAmount *= amount; // [BB] static_cast<ABasicArmorBonus*>(item)->BonusCount *= amount; } else { item->Amount = MIN (amount, item->MaxAmount); } } if(item->flags & MF_COUNTITEM) // Given items shouldn't count against the map's total, { // since they aren't added to the player's total. level.total_items--; item->flags &= ~MF_COUNTITEM; } if (!item->CallTryPickup (player->mo)) { item->Destroy (); } else { // [BB] This construction is more or less a hack, but at least the give cheats are now working. SERVER_GiveInventoryToPlayer( player, item ); // [BC] Play the announcer sound. if ( players[consoleplayer].camera == players[consoleplayer].mo && cl_announcepickups ) ANNOUNCER_PlayEntry( cl_announcer, item->PickupAnnouncerEntry( )); } } }
//***************************************************************************** // void DUEL_Tick( void ) { // Not in duel mode. if ( duel == false ) return; switch ( g_DuelState ) { case DS_WAITINGFORPLAYERS: if ( NETWORK_GetState( ) == NETSTATE_CLIENT ) break; // Two players are here now, begin the countdown! if ( DUEL_CountActiveDuelers( ) == 2 ) { if ( sv_duelcountdowntime > 0 ) DUEL_StartCountdown(( sv_duelcountdowntime * TICRATE ) - 1 ); else DUEL_StartCountdown(( 10 * TICRATE ) - 1 ); } break; case DS_COUNTDOWN: if ( g_ulDuelCountdownTicks ) { g_ulDuelCountdownTicks--; // FIGHT! if (( g_ulDuelCountdownTicks == 0 ) && ( NETWORK_GetState( ) != NETSTATE_CLIENT )) DUEL_DoFight( ); // Play "3... 2... 1..." sounds. else if ( g_ulDuelCountdownTicks == ( 3 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "Three" ); else if ( g_ulDuelCountdownTicks == ( 2 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "Two" ); else if ( g_ulDuelCountdownTicks == ( 1 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "One" ); } break; } }
//***************************************************************************** // void LASTMANSTANDING_DoFight( void ) { DHUDMessageFadeOut *pMsg; // The match is now in progress. if (( NETWORK_GetState( ) != NETSTATE_CLIENT ) && ( CLIENTDEMO_IsPlaying( ) == false )) { LASTMANSTANDING_SetState( LMSS_INPROGRESS ); } // Make sure this is 0. Can be non-zero in network games if they're slightly out of sync. g_ulLMSCountdownTicks = 0; // Since the level time is being reset, also reset the last frag/excellent time for // each player. PLAYER_ResetAllPlayersSpecialCounters(); // 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" ); // Display "FIGHT!" HUD message. pMsg = new DHUDMessageFadeOut( BigFont, "FIGHT!", 160.4f, 75.0f, 320, 200, CR_RED, 2.0f, 1.0f ); StatusBar->AttachMessage( pMsg, MAKE_ID('C','N','T','R') ); } // Display a little thing in the server window so servers can know when matches begin. else Printf( "FIGHT!\n" ); // Reset the map. GAME_ResetMap( ); GAMEMODE_RespawnAllPlayers( BOTEVENT_LMS_FIGHT ); SCOREBOARD_RefreshHUD( ); }
//***************************************************************************** // 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 LASTMANSTANDING_StartCountdown( ULONG ulTicks ) { ULONG ulIdx; for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if (( playeringame[ulIdx] ) && ( players[ulIdx].pSkullBot )) players[ulIdx].pSkullBot->PostEvent( BOTEVENT_LMS_STARTINGCOUNTDOWN ); } /* // First, reset everyone's fragcount. This must be done before setting the state to LMSS_COUNTDOWN // otherwise PLAYER_SetFragcount will ignore our request. for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if ( playeringame[ulIdx] ) PLAYER_SetFragcount( &players[ulIdx], 0, false, false ); } */ /* for ( ULONG i = 0; i < teams.Size( ); i++ ) TEAM_SetFragCount( i, 0, false ); */ // Put the game in a countdown state. if (( NETWORK_GetState( ) != NETSTATE_CLIENT ) && ( CLIENTDEMO_IsPlaying( ) == false )) { LASTMANSTANDING_SetState( LMSS_COUNTDOWN ); } // Set the LMS countdown ticks. LASTMANSTANDING_SetCountdownTicks( ulTicks ); // Announce that the fight will soon start. ANNOUNCER_PlayEntry( cl_announcer, "PrepareToFight" ); // Tell clients to start the countdown. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_DoGameModeCountdown( ulTicks ); }
//***************************************************************************** // void LASTMANSTANDING_Tick( void ) { // Not in LMS mode. if (( lastmanstanding == false ) && ( teamlms == false )) return; switch ( g_LMSState ) { case LMSS_WAITINGFORPLAYERS: if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { break; } if ( lastmanstanding ) { // Two players are here now, being the countdown! if ( GAME_CountActivePlayers( ) >= 2 ) { if ( sv_lmscountdowntime > 0 ) LASTMANSTANDING_StartCountdown(( sv_lmscountdowntime * TICRATE ) - 1 ); else LASTMANSTANDING_StartCountdown(( 10 * TICRATE ) - 1 ); } } if ( teamlms ) { if ( TEAM_TeamsWithPlayersOn( ) > 1 ) { if ( sv_lmscountdowntime > 0 ) LASTMANSTANDING_StartCountdown(( sv_lmscountdowntime * TICRATE ) - 1 ); else LASTMANSTANDING_StartCountdown(( 10 * TICRATE ) - 1 ); } } break; case LMSS_COUNTDOWN: if ( g_ulLMSCountdownTicks ) { g_ulLMSCountdownTicks--; // FIGHT! if (( g_ulLMSCountdownTicks == 0 ) && ( NETWORK_GetState( ) != NETSTATE_CLIENT ) && ( CLIENTDEMO_IsPlaying( ) == false )) { LASTMANSTANDING_DoFight( ); } // Play "3... 2... 1..." sounds. else if ( g_ulLMSCountdownTicks == ( 3 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "Three" ); else if ( g_ulLMSCountdownTicks == ( 2 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "Two" ); else if ( g_ulLMSCountdownTicks == ( 1 * TICRATE )) ANNOUNCER_PlayEntry( cl_announcer, "One" ); } break; case LMSS_INPROGRESS: if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { break; } // Check to see how many men are left standing. if ( lastmanstanding ) { // If only one man is left standing, somebody just won! if ( GAME_CountLivingAndRespawnablePlayers( ) == 1 ) { 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 ); GAME_SetEndLevelDelay( 5 * TICRATE ); } } // If NOBODY is left standing, it's a draw game! else if ( GAME_CountLivingAndRespawnablePlayers( ) == 0 ) { ULONG ulIdx; for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if (( playeringame[ulIdx] ) && ( PLAYER_IsTrueSpectator( &players[ulIdx] ) == false )) break; } if ( ulIdx != MAXPLAYERS ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "DRAW GAME!\n" ); else Printf( "DRAW GAME!\n" ); // Pause for five seconds for the win sequence. LASTMANSTANDING_DoWinSequence( MAXPLAYERS ); GAME_SetEndLevelDelay( 5 * TICRATE ); } } } // Check to see how many men are left standing on each team. if ( teamlms ) { if ( 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 ); // [BB] Every player who is still alive also gets a win. for ( ULONG ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if ( playeringame[ulIdx] && ( players[ulIdx].bOnTeam ) && ( players[ulIdx].bSpectating == false ) && PLAYER_IsAliveOrCanRespawn ( &players[ulIdx] ) ) PLAYER_SetWins( &players[ulIdx], players[ulIdx].ulWins + 1 ); } // Pause for five seconds for the win sequence. LASTMANSTANDING_DoWinSequence( lWinner ); GAME_SetEndLevelDelay( 5 * TICRATE ); } // If NOBODY is left standing, it's a draw game! else { ULONG ulIdx; for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if (( playeringame[ulIdx] ) && ( PLAYER_IsTrueSpectator( &players[ulIdx] ) == false )) break; } if ( ulIdx != MAXPLAYERS ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "DRAW GAME!\n" ); else Printf( "DRAW GAME!\n" ); // Pause for five seconds for the win sequence. LASTMANSTANDING_DoWinSequence( teams.Size( ) ); GAME_SetEndLevelDelay( 5 * TICRATE ); } } } } break; default: break; } }
//***************************************************************************** // 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_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 ); }
//***************************************************************************** // void CALLVOTE_BeginVote( FString Command, FString Parameters, FString Reason, ULONG ulPlayer ) { // Don't allow a vote in the middle of another vote. if ( g_VoteState != VOTESTATE_NOVOTE ) { if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_PrintfPlayer( PRINT_HIGH, SERVER_GetCurrentClient( ), "Another vote is already underway.\n" ); return; } // Check and make sure all the parameters are valid. if ( callvote_CheckValidity( Command, Parameters ) == false ) return; // Prevent excessive re-voting. if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && callvote_CheckForFlooding( Command, Parameters, ulPlayer ) == false ) return; // Play the announcer sound for this. ANNOUNCER_PlayEntry( cl_announcer, "VoteNow" ); // Create the vote console command. g_VoteCommand = Command; g_VoteCommand += " "; g_VoteCommand += Parameters; g_ulVoteCaller = ulPlayer; g_VoteReason = Reason.Left(25); // Create the record of the vote for flood prevention. { VOTE_s VoteRecord; VoteRecord.fsParameter = Parameters; time_t tNow; time( &tNow ); VoteRecord.tTimeCalled = tNow; VoteRecord.Address = SERVER_GetClient( g_ulVoteCaller )->Address; VoteRecord.ulVoteType = callvote_GetVoteType( Command ); if ( callvote_IsKickVote ( VoteRecord.ulVoteType ) ) VoteRecord.KickAddress = g_KickVoteVictimAddress; g_PreviousVotes.push_back( VoteRecord ); } // Display the message in the console. { FString ReasonBlurb = ( g_VoteReason.Len( )) ? ( ", reason: \"" + g_VoteReason + "\"" ) : ""; if ( NETWORK_GetState( ) == NETSTATE_SERVER ) Printf( "%s\\c- (%s) has called a vote (\"%s\"%s).\n", players[ulPlayer].userinfo.netname, NETWORK_AddressToString( SERVER_GetClient( ulPlayer )->Address ), g_VoteCommand.GetChars(), ReasonBlurb.GetChars() ); else Printf( "%s\\c- has called a vote (\"%s\"%s).\n", players[ulPlayer].userinfo.netname, g_VoteCommand.GetChars(), ReasonBlurb.GetChars() ); } g_VoteState = VOTESTATE_INVOTE; g_ulVoteCountdownTicks = VOTE_COUNTDOWN_TIME * TICRATE; g_ulShowVoteScreenTicks = g_ulVoteCountdownTicks; g_bVoteCancelled = false; // Inform clients about the vote being called. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_CallVote( ulPlayer, Command, Parameters, Reason ); }