//***************************************************************************** // ULONG medal_GetDesiredIcon( player_t *pPlayer, AInventory *&pTeamItem ) { ULONG ulDesiredSprite = NUM_SPRITES; // [BB] Invalid players certainly don't need any icon. if ( ( pPlayer == NULL ) || ( pPlayer->mo == NULL ) ) return NUM_SPRITES; // Draw an ally icon if this person is on our team. Would this be useful for co-op, too? // [BB] In free spectate mode, we don't have allies (and SCOREBOARD_GetViewPlayer doesn't return a useful value). if ( ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS ) && ( CLIENTDEMO_IsInFreeSpectateMode() == false ) ) { // [BB] Dead spectators shall see the icon for their teammates. if ( pPlayer->mo->IsTeammate( players[SCOREBOARD_GetViewPlayer()].mo ) && !PLAYER_IsTrueSpectator ( &players[SCOREBOARD_GetViewPlayer()] ) ) ulDesiredSprite = SPRITE_ALLY; } // Draw a chat icon over the player if they're typing. if ( pPlayer->bChatting ) ulDesiredSprite = SPRITE_CHAT; // Draw a console icon over the player if they're in the console. if ( pPlayer->bInConsole ) ulDesiredSprite = SPRITE_INCONSOLE; // Draw a lag icon over their head if they're lagging. if ( pPlayer->bLagging ) ulDesiredSprite = SPRITE_LAG; // Draw a flag/skull above this player if he's carrying one. if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_USETEAMITEM ) { if ( pPlayer->bOnTeam ) { if ( oneflagctf ) { AInventory *pInventory = pPlayer->mo->FindInventory( PClass::FindClass( "WhiteFlag" )); if ( pInventory ) ulDesiredSprite = SPRITE_WHITEFLAG; } else { pTeamItem = TEAM_FindOpposingTeamsItemInPlayersInventory ( pPlayer ); if ( pTeamItem ) ulDesiredSprite = SPRITE_TEAMITEM; } } } // Draw the terminator artifact over the terminator. if ( terminator && ( pPlayer->cheats2 & CF2_TERMINATORARTIFACT )) ulDesiredSprite = SPRITE_TERMINATORARTIFACT; // Draw the possession artifact over the player. if (( possession || teampossession ) && ( pPlayer->cheats2 & CF2_POSSESSIONARTIFACT )) ulDesiredSprite = SPRITE_POSSESSIONARTIFACT; return ulDesiredSprite; }
static int GetScoreForTeam( int t ) { if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode() ) & GMF_PLAYERSEARNFRAGS ) return TEAM_GetFragCount( t ); else if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode() ) & GMF_PLAYERSEARNWINS ) return TEAM_GetWinCount( t ); return TEAM_GetScore( t ); }
//***************************************************************************** // bool CAMPAIGN_DidPlayerBeatMap( void ) { // Preliminary check. if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS ) { // If the console player isn't on a team, he DEFINITELY lost. if ( players[consoleplayer].bOnTeam == false ) return ( false ); // If this is teamplay, compare the fragcount of the two teams. if ( GAMEMODE_GetFlags(GAMEMODE_GetCurrentMode()) & GMF_PLAYERSEARNFRAGS ) { for ( ULONG i = 0; i < teams.Size( ); i++ ) { if ( TEAM_GetFragCount( players[consoleplayer].ulTeam ) < TEAM_GetFragCount( i )) return ( false ); } } // If this is a teamgame or team possession, compare the team scores. if ( GAMEMODE_GetFlags(GAMEMODE_GetCurrentMode()) & GMF_PLAYERSEARNPOINTS ) { for ( ULONG i = 0; i < teams.Size( ); i++ ) { if ( TEAM_GetScore( players[consoleplayer].ulTeam ) < TEAM_GetScore( i )) return ( false ); } } // If this is teamlms, compare the team wins. if ( GAMEMODE_GetFlags(GAMEMODE_GetCurrentMode()) & GMF_PLAYERSEARNWINS ) { for ( ULONG i = 0; i < teams.Size( ); i++ ) { if ( TEAM_GetWinCount( players[consoleplayer].ulTeam ) < TEAM_GetWinCount( i )) return ( false ); } } } // If it's a deathmatch, check the player's spread. else if ( deathmatch ) { if ( SCOREBOARD_CalcSpread( consoleplayer ) < 0 ) return ( false ); } // Passed all checks! return ( true ); }
//***************************************************************************** // void JOINQUEUE_PrintQueue( void ) { if ( NETWORK_GetState( ) != NETSTATE_SERVER ) { Printf ( "Only the server can print the join queue\n" ); return; } bool bQueueEmpty = true; for ( ULONG ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) { if ( g_lJoinQueue[ulIdx].ulPlayer < MAXPLAYERS ) { player_t* pPlayer = &players[ulIdx]; bQueueEmpty = false; Printf ( "%02lu - %s", ulIdx + 1, pPlayer->userinfo.netname ); if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS ) Printf ( " - %s", TEAM_CheckIfValid ( g_lJoinQueue[ulIdx].ulTeam ) ? TEAM_GetName ( g_lJoinQueue[ulIdx].ulTeam ) : "auto team selection" ); Printf ( "\n" ); } } if ( bQueueEmpty ) Printf ( "The join queue is empty\n" ); }
//***************************************************************************** // bool COOP_VoodooDollsSelectedByGameMode ( void ) { // [BB] Voodoo dolls are only used in coop. if ( !( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_COOPERATIVE ) ) return false; // [BB] Only use them if the compat flag tells us to. if ( sv_coopspawnvoodoodolls == false ) return false; return true; }
//***************************************************************************** // void COOP_PotentiallyStoreUVDPickup ( const PClass *pType ) { // [BB] The current game mode doesn't need voodoo dolls, so no need to store any pickups. if ( COOP_VoodooDollsSelectedByGameMode() == false ) return; // [BB] There is no ingame joining in such gamemodes, so no need to store any pickups. if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_MAPRESETS ) return; // [BB] Nothing to store. if ( pType == NULL ) return; // [BB] We only store weapons and keys since they might be crucial to finish a map. if ( ( pType->IsDescendantOf( RUNTIME_CLASS( AWeapon )) == false ) && ( pType->IsDescendantOf( RUNTIME_CLASS( AKey )) == false ) ) return; const FName pickupName = pType->TypeName.GetChars(); if ( UVDpickupMap.CheckKey( pickupName ) == false ) UVDpickupMap.Insert( pickupName, 1 ); }
bool AArtiTeleport::Use (bool pickup) { fixed_t destX; fixed_t destY; angle_t destAngle; // [BC] Let the server decide where we go. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return ( true ); } // [BB] If this is a team game and there are valid team starts for the team // the owner is on, teleport to one of the team starts. const ULONG ownerTeam = Owner->player ? Owner->player->ulTeam : teams.Size( ); if ( ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS ) && TEAM_CheckIfValid ( ownerTeam ) && ( teams[ownerTeam].TeamStarts.Size( ) > 0 ) ) { unsigned int selections = teams[ownerTeam].TeamStarts.Size (); unsigned int i = pr_tele() % selections; destX = teams[ownerTeam].TeamStarts[i].x; destY = teams[ownerTeam].TeamStarts[i].y; destAngle = ANG45 * (teams[ownerTeam].TeamStarts[i].angle/45); } else if (deathmatch) { unsigned int selections = deathmatchstarts.Size (); unsigned int i = pr_tele() % selections; destX = deathmatchstarts[i].x; destY = deathmatchstarts[i].y; destAngle = ANG45 * (deathmatchstarts[i].angle/45); } else { FMapThing *pSpot = NULL; // [BB] If there is a designated start for this player use it. if ( playerstarts[Owner->player - players].type != 0 ) pSpot = &playerstarts[Owner->player - players]; // [BB] Otherwise we just have to select a start at random from all available player starts. else pSpot = SelectRandomCooperativeSpot( Owner->player - players ); if ( pSpot != NULL ) { destX = pSpot->x; destY = pSpot->y; destAngle = ANG45 * (pSpot->angle/45); } else I_Error( "ArtiTeleport: No player start found!" ); } P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false); bool canlaugh = true; if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) { // Teleporting away will undo any morph effects (pig) if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE) && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) { canlaugh = false; } } if (canlaugh) { // Full volume laugh S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE); // [BC] Play the laugh for clients. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SoundActor( Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE ); } return true; }
//***************************************************************************** // [BB, RC] Returns whether the player wears a carrier icon (flag/skull/hellstone/etc) and removes any invalid ones. // bool medal_PlayerHasCarrierIcon ( ULONG ulPlayer ) { player_t *pPlayer = &players[ulPlayer]; AInventory *pInventory = NULL; bool bInvalid = false; bool bHasIcon = true; // [BB] If the player has no icon, he obviously doesn't have a carrier icon. if ( pPlayer->pIcon == NULL ) return false; // Verify that our current icon is valid. if ( pPlayer->pIcon && pPlayer->pIcon->bTeamItemFloatyIcon == false ) { switch ( (ULONG)( pPlayer->pIcon->state - pPlayer->pIcon->SpawnState )) { // Flag/skull icon. Delete it if the player no longer has it. case S_WHITEFLAG: case ( S_WHITEFLAG + 1 ): case ( S_WHITEFLAG + 2 ): case ( S_WHITEFLAG + 3 ): case ( S_WHITEFLAG + 4 ): case ( S_WHITEFLAG + 5 ): { // Delete the icon if teamgame has been turned off, or if the player // is not on a team. if (( teamgame == false ) || ( pPlayer->bOnTeam == false )) { bInvalid = true; break; } // Delete the white flag if the player no longer has it. pInventory = pPlayer->mo->FindInventory( PClass::FindClass( "WhiteFlag" )); if ( pInventory == NULL ) { bInvalid = true; break; } } break; // Terminator artifact icon. Delete it if the player no longer has it. case S_TERMINATORARTIFACT: case ( S_TERMINATORARTIFACT + 1 ): case ( S_TERMINATORARTIFACT + 2 ): case ( S_TERMINATORARTIFACT + 3 ): if (( terminator == false ) || (( pPlayer->cheats2 & CF2_TERMINATORARTIFACT ) == false )) bInvalid = true; break; // Possession artifact icon. Delete it if the player no longer has it. case S_POSSESSIONARTIFACT: case ( S_POSSESSIONARTIFACT + 1 ): case ( S_POSSESSIONARTIFACT + 2 ): case ( S_POSSESSIONARTIFACT + 3 ): if ((( possession == false ) && ( teampossession == false )) || (( pPlayer->cheats2 & CF2_POSSESSIONARTIFACT ) == false )) bInvalid = true; break; default: bHasIcon = false; break; } } if ( pPlayer->pIcon && pPlayer->pIcon->bTeamItemFloatyIcon ) { if ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_USETEAMITEM ) bInvalid = ( TEAM_FindOpposingTeamsItemInPlayersInventory ( pPlayer ) == NULL ); } // Remove it. if ( bInvalid && bHasIcon ) { players[ulPlayer].pIcon->Destroy( ); players[ulPlayer].pIcon = NULL; medal_TriggerMedal( ulPlayer, g_MedalQueue[ulPlayer][0].ulMedal ); } return bHasIcon && !bInvalid; }
//***************************************************************************** // void medal_SelectIcon( ULONG ulPlayer ) { AInventory *pInventory; player_t *pPlayer; ULONG ulActualSprite = NUM_SPRITES; // [BB] If ulPlayer carries a TeamItem, e.g. flag or skull, we store a pointer // to it in pTeamItem and set the floaty icon to the carry (or spawn) state of // the TeamItem. We also need to copy the Translation of the TeamItem to the // FloatyIcon. AInventory *pTeamItem = NULL; if ( ulPlayer >= MAXPLAYERS ) return; pPlayer = &players[ulPlayer]; if ( pPlayer->mo == NULL ) return; // Allow the user to disable icons. if (( cl_icons == false ) || ( NETWORK_GetState( ) == NETSTATE_SERVER ) || pPlayer->bSpectating ) { if ( pPlayer->pIcon ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } return; } // Verify that our current icon is valid. (i.e. We may have had a chat bubble, then // stopped talking, so we need to delete it). if ( pPlayer->pIcon && pPlayer->pIcon->bTeamItemFloatyIcon == false ) { switch ( (ULONG)( pPlayer->pIcon->state - pPlayer->pIcon->SpawnState )) { // Chat icon. Delete it if the player is no longer talking. case S_CHAT: if ( pPlayer->bChatting == false ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_CHAT; break; // In console icon. Delete it if the player is no longer in the console. case S_INCONSOLE: case ( S_INCONSOLE + 1): if ( pPlayer->bInConsole == false ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_INCONSOLE; break; // Ally icon. Delete it if the player is now our enemy or if we're spectating. // [BB] Dead spectators shall keep the icon for their teammates. case S_ALLY: if ( PLAYER_IsTrueSpectator ( &players[ SCOREBOARD_GetViewPlayer() ] ) || ( !pPlayer->mo->IsTeammate( players[ SCOREBOARD_GetViewPlayer() ].mo ) ) ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_ALLY; break; // Flag/skull icon. Delete it if the player no longer has it. case S_WHITEFLAG: case ( S_WHITEFLAG + 1 ): case ( S_WHITEFLAG + 2 ): case ( S_WHITEFLAG + 3 ): case ( S_WHITEFLAG + 4 ): case ( S_WHITEFLAG + 5 ): { bool bDelete = false; // Delete the icon if teamgame has been turned off, or if the player // is not on a team. if (( teamgame == false ) || ( pPlayer->bOnTeam == false )) { bDelete = true; } // Delete the white flag if the player no longer has it. pInventory = pPlayer->mo->FindInventory( PClass::FindClass( "WhiteFlag" )); if (( oneflagctf ) && ( pInventory == NULL )) bDelete = true; // We wish to delete the icon, so do that now. if ( bDelete ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_WHITEFLAG; } break; // Terminator artifact icon. Delete it if the player no longer has it. case S_TERMINATORARTIFACT: case ( S_TERMINATORARTIFACT + 1 ): case ( S_TERMINATORARTIFACT + 2 ): case ( S_TERMINATORARTIFACT + 3 ): if (( terminator == false ) || (( pPlayer->cheats2 & CF2_TERMINATORARTIFACT ) == false )) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_TERMINATORARTIFACT; break; // Lag icon. Delete it if the player is no longer lagging. case S_LAG: if ((( NETWORK_GetState( ) != NETSTATE_CLIENT ) && ( CLIENTDEMO_IsPlaying( ) == false )) || ( pPlayer->bLagging == false )) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_LAG; break; // Possession artifact icon. Delete it if the player no longer has it. case S_POSSESSIONARTIFACT: case ( S_POSSESSIONARTIFACT + 1 ): case ( S_POSSESSIONARTIFACT + 2 ): case ( S_POSSESSIONARTIFACT + 3 ): if ((( possession == false ) && ( teampossession == false )) || (( pPlayer->cheats2 & CF2_POSSESSIONARTIFACT ) == false )) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else ulActualSprite = SPRITE_POSSESSIONARTIFACT; break; } } // Check if we need to have an icon above us, or change the current icon. { if ( pPlayer->pIcon && pPlayer->pIcon->bTeamItemFloatyIcon ) { if ( !( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_USETEAMITEM ) || ( pPlayer->bOnTeam == false ) || ( TEAM_FindOpposingTeamsItemInPlayersInventory ( pPlayer ) == NULL ) ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } else { ulActualSprite = SPRITE_TEAMITEM; } } ULONG ulFrame = 65535; const ULONG ulDesiredSprite = medal_GetDesiredIcon ( pPlayer, pTeamItem ); // [BB] Determine the frame based on the desired sprite. switch ( ulDesiredSprite ) { case SPRITE_ALLY: ulFrame = S_ALLY; break; case SPRITE_CHAT: ulFrame = S_CHAT; break; case SPRITE_INCONSOLE: ulFrame = S_INCONSOLE; break; case SPRITE_LAG: ulFrame = S_LAG; break; case SPRITE_WHITEFLAG: ulFrame = S_WHITEFLAG; break; case SPRITE_TEAMITEM: ulFrame = 0; break; case SPRITE_TERMINATORARTIFACT: ulFrame = S_TERMINATORARTIFACT; break; case SPRITE_POSSESSIONARTIFACT: ulFrame = S_POSSESSIONARTIFACT; break; default: break; } // We have an icon that needs to be spawned. if ((( ulFrame != 65535 ) && ( ulDesiredSprite != NUM_SPRITES ))) { // [BB] If a TeamItem icon replaces an existing non-team icon, we have to delete the old icon first. if ( pPlayer->pIcon && ( pPlayer->pIcon->bTeamItemFloatyIcon == false ) && pTeamItem ) { pPlayer->pIcon->Destroy( ); pPlayer->pIcon = NULL; } if (( pPlayer->pIcon == NULL ) || ( ulDesiredSprite != ulActualSprite )) { if ( pPlayer->pIcon == NULL ) { pPlayer->pIcon = Spawn<AFloatyIcon>( pPlayer->mo->x, pPlayer->mo->y, pPlayer->mo->z + pPlayer->mo->height + ( 4 * FRACUNIT ), NO_REPLACE ); if ( pTeamItem ) { pPlayer->pIcon->bTeamItemFloatyIcon = true; FName Name = "Carry"; FState *CarryState = pTeamItem->FindState( Name ); // [BB] If the TeamItem has a Carry state (like the built in flags), use it. // Otherwise use the spawn state (the built in skulls don't have a carry state). if ( CarryState ) pPlayer->pIcon->SetState( CarryState ); else pPlayer->pIcon->SetState( pTeamItem->SpawnState ); pPlayer->pIcon->Translation = pTeamItem->Translation; } else { pPlayer->pIcon->bTeamItemFloatyIcon = false; } } if ( pPlayer->pIcon ) { // [BB] Potentially the new icon overrides an existing medal, so make sure that it doesn't fade out. pPlayer->pIcon->lTick = 0; pPlayer->pIcon->SetTracer( pPlayer->mo ); if ( pPlayer->pIcon->bTeamItemFloatyIcon == false ) pPlayer->pIcon->SetState( pPlayer->pIcon->SpawnState + ulFrame ); } } } } }
//***************************************************************************** // 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( ); }
BOOL CALLBACK settings_GameplayTab_Callback( HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam ) { switch ( Message ) { case WM_INITDIALOG: g_hDlg_GameplayTab = hDlg; // Enable tab gradients on XP and later. if ( pEnableThemeDialogTexture != NULL ) pEnableThemeDialogTexture ( hDlg, ETDT_ENABLETAB ); // Limit the input length for the spin boxes. SendDlgItemMessage( hDlg, IDC_FRAGLIMIT, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_TIMELIMIT, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_POINTLIMIT, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_DUELLIMIT, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_WINLIMIT, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_MAXLIVES, EM_SETLIMITTEXT, 4, 0 ); SendDlgItemMessage( hDlg, IDC_TIMELIMITSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); SendDlgItemMessage( hDlg, IDC_FRAGLIMITSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); SendDlgItemMessage( hDlg, IDC_POINTLIMITSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); SendDlgItemMessage( hDlg, IDC_DUELLIMITSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); SendDlgItemMessage( hDlg, IDC_WINLIMITSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); SendDlgItemMessage( hDlg, IDC_MAXLIVESSPIN, UDM_SETRANGE, 0, MAKELONG( 9999,0 )); // Initialize all the fields. SetDlgItemText( hDlg, IDC_FRAGLIMIT, fraglimit.GetGenericRep( CVAR_String ).String ); SetDlgItemText( hDlg, IDC_TIMELIMIT, timelimit.GetGenericRep( CVAR_String ).String ); SetDlgItemText( hDlg, IDC_POINTLIMIT, pointlimit.GetGenericRep( CVAR_String ).String ); SetDlgItemText( hDlg, IDC_DUELLIMIT, duellimit.GetGenericRep( CVAR_String ).String ); SetDlgItemText( hDlg, IDC_WINLIMIT, winlimit.GetGenericRep( CVAR_String ).String ); SetDlgItemText( hDlg, IDC_MAXLIVES, sv_maxlives.GetGenericRep( CVAR_String ).String ); // Fill the list with game modes, and select the current one. for ( int i = 0; i < NUM_GAMEMODES; i++ ) SendDlgItemMessage( hDlg, IDC_GAMEPLAYMODE, CB_INSERTSTRING, -1, (WPARAM)(LPSTR) GameModeVals[i].name ); SendDlgItemMessage( hDlg, IDC_GAMEPLAYMODE, CB_SETCURSEL, (LONG) GAMEMODE_GetCurrentMode( ), 0 ); // Fill and select modifiers. for ( int i = 0; i < NUM_MODIFIERS; i++ ) SendDlgItemMessage( hDlg, IDC_MODIFIER, CB_INSERTSTRING, -1, (WPARAM)(LPSTR) ModifierVals[i].name ); SendDlgItemMessage( hDlg, IDC_MODIFIER, CB_SETCURSEL, (LONG) GAMEMODE_GetModifier( ), 0 ); // Fill and select skills. for ( int i = 0; i < NUM_SKILLS; i++ ) SendDlgItemMessage( hDlg, IDC_SKILL, CB_INSERTSTRING, -1, (WPARAM)(LPSTR) GameskillVals[i].name ); SendDlgItemMessage( hDlg, IDC_SKILL, CB_SETCURSEL, gameskill.GetGenericRep( CVAR_Int ).Int, 0 ); // Fill and select botskills. for ( int i = 0; i < NUM_BOTSKILLS; i++ ) SendDlgItemMessage( hDlg, IDC_BOTSKILL, CB_INSERTSTRING, -1, (WPARAM)(LPSTR) BotskillVals[i].name ); SendDlgItemMessage( hDlg, IDC_BOTSKILL, CB_SETCURSEL, botskill.GetGenericRep( CVAR_Int ).Int, 0 ); settings_GameplayTab_ShowOrHideItems( hDlg ); break; case WM_COMMAND: if ( LOWORD( wParam ) == IDC_GAMEPLAYMODE ) settings_GameplayTab_ShowOrHideItems( hDlg ); if ( LOWORD( wParam ) == IDC_MAPLIST ) DialogBox( g_hInst, MAKEINTRESOURCE( IDD_MAPROTATION ), hDlg, SERVERCONSOLE_MapRotationCallback ); if ( LOWORD( wParam ) == IDC_SHOWFLAGS ) DialogBox( g_hInst, MAKEINTRESOURCE( IDD_DMFLAGS ), hDlg, SERVERCONSOLE_DMFlagsCallback ); break; } return FALSE; }
void settings_Dialog_SaveSettings( ) { char szBuffer[1024]; FString fsRestartMessage = ""; //================================== // Save the "server" tab's settings. //================================== HWND hDlg = g_hDlg_ServerTab; GetDlgItemText( hDlg, IDC_SERVERNAME, szBuffer, 1024 ); sv_hostname = szBuffer; if ( g_ulNumPWADs > 0 ) { GetDlgItemText( hDlg, IDC_WADURL, szBuffer, 1024 ); sv_website = szBuffer; } GetDlgItemText( hDlg, IDC_EMAIL, szBuffer, 1024 ); sv_hostemail = szBuffer; sv_updatemaster = !!SendDlgItemMessage( hDlg, IDC_UPDATEMASTER, BM_GETCHECK, 0, 0 ); sv_broadcast = !!SendDlgItemMessage( hDlg, IDC_BROADCAST, BM_GETCHECK, 0, 0 ); sv_motd = g_fsMOTD; //==================================== // Save the "gameplay" tab's settings. //==================================== hDlg = g_hDlg_GameplayTab; // Save limits. settings_Dialog_DoLimit( IDC_FRAGLIMIT, fraglimit, szBuffer ); settings_Dialog_DoLimit( IDC_POINTLIMIT, pointlimit, szBuffer ); settings_Dialog_DoLimit( IDC_WINLIMIT, winlimit, szBuffer ); settings_Dialog_DoLimit( IDC_DUELLIMIT, duellimit, szBuffer ); settings_Dialog_DoLimit( IDC_MAXLIVES, sv_maxlives, szBuffer ); // Timelimit is a float. GetDlgItemText( hDlg, IDC_TIMELIMIT, szBuffer, 1024 ); // [BB] We shouldn't compare two floats with "!=". if ( abs( timelimit - atof( szBuffer ) ) > 1e-8 ) timelimit = atof( szBuffer ); // Save game mode. if ( (LONG) GAMEMODE_GetCurrentMode( ) != SendDlgItemMessage( hDlg, IDC_GAMEPLAYMODE, CB_GETCURSEL, 0, 0 )) { fsRestartMessage += "Game mode\n"; GAMEMODE_SetCurrentMode( (GAMEMODE_e) SendDlgItemMessage( hDlg, IDC_GAMEPLAYMODE, CB_GETCURSEL, 0, 0 ) ); } // Save modifier. if ( (LONG) GAMEMODE_GetModifier( ) != SendDlgItemMessage( hDlg, IDC_MODIFIER, CB_GETCURSEL, 0, 0 )) { fsRestartMessage += "Modifier\n"; GAMEMODE_SetModifier( (MODIFIER_e) SendDlgItemMessage( hDlg, IDC_MODIFIER, CB_GETCURSEL, 0, 0 ) ); } // Save skill. if ( SendDlgItemMessage( hDlg, IDC_SKILL, CB_GETCURSEL, 0, 0 ) != gameskill ) { fsRestartMessage += "Skill\n"; gameskill = SendDlgItemMessage( hDlg, IDC_SKILL, CB_GETCURSEL, 0, 0 ); } // Save botskill. if ( SendDlgItemMessage( hDlg, IDC_BOTSKILL, CB_GETCURSEL, 0, 0 ) != botskill ) { fsRestartMessage += "Bots' skill\n"; botskill = SendDlgItemMessage( hDlg, IDC_BOTSKILL, CB_GETCURSEL, 0, 0 ); } //==================================== // Save the "admin" tab's settings. //==================================== hDlg = g_hDlg_AdminTab; // Update logfile. GetDlgItemText( hDlg, IDC_LOGFILE, szBuffer, 256 ); if ( stricmp( szBuffer, g_szDesiredLogFilename ) != 0 || sv_logfilenametimestamp != ( SendDlgItemMessage( hDlg, IDC_LOGFILENAME_TIMESTAMP, BM_GETCHECK, 0, 0 ) == BST_CHECKED )) { sv_logfilenametimestamp = ( SendDlgItemMessage( hDlg, IDC_LOGFILENAME_TIMESTAMP, BM_GETCHECK, 0, 0 ) == BST_CHECKED ); if ( Logfile ) StopLogging( ); if ( SendDlgItemMessage( hDlg, IDC_ENABLELOGGING, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) StartLogging( szBuffer ); } GetDlgItemText( hDlg, IDC_RCONPASSWORD, szBuffer, 1024 ); sv_rconpassword = ( SendDlgItemMessage( hDlg, IDC_ALLOWRCON, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) ? szBuffer : ""; //================================== // Save the "access" tab's settings. //================================== hDlg = g_hDlg_AccessTab; // Save voting settings. if ( SendDlgItemMessage( hDlg, IDC_ALLOW_CALLVOTE, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) { if ( SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_SPECTATOR, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) sv_nocallvote = 0; else sv_nocallvote = 2; } else sv_nocallvote = 1; sv_noduellimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_DUELLIMIT, BM_GETCHECK, 0, 0 ); sv_nofraglimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_FRAGLIMIT, BM_GETCHECK, 0, 0 ); sv_nokickvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_KICKLIMIT, BM_GETCHECK, 0, 0 ); sv_nopointlimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_POINTLIMIT, BM_GETCHECK, 0, 0 ); sv_notimelimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_TIMELIMIT, BM_GETCHECK, 0, 0 ); sv_nowinlimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_WINLIMIT, BM_GETCHECK, 0, 0 ); sv_nomapvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_MAP, BM_GETCHECK, 0, 0 ); GetDlgItemText( hDlg, IDC_PASSWORD, szBuffer, 1024 ); sv_password = szBuffer; sv_forcepassword = !!SendDlgItemMessage( hDlg, IDC_REQUIREPW, BM_GETCHECK, 0, 0 ); GetDlgItemText( hDlg, IDC_JOINPASSWORD, szBuffer, 1024 ); sv_joinpassword = szBuffer; sv_forcejoinpassword = !!SendDlgItemMessage( hDlg, IDC_REQUIREJOINPW, BM_GETCHECK, 0, 0 ); GetDlgItemText( hDlg, IDC_MAXCLIENTS, szBuffer, 1024 ); sv_maxclients = atoi( szBuffer ); GetDlgItemText( hDlg, IDC_MAXPLAYERS, szBuffer, 1024 ); sv_maxplayers = atoi( szBuffer ); // Is a map change needed? if ( fsRestartMessage.Len( )) { fsRestartMessage = "The following settings require a map change to take effect:\n\n" + fsRestartMessage + "\nRestart the map?"; if ( MessageBox( g_hDlg_Dialog, fsRestartMessage.GetChars( ), SERVERCONSOLE_TITLESTRING, MB_YESNO|MB_ICONQUESTION ) == IDYES ) { FString String; String.Format( "map %s", level.mapname ); SERVER_AddCommand( String.GetChars( )); } } // Update our 'public/private/LAN' section in the statusbar. SERVERCONSOLE_UpdateBroadcasting( ); }
void cht_DoCheat (player_t *player, int cheat) { static const char * BeholdPowers[9] = { "PowerInvulnerable", "PowerStrength", "PowerInvisibility", "PowerIronFeet", "MapRevealer", "PowerLightAmp", "PowerShadow", "PowerMask", "PowerTargeter", }; const PClass *type; AInventory *item; const char *msg = ""; char msgbuild[32]; int i; switch (cheat) { case CHT_IDDQD: if (!(player->cheats & CF_GODMODE) && player->playerstate == PST_LIVE) { if (player->mo) player->mo->health = deh.GodHealth; player->health = deh.GodHealth; } // fall through to CHT_GOD case CHT_GOD: player->cheats ^= CF_GODMODE; if (gameinfo.gametype != GAME_Chex) { if (player->cheats & CF_GODMODE) msg = GStrings("STSTR_DQDON"); else msg = GStrings("STSTR_DQDOFF"); } else { if (player->cheats & CF_GODMODE) msg = GStrings("STSTR_CDQDON"); else msg = GStrings("STSTR_CDQDOFF"); } if ( NETWORK_GetState( ) != NETSTATE_SERVER ) SB_state = screen->GetPageCount (); break; case CHT_BUDDHA: player->cheats ^= CF_BUDDHA; if (player->cheats & CF_BUDDHA) msg = GStrings("TXT_BUDDHAON"); else msg = GStrings("TXT_BUDDHAOFF"); break; case CHT_NOCLIP: player->cheats ^= CF_NOCLIP; if (player->cheats & CF_NOCLIP) msg = GStrings("STSTR_NCON"); else msg = GStrings("STSTR_NCOFF"); break; case CHT_NOVELOCITY: player->cheats ^= CF_NOVELOCITY; if (player->cheats & CF_NOVELOCITY) msg = GStrings("TXT_LEADBOOTSON"); else msg = GStrings("TXT_LEADBOOTSOFF"); break; case CHT_FLY: if (player->mo != NULL) { player->cheats ^= CF_FLY; if (player->cheats & CF_FLY) { player->mo->flags |= MF_NOGRAVITY; player->mo->flags2 |= MF2_FLY; msg = GStrings("TXT_LIGHTER"); } else { player->mo->flags &= ~MF_NOGRAVITY; player->mo->flags2 &= ~MF2_FLY; msg = GStrings("TXT_GRAVITY"); } } break; case CHT_MORPH: msg = cht_Morph (player, PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer), true); break; case CHT_NOTARGET: player->cheats ^= CF_NOTARGET; if (player->cheats & CF_NOTARGET) msg = "notarget ON"; else msg = "notarget OFF"; break; case CHT_ANUBIS: player->cheats ^= CF_FRIGHTENING; if (player->cheats & CF_FRIGHTENING) msg = "\"Quake with fear!\""; else msg = "No more ogre armor"; break; case CHT_CHASECAM: player->cheats ^= CF_CHASECAM; if (player->cheats & CF_CHASECAM) msg = "chasecam ON"; else msg = "chasecam OFF"; R_ResetViewInterpolation (); break; case CHT_CHAINSAW: if (player->mo != NULL && player->health >= 0) { type = PClass::FindClass ("Chainsaw"); if (player->mo->FindInventory (type) == NULL) { player->mo->GiveInventoryType (type); } if(gameinfo.gametype != GAME_Chex) msg = GStrings("STSTR_CHOPPERS"); else msg = GStrings("STSTR_CCHOPPERS"); } // [RH] The original cheat also set powers[pw_invulnerability] to true. // Since this is a timer and not a boolean, it effectively turned off // the invulnerability powerup, although it looks like it was meant to // turn it on. break; case CHT_POWER: if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); if (item != NULL) { item->Destroy (); msg = GStrings("TXT_CHEATPOWEROFF"); } else { player->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); msg = GStrings("TXT_CHEATPOWERON"); } } break; case CHT_IDKFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "keys"); cht_Give (player, "armor"); if(gameinfo.gametype != GAME_Chex) msg = GStrings("STSTR_KFAADDED"); else msg = GStrings("STSTR_CKFAADDED"); break; case CHT_IDFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "armor"); if(gameinfo.gametype != GAME_Chex) msg = GStrings("STSTR_FAADDED"); else msg = GStrings("STSTR_CFAADDED"); break; case CHT_BEHOLDV: case CHT_BEHOLDS: case CHT_BEHOLDI: case CHT_BEHOLDR: case CHT_BEHOLDA: case CHT_BEHOLDL: case CHT_PUMPUPI: case CHT_PUMPUPM: case CHT_PUMPUPT: i = cheat - CHT_BEHOLDV; if (i == 4) { level.flags2 ^= LEVEL2_ALLMAP; } else if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory (BeholdPowers[i]); if (item == NULL) { if (i != 0) { cht_Give(player, BeholdPowers[i]); if (cheat == CHT_BEHOLDS) { P_GiveBody (player->mo, -100); } } else { // Let's give the item here so that the power doesn't need colormap information. cht_Give(player, "InvulnerabilitySphere"); } } else { item->Destroy (); } } msg = GStrings("STSTR_BEHOLDX"); break; case CHT_MASSACRE: { int killcount = P_Massacre (); // killough 3/22/98: make more intelligent about plural // Ty 03/27/98 - string(s) *not* externalized mysnprintf (msgbuild, countof(msgbuild), "%d Monster%s Killed", killcount, killcount==1 ? "" : "s"); msg = msgbuild; } break; case CHT_HEALTH: if (player->mo != NULL && player->playerstate == PST_LIVE) { player->health = player->mo->health = player->mo->GetDefault()->health; msg = GStrings("TXT_CHEATHEALTH"); } break; case CHT_KEYS: cht_Give (player, "keys"); msg = GStrings("TXT_CHEATKEYS"); break; // [GRB] case CHT_RESSURECT: if (player->playerstate != PST_LIVE && player->mo != NULL) { if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk))) { Printf("Unable to resurrect. Player is no longer connected to its body.\n"); } else { player->playerstate = PST_LIVE; player->health = player->mo->health = player->mo->GetDefault()->health; player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight; player->mo->flags = player->mo->GetDefault()->flags; player->mo->flags2 = player->mo->GetDefault()->flags2; player->mo->flags3 = player->mo->GetDefault()->flags3; player->mo->flags4 = player->mo->GetDefault()->flags4; player->mo->flags5 = player->mo->GetDefault()->flags5; player->mo->renderflags &= ~RF_INVISIBLE; player->mo->height = player->mo->GetDefault()->height; player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); if (!(player->mo->flags2 & MF2_DONTTRANSLATE)) { player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); } player->mo->DamageType = NAME_None; // player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) { P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) { P_UndoPlayerMorph(player, player); } } } break; case CHT_GIMMIEA: cht_Give (player, "ArtiInvulnerability"); msg = "Valador's Ring of Invunerability"; break; case CHT_GIMMIEB: cht_Give (player, "ArtiInvisibility"); msg = "Shadowsphere"; break; case CHT_GIMMIEC: cht_Give (player, "ArtiHealth"); msg = "Quartz Flask"; break; case CHT_GIMMIED: cht_Give (player, "ArtiSuperHealth"); msg = "Mystic Urn"; break; case CHT_GIMMIEE: cht_Give (player, "ArtiTomeOfPower"); msg = "Tyketto's Tome of Power"; break; case CHT_GIMMIEF: cht_Give (player, "ArtiTorch"); msg = "Torch"; break; case CHT_GIMMIEG: cht_Give (player, "ArtiTimeBomb"); msg = "Delmintalintar's Time Bomb of the Ancients"; break; case CHT_GIMMIEH: cht_Give (player, "ArtiEgg"); msg = "Torpol's Morph Ovum"; break; case CHT_GIMMIEI: cht_Give (player, "ArtiFly"); msg = "Inhilicon's Wings of Wrath"; break; case CHT_GIMMIEJ: cht_Give (player, "ArtiTeleport"); msg = "Darchala's Chaos Device"; break; case CHT_GIMMIEZ: for (int i=0;i<16;i++) { cht_Give (player, "artifacts"); } msg = "All artifacts!"; break; case CHT_TAKEWEAPS: if (player->morphTics || player->mo == NULL || player->mo->health <= 0) { return; } { // Take away all weapons that are either non-wimpy or use ammo. AInventory **invp = &player->mo->Inventory, **lastinvp; for (item = *invp; item != NULL; item = *invp) { lastinvp = invp; invp = &(*invp)->Inventory; if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) { AWeapon *weap = static_cast<AWeapon *> (item); if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || weap->AmmoType1 != NULL) { item->Destroy (); invp = lastinvp; } } } } msg = GStrings("TXT_CHEATIDKFA"); break; case CHT_NOWUDIE: cht_Suicide (player); msg = GStrings("TXT_CHEATIDDQD"); break; case CHT_ALLARTI: for (int i=0;i<25;i++) { cht_Give (player, "artifacts"); } msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_PUZZLE: cht_Give (player, "puzzlepieces"); msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_MDK: if (player->mo == NULL) { Printf ("What do you want to kill outside of a game?\n"); } // else if (!deathmatch) { // Don't allow this in deathmatch even with cheats enabled, because it's // a very very cheap kill. // [Dusk] <jino> and summoning 5000 bfg balls isn't? P_LineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE, P_AimLineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, NAME_MDK, NAME_BulletPuff); } break; case CHT_DONNYTRUMP: cht_Give (player, "HealthTraining"); msg = GStrings("TXT_MIDASTOUCH"); break; case CHT_LEGO: if (player->mo != NULL && player->health >= 0) { int oldpieces = ASigil::GiveSigilPiece (player->mo); item = player->mo->FindInventory (RUNTIME_CLASS(ASigil)); if (item != NULL) { if (oldpieces == 5) { item->Destroy (); } else { player->PendingWeapon = static_cast<AWeapon *> (item); } } } break; case CHT_PUMPUPH: cht_Give (player, "MedPatch"); cht_Give (player, "MedicalKit"); cht_Give (player, "SurgeryKit"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPP: cht_Give (player, "AmmoSatchel"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPS: cht_Give (player, "UpgradeStamina", 10); cht_Give (player, "UpgradeAccuracy"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_CLEARFROZENPROPS: player->cheats &= ~(CF_FROZEN|CF_TOTALLYFROZEN); msg = "Frozen player properties turned off"; break; /* [BB] Skulltag doesn't use this. case CHT_FREEZE: bglobal.changefreeze ^= 1; if (bglobal.freeze ^ bglobal.changefreeze) { msg = GStrings("TXT_FREEZEON"); } else { msg = GStrings("TXT_FREEZEOFF"); } break; */ } if (!*msg) // [SO] Don't print blank lines! return; if( ( cheat != CHT_CHASECAM ) || ( !( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_COOPERATIVE ) && ( player->bSpectating == false ) && !(dmflags2 & DF2_CHASECAM))){ if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVER_Printf( PRINT_HIGH, "%s is a cheater: %s\n", player->userinfo.netname, msg ); else if ( player == &players[consoleplayer] || CLIENTDEMO_IsFreeSpectatorPlayer( player ) ) Printf ("%s\n", msg); // [BB] The server already ensures that all clients see the cheater message. else if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg); } }