etqw-sdk/source/game/rules/GameRules_Objective.cpp

479 lines
11 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "GameRules_Objective.h"
#include "../Player.h"
#include "../script/Script_Helper.h"
#include "../script/Script_ScriptObject.h"
#include "../guis/UserInterfaceLocal.h"
#include "../rules/VoteManager.h"
sdGameRulesObjectiveNetworkState::sdGameRulesObjectiveNetworkState( void ) {
}
void sdGameRulesObjectiveNetworkState::MakeDefault( void ) {
sdGameRulesNetworkState::MakeDefault();
winningTeam = NULL;
}
void sdGameRulesObjectiveNetworkState::Write( idFile* file ) const {
sdGameRulesNetworkState::Write( file );
file->WriteInt( winningTeam ? winningTeam->GetIndex() : -1 );
}
void sdGameRulesObjectiveNetworkState::Read( idFile* file ) {
sdGameRulesNetworkState::Read( file );
int winningTeamIndex;
file->ReadInt( winningTeamIndex );
winningTeam = winningTeamIndex == -1 ? NULL : &sdTeamManager::GetInstance().GetTeamByIndex( winningTeamIndex );
}
/*
===============================================================================
sdGameRulesObjective
===============================================================================
*/
CLASS_DECLARATION( sdGameRules, sdGameRulesObjective )
END_CLASS
/*
================
sdGameRulesObjective::sdGameRulesObjective
================
*/
sdGameRulesObjective::sdGameRulesObjective( void ) : winningTeam( NULL ) {
}
/*
================
sdGameRulesObjective::~sdGameRulesObjective
================
*/
sdGameRulesObjective::~sdGameRulesObjective( void ) {
}
/*
================
sdGameRulesObjective::GameState_Review
================
*/
void sdGameRulesObjective::GameState_Review( void ) {
if ( nextState != GS_INACTIVE ) {
return;
}
if ( si_gameReviewReadyWait.GetBool() ) {
if ( ArePlayersReady() != RS_READY ) {
return;
}
}
NextStateDelayed( GS_NEXTMAP, MINS2MS( g_gameReviewPause.GetFloat() ) );
}
/*
================
sdGameRulesObjective::GameState_NextGame
================
*/
void sdGameRulesObjective::GameState_NextGame( void ) {
if ( nextState != GS_INACTIVE ) {
return;
}
NewState( GS_WARMUP );
// put everyone back in from endgame spectate
CheckRespawns( true );
}
/*
================
sdGameRulesObjective::GameState_Warmup
================
*/
void sdGameRulesObjective::GameState_Warmup( void ) {
if ( !CanStartMatch() ) {
needsRestart = true;
return;
}
StartMatch();
}
/*
================
sdGameRulesObjective::GameState_Countdown
================
*/
void sdGameRulesObjective::GameState_Countdown( void ) {
}
/*
================
sdGameRulesObjective::GameState_GameOn
================
*/
void sdGameRulesObjective::GameState_GameOn( void ) {
if ( gameLocal.GameState() == GAMESTATE_STARTUP || nextState != GS_INACTIVE ) {
return;
}
int timeLimit = GetTimeLimit();
if ( timeLimit != 0 ) {
if ( gameLocal.time - matchStartedTime >= timeLimit ) {
OnTimeLimitHit();
EndGame();
}
}
}
/*
================
sdGameRulesObjective::GameState_NextMap
================
*/
void sdGameRulesObjective::GameState_NextMap( void ) {
winningTeam = NULL;
BackupPlayerTeams();
if ( gameLocal.NextMap() ) {
return;
}
gameLocal.LocalMapRestart();
sdTeamManagerLocal& manager = sdTeamManager::GetInstance();
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gameLocal.GetClient( i );
if ( player == NULL ) {
continue;
}
player->GetProficiencyTable().Clear( false );
player->Killed( NULL, NULL, 0, vec3_zero, -1, NULL );
player->ServerForceRespawn( true );
}
NewState( GS_NEXTGAME );
}
/*
================
sdGameRulesObjective::OnGameState_Review
================
*/
void sdGameRulesObjective::OnGameState_Review( void ) {
if ( !gameLocal.isClient ) {
nextState = GS_INACTIVE; // used to abort a game. cancel out any upcoming state change
ClearPlayerReadyFlags();
}
}
/*
================
sdGameRulesObjective::OnGameState_Countdown
================
*/
void sdGameRulesObjective::OnGameState_Countdown( void ) {
}
/*
================
sdGameRulesObjective::OnGameState_GameOn
================
*/
void sdGameRulesObjective::OnGameState_GameOn( void ) {
if ( !gameLocal.isClient ) {
if ( needsRestart ) {
needsRestart = false;
gameLocal.LocalMapRestart();
}
matchStartedTime = gameLocal.time;
}
}
/*
================
sdGameRulesObjective::OnGameState_NextMap
================
*/
void sdGameRulesObjective::OnGameState_NextMap( void ) {
ClearPlayerReadyFlags();
}
/*
================
sdGameRulesObjective::EndGame
================
*/
void sdGameRulesObjective::EndGame( void ) {
if ( IsWarmup() ) {
return;
}
NextStateDelayed( GS_GAMEREVIEW, 1000 );
RecordWinningTeam( winningTeam, "maps", true );
CallScriptEndGame();
}
/*
================
sdGameRulesObjective::ApplyNetworkState
================
*/
void sdGameRulesObjective::ApplyNetworkState( const sdEntityStateNetworkData& newState ) {
sdGameRules::ApplyNetworkState( newState );
NET_GET_NEW( sdGameRulesObjectiveNetworkState );
SetWinner( newData.winningTeam );
}
/*
================
sdGameRulesObjective::ReadNetworkState
================
*/
void sdGameRulesObjective::ReadNetworkState( const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, const idBitMsg& msg ) const {
sdGameRules::ReadNetworkState( baseState, newState, msg );
NET_GET_STATES( sdGameRulesObjectiveNetworkState );
sdTeamManagerLocal& teamManager = sdTeamManager::GetInstance();
newData.winningTeam = teamManager.ReadTeamFromStream( baseData.winningTeam, msg );
}
/*
================
sdGameRulesObjective::WriteNetworkState
================
*/
void sdGameRulesObjective::WriteNetworkState( const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, idBitMsg& msg ) const {
sdGameRules::WriteNetworkState( baseState, newState, msg );
NET_GET_STATES( sdGameRulesObjectiveNetworkState );
newData.winningTeam = GetWinningTeam();
sdTeamManagerLocal& teamManager = sdTeamManager::GetInstance();
teamManager.WriteTeamToStream( baseData.winningTeam, newData.winningTeam, msg );
}
/*
================
sdGameRulesObjective::CheckNetworkStateChanges
================
*/
bool sdGameRulesObjective::CheckNetworkStateChanges( const sdEntityStateNetworkData& baseState ) const {
if ( sdGameRules::CheckNetworkStateChanges( baseState ) ) {
return true;
}
NET_GET_BASE( sdGameRulesObjectiveNetworkState );
NET_CHECK_FIELD( winningTeam, GetWinningTeam() );
return false;
}
/*
================
sdGameRulesObjective::CreateNetworkStructure
================
*/
sdEntityStateNetworkData* sdGameRulesObjective::CreateNetworkStructure( void ) const {
return new sdGameRulesObjectiveNetworkState();
}
/*
================
sdGameRulesObjective::SetWinner
================
*/
void sdGameRulesObjective::SetWinner( sdTeamInfo* team ) {
if ( !gameLocal.isClient && ( gameState == GS_GAMEREVIEW ) ) {
gameLocal.Warning( "Attempted to set winning team after game has ended" );
return;
}
if ( winningTeam == team ) {
return;
}
winningTeam = team;
if( gameLocal.DoClientSideStuff() ) {
UpdateClientFromServerInfo( gameLocal.serverInfo, false );
}
}
/*
================
sdGameRulesObjective::ChangeMap
================
*/
bool sdGameRulesObjective::ChangeMap( const char* mapName ) {
idStr cleanMapName = mapName;
sdGameRules_SingleMapHelper::SanitizeMapName( cleanMapName, true );
idStr sessionCommand = va( "usermap %s", cleanMapName.c_str() );
cmdSystem->PushFrameCommand( sessionCommand.c_str() );
return true;
}
/*
================
sdGameRulesObjective::OnUserStartMap
================
*/
userMapChangeResult_e sdGameRulesObjective::OnUserStartMap( const char* text, idStr& reason, idStr& mapName ) {
return sdGameRules_SingleMapHelper::OnUserStartMap( text, reason, mapName );
}
/*
================
sdGameRulesObjective::GetGameTime
================
*/
int sdGameRulesObjective::GetGameTime( void ) const {
int ms;
if ( gameState == GS_WARMUP ) {
ms = 0;
} else if ( gameState == GS_COUNTDOWN ) {
ms = nextStateSwitch - gameLocal.time;
} else {
ms = GetTimeLimit() - ( gameLocal.time - matchStartedTime );
if ( ms < 0 ) {
ms = 0;
}
}
return ms;
}
/*
================
sdGameRulesObjective::GetTypeText
================
*/
const sdDeclLocStr* sdGameRulesObjective::GetTypeText( void ) const {
return declHolder.declLocStrType[ "game/gametype/objective" ];
}
/*
================
sdGameRulesObjective::ArgCompletion_StartGame
================
*/
void sdGameRulesObjective::ArgCompletion_StartGame( const idCmdArgs& args, argCompletionCallback_t callback ) {
sdGameRules_SingleMapHelper::ArgCompletion_StartGame( args, callback );
}
/*
============
sdGameRulesObjective::UpdateClientFromServerInfo
============
*/
void sdGameRulesObjective::UpdateClientFromServerInfo( const idDict& serverInfo, bool allowMedia ) {
sdGameRules::UpdateClientFromServerInfo( serverInfo, allowMedia );
idStr mapName = serverInfo.GetString( "si_map" );
if( mapName.IsEmpty() ) {
return;
}
mapName.StripFileExtension();
using namespace sdProperties;
// update status
if ( sdUserInterfaceScope* scope = gameLocal.globalProperties.GetSubScope( "campaignInfo" ) ) {
const idDict* metaData = gameLocal.mapMetaDataList->FindMetaData( mapName, &gameLocal.defaultMetaData );
if( allowMedia ) {
const sdDeclMapInfo* mapInfo = gameLocal.declMapInfoType.LocalFind( metaData->GetString( "mapinfo", "_default" ) );
// setup the backdrop
if ( sdProperty* property = scope->GetProperty( "backdrop", PT_STRING ) ) {
const char* value = mapInfo->GetData().GetString( "mtr_backdrop", "guis/assets/black" );
*property->value.stringValue = value;
}
const char* status = "current";
if( winningTeam != NULL ) {
status = winningTeam->GetLookupName();
}
SetupLoadScreenUI( *scope, status, true, 1, *metaData, mapInfo );
}
// setup the name
if ( sdProperty* property = scope->GetProperty( "name", PT_WSTRING ) ) {
*property->value.wstringValue = va( L"%hs", metaData->GetString( "pretty_name" ) );
}
// setup the number of maps
if ( sdProperty* property = scope->GetProperty( "numMaps", PT_FLOAT ) ) {
*property->value.floatValue = 1.0f;
}
if ( sdProperty* property = scope->GetProperty( "currentMap", PT_FLOAT ) ) {
*property->value.floatValue = 1.0f;
}
// setup the status
if ( sdProperty* property = scope->GetProperty( "ruleStatus", PT_WSTRING ) ) {
*property->value.wstringValue = L"";
}
}
}
/*
============
sdGameRulesObjective::Clear
============
*/
void sdGameRulesObjective::Clear( void ) {
sdGameRules::Clear();
winningTeam = NULL;
}
/*
============
sdGameRulesObjective::GetServerBrowserScore
============
*/
int sdGameRulesObjective::GetServerBrowserScore( const sdNetSession& session ) const {
int score = 0;
score += sdHotServerList::BROWSER_GOOD_BONUS - 1;
score += sdGameRules::GetServerBrowserScore( session );
return score;
}