2013-02-22 08:32:22 +01:00
|
|
|
/* Copyright (C) 2013 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2004-07-27 23:00:53 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
|
|
|
#include "Game.h"
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "graphics/GameView.h"
|
2011-02-03 02:12:24 +01:00
|
|
|
#include "graphics/LOSTexture.h"
|
2011-04-03 21:15:15 +02:00
|
|
|
#include "graphics/ParticleManager.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "graphics/UnitManager.h"
|
2012-08-15 02:10:44 +02:00
|
|
|
#include "gui/GUIManager.h"
|
2012-08-31 21:08:41 +02:00
|
|
|
#include "lib/config2.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "lib/timer.h"
|
2008-06-16 20:19:35 +02:00
|
|
|
#include "network/NetClient.h"
|
2010-06-30 23:41:04 +02:00
|
|
|
#include "network/NetServer.h"
|
|
|
|
#include "network/NetTurnManager.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "ps/CConsole.h"
|
|
|
|
#include "ps/CLogger.h"
|
|
|
|
#include "ps/CStr.h"
|
|
|
|
#include "ps/Loader.h"
|
2011-03-05 02:56:59 +01:00
|
|
|
#include "ps/LoaderThunks.h"
|
2010-06-30 23:41:04 +02:00
|
|
|
#include "ps/Overlay.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "ps/Profile.h"
|
2010-08-07 00:16:05 +02:00
|
|
|
#include "ps/Replay.h"
|
2006-03-21 21:55:45 +01:00
|
|
|
#include "ps/World.h"
|
2011-12-22 15:04:32 +01:00
|
|
|
#include "ps/GameSetup/GameSetup.h"
|
2011-04-03 21:15:15 +02:00
|
|
|
#include "renderer/Renderer.h"
|
2012-08-06 21:10:47 +02:00
|
|
|
#include "renderer/TimeManager.h"
|
2010-06-30 23:41:04 +02:00
|
|
|
#include "scripting/ScriptingHost.h"
|
|
|
|
#include "scriptinterface/ScriptInterface.h"
|
2010-01-09 20:20:14 +01:00
|
|
|
#include "simulation2/Simulation2.h"
|
2010-06-30 23:41:04 +02:00
|
|
|
#include "simulation2/components/ICmpPlayer.h"
|
|
|
|
#include "simulation2/components/ICmpPlayerManager.h"
|
2013-06-06 13:13:57 +02:00
|
|
|
#include "soundmanager/ISoundManager.h"
|
2006-11-12 05:02:36 +01:00
|
|
|
|
2006-10-08 05:28:22 +02:00
|
|
|
extern bool g_GameRestarted;
|
2006-10-08 05:07:54 +02:00
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
/**
|
|
|
|
* Globally accessible pointer to the CGame object.
|
|
|
|
**/
|
2004-07-31 17:57:18 +02:00
|
|
|
CGame *g_Game=NULL;
|
2004-07-27 23:00:53 +02:00
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
**/
|
2010-06-30 23:41:04 +02:00
|
|
|
CGame::CGame(bool disableGraphics):
|
2006-03-21 21:55:45 +01:00
|
|
|
m_World(new CWorld(this)),
|
2010-05-20 20:09:23 +02:00
|
|
|
m_Simulation2(new CSimulation2(&m_World->GetUnitManager(), m_World->GetTerrain())),
|
2010-06-30 23:41:04 +02:00
|
|
|
m_GameView(disableGraphics ? NULL : new CGameView(this)),
|
2006-01-02 04:07:29 +01:00
|
|
|
m_GameStarted(false),
|
2006-01-23 04:56:48 +01:00
|
|
|
m_Paused(false),
|
2010-06-30 23:41:04 +02:00
|
|
|
m_SimRate(1.0f),
|
2011-12-22 15:04:32 +01:00
|
|
|
m_PlayerID(-1),
|
|
|
|
m_IsSavedGame(false)
|
2004-08-05 15:07:51 +02:00
|
|
|
{
|
2010-08-07 00:16:05 +02:00
|
|
|
m_ReplayLogger = new CReplayLogger(m_Simulation2->GetScriptInterface());
|
|
|
|
// TODO: should use CDummyReplayLogger unless activated by cmd-line arg, perhaps?
|
|
|
|
|
2007-01-13 23:44:42 +01:00
|
|
|
// Need to set the CObjectManager references after various objects have
|
|
|
|
// been initialised, so do it here rather than via the initialisers above.
|
2010-06-30 23:41:04 +02:00
|
|
|
if (m_GameView)
|
|
|
|
m_World->GetUnitManager().SetObjectManager(m_GameView->GetObjectManager());
|
2010-01-09 20:20:14 +01:00
|
|
|
|
2010-08-07 00:16:05 +02:00
|
|
|
m_TurnManager = new CNetLocalTurnManager(*m_Simulation2, GetReplayLogger()); // this will get replaced if we're a net server/client
|
2010-05-20 02:59:01 +02:00
|
|
|
|
2010-05-20 20:09:23 +02:00
|
|
|
m_Simulation2->LoadDefaultScripts();
|
2004-08-05 15:07:51 +02:00
|
|
|
}
|
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*
|
|
|
|
**/
|
2004-08-05 15:07:51 +02:00
|
|
|
CGame::~CGame()
|
|
|
|
{
|
2005-03-30 18:14:19 +02:00
|
|
|
// Again, the in-game call tree is going to be different to the main menu one.
|
2010-06-30 23:41:04 +02:00
|
|
|
if (CProfileManager::IsInitialised())
|
|
|
|
g_Profiler.StructuralReset();
|
2006-03-21 21:55:45 +01:00
|
|
|
|
2010-05-20 02:59:01 +02:00
|
|
|
delete m_TurnManager;
|
2006-03-21 21:55:45 +01:00
|
|
|
delete m_GameView;
|
2010-01-09 20:20:14 +01:00
|
|
|
delete m_Simulation2;
|
2006-03-21 21:55:45 +01:00
|
|
|
delete m_World;
|
2010-08-07 00:16:05 +02:00
|
|
|
delete m_ReplayLogger;
|
2004-08-05 15:07:51 +02:00
|
|
|
}
|
|
|
|
|
2010-05-20 02:59:01 +02:00
|
|
|
void CGame::SetTurnManager(CNetTurnManager* turnManager)
|
|
|
|
{
|
|
|
|
if (m_TurnManager)
|
|
|
|
delete m_TurnManager;
|
2010-06-30 23:41:04 +02:00
|
|
|
|
2010-05-20 02:59:01 +02:00
|
|
|
m_TurnManager = turnManager;
|
2010-06-30 23:41:04 +02:00
|
|
|
|
|
|
|
if (m_TurnManager)
|
|
|
|
m_TurnManager->SetPlayerID(m_PlayerID);
|
2010-05-20 02:59:01 +02:00
|
|
|
}
|
2005-03-22 03:17:55 +01:00
|
|
|
|
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
/**
|
|
|
|
* Initializes the game with the set of attributes provided.
|
|
|
|
* Makes calls to initialize the game view, world, and simulation objects.
|
|
|
|
* Calls are made to facilitate progress reporting of the initialization.
|
|
|
|
**/
|
2011-10-30 02:07:28 +02:00
|
|
|
void CGame::RegisterInit(const CScriptValRooted& attribs, const std::string& savedState)
|
2005-03-22 03:17:55 +01:00
|
|
|
{
|
2011-10-30 02:07:28 +02:00
|
|
|
m_InitialSavedState = savedState;
|
2011-12-22 15:04:32 +01:00
|
|
|
m_IsSavedGame = !savedState.empty();
|
2011-10-30 02:07:28 +02:00
|
|
|
|
2011-10-24 16:31:05 +02:00
|
|
|
m_Simulation2->SetInitAttributes(attribs);
|
2011-01-12 13:29:00 +01:00
|
|
|
|
2010-10-30 06:02:42 +02:00
|
|
|
std::string mapType;
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "mapType", mapType);
|
2010-06-30 23:41:04 +02:00
|
|
|
|
2013-04-04 01:24:22 +02:00
|
|
|
float speed;
|
|
|
|
if (m_Simulation2->GetScriptInterface().HasProperty(attribs.get(), "gameSpeed") && m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "gameSpeed", speed))
|
|
|
|
SetSimRate(speed);
|
|
|
|
|
2005-03-22 03:17:55 +01:00
|
|
|
LDR_BeginRegistering();
|
|
|
|
|
2011-03-05 02:56:59 +01:00
|
|
|
RegMemFun(m_Simulation2, &CSimulation2::ProgressiveLoad, L"Simulation init", 1000);
|
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
// RC, 040804 - GameView needs to be initialized before World, otherwise GameView initialization
|
2005-03-22 03:17:55 +01:00
|
|
|
// overwrites anything stored in the map file that gets loaded by CWorld::Initialize with default
|
2010-06-30 23:41:04 +02:00
|
|
|
// values. At the minute, it's just lighting settings, but could be extended to store camera position.
|
|
|
|
// Storing lighting settings in the game view seems a little odd, but it's no big deal; maybe move it at
|
2005-03-22 03:17:55 +01:00
|
|
|
// some point to be stored in the world object?
|
2010-06-30 23:41:04 +02:00
|
|
|
if (m_GameView)
|
|
|
|
m_GameView->RegisterInit();
|
2010-10-30 06:02:42 +02:00
|
|
|
|
Implements skirmish maps, based on patch by sanderd17, fixes #1198. Skirmish maps are like scenarios, except the player can choose their civ during match setup. To create a skirmish map: place some skirmish entities for each player in Atlas (see templates/skirmish/* for examples), uncheck the player's civ in Atlas' player panel if desired, and save in the maps/skirmishes directory. The map will appear in match setup under the "Skirmish" match type.
Implements custom, VFS-based map load/save dialogs for Atlas (replaces
broken native file dialogs), fixes #631, #889.
Fixes map loading/saving to handle arbitrary subdirectories for better
organization.
Adds default settings to Atlas player panel, fixes #1872. Each setting
now has a checkbox to choose whether it should be saved with the map
(avoids writing lots of useless default data for each map).
Adds map preview setting to Atlas, refs #1745.
Cleans up and simplifies some duplicate code.
Fixes optional serialization performance test.
This was SVN commit r13938.
2013-10-04 04:29:16 +02:00
|
|
|
if (mapType == "random")
|
2010-10-30 06:02:42 +02:00
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
// Load random map attributes
|
|
|
|
std::wstring scriptFile;
|
|
|
|
CScriptValRooted settings;
|
|
|
|
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "script", scriptFile);
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "settings", settings);
|
|
|
|
|
|
|
|
m_World->RegisterInitRMS(scriptFile, settings, m_PlayerID);
|
2010-10-30 06:02:42 +02:00
|
|
|
}
|
Implements skirmish maps, based on patch by sanderd17, fixes #1198. Skirmish maps are like scenarios, except the player can choose their civ during match setup. To create a skirmish map: place some skirmish entities for each player in Atlas (see templates/skirmish/* for examples), uncheck the player's civ in Atlas' player panel if desired, and save in the maps/skirmishes directory. The map will appear in match setup under the "Skirmish" match type.
Implements custom, VFS-based map load/save dialogs for Atlas (replaces
broken native file dialogs), fixes #631, #889.
Fixes map loading/saving to handle arbitrary subdirectories for better
organization.
Adds default settings to Atlas player panel, fixes #1872. Each setting
now has a checkbox to choose whether it should be saved with the map
(avoids writing lots of useless default data for each map).
Adds map preview setting to Atlas, refs #1745.
Cleans up and simplifies some duplicate code.
Fixes optional serialization performance test.
This was SVN commit r13938.
2013-10-04 04:29:16 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::wstring mapFile;
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "map", mapFile);
|
|
|
|
CScriptValRooted settings;
|
|
|
|
if (mapType == "skirmish")
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "settings", settings);
|
|
|
|
|
|
|
|
m_World->RegisterInit(mapFile, settings, m_PlayerID);
|
|
|
|
}
|
2010-10-30 06:02:42 +02:00
|
|
|
|
2011-12-22 15:04:32 +01:00
|
|
|
if (m_IsSavedGame)
|
2011-10-30 02:07:28 +02:00
|
|
|
RegMemFun(this, &CGame::LoadInitialState, L"Loading game", 1000);
|
|
|
|
|
2005-03-22 03:17:55 +01:00
|
|
|
LDR_EndRegistering();
|
|
|
|
}
|
2010-06-30 23:41:04 +02:00
|
|
|
|
2011-10-30 02:07:28 +02:00
|
|
|
int CGame::LoadInitialState()
|
|
|
|
{
|
2011-12-22 15:04:32 +01:00
|
|
|
ENSURE(m_IsSavedGame);
|
2011-10-30 02:07:28 +02:00
|
|
|
ENSURE(!m_InitialSavedState.empty());
|
|
|
|
|
|
|
|
std::string state;
|
|
|
|
m_InitialSavedState.swap(state); // deletes the original to save a bit of memory
|
|
|
|
|
|
|
|
std::stringstream stream(state);
|
|
|
|
|
|
|
|
bool ok = m_Simulation2->DeserializeState(stream);
|
2011-12-22 15:04:32 +01:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
CancelLoad(L"Failed to load saved game state. It might have been\nsaved with an incompatible version of the game.");
|
|
|
|
return 0;
|
|
|
|
}
|
2011-10-30 02:07:28 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-02-01 02:34:17 +01:00
|
|
|
/**
|
|
|
|
* Game initialization has been completed. Set game started flag and start the session.
|
|
|
|
*
|
|
|
|
* @return PSRETURN 0
|
|
|
|
**/
|
2005-03-22 03:17:55 +01:00
|
|
|
PSRETURN CGame::ReallyStartGame()
|
|
|
|
{
|
2013-10-16 19:58:12 +02:00
|
|
|
// Call the script function InitGame only for new games, not saved games
|
2011-12-22 15:04:32 +01:00
|
|
|
if (!m_IsSavedGame)
|
|
|
|
{
|
|
|
|
CScriptVal settings;
|
|
|
|
m_Simulation2->GetScriptInterface().GetProperty(m_Simulation2->GetInitAttributes().get(), "settings", settings);
|
|
|
|
m_Simulation2->InitGame(settings);
|
|
|
|
}
|
2011-01-12 13:29:00 +01:00
|
|
|
|
2013-02-22 08:32:22 +01:00
|
|
|
// We need to do an initial Interpolate call to set up all the models etc,
|
|
|
|
// because Update might never interpolate (e.g. if the game starts paused)
|
|
|
|
// and we could end up rendering before having set up any models (so they'd
|
|
|
|
// all be invisible)
|
|
|
|
Interpolate(0, 0);
|
|
|
|
|
|
|
|
m_GameStarted=true;
|
|
|
|
|
|
|
|
// Render a frame to begin loading assets
|
|
|
|
if (CRenderer::IsInitialised())
|
|
|
|
Render();
|
|
|
|
|
2006-06-10 01:07:11 +02:00
|
|
|
// Call the reallyStartGame GUI function, but only if it exists
|
2010-06-30 23:41:04 +02:00
|
|
|
if (g_GUI && g_GUI->HasPages())
|
2005-06-28 01:04:34 +02:00
|
|
|
{
|
2010-05-20 02:59:01 +02:00
|
|
|
jsval fval, rval;
|
|
|
|
JSBool ok = JS_GetProperty(g_ScriptingHost.getContext(), g_GUI->GetScriptObject(), "reallyStartGame", &fval);
|
2011-04-30 15:01:45 +02:00
|
|
|
ENSURE(ok);
|
2010-05-20 02:59:01 +02:00
|
|
|
if (ok && !JSVAL_IS_VOID(fval))
|
2012-08-21 01:59:50 +02:00
|
|
|
JS_CallFunctionValue(g_ScriptingHost.getContext(), g_GUI->GetScriptObject(), fval, 0, NULL, &rval);
|
2005-06-28 01:04:34 +02:00
|
|
|
}
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
if (g_NetClient)
|
|
|
|
g_NetClient->LoadFinished();
|
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
debug_printf(L"GAME STARTED, ALL INIT COMPLETE\n");
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2005-03-30 18:14:19 +02:00
|
|
|
// The call tree we've built for pregame probably isn't useful in-game.
|
2010-06-30 23:41:04 +02:00
|
|
|
if (CProfileManager::IsInitialised())
|
|
|
|
g_Profiler.StructuralReset();
|
2005-03-30 18:14:19 +02:00
|
|
|
|
2006-10-08 05:28:22 +02:00
|
|
|
// Mark terrain as modified so the minimap can repaint (is there a cleaner way of handling this?)
|
|
|
|
g_GameRestarted = true;
|
|
|
|
|
2005-03-22 03:17:55 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
int CGame::GetPlayerID()
|
|
|
|
{
|
|
|
|
return m_PlayerID;
|
|
|
|
}
|
2004-08-16 17:19:17 +02:00
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
void CGame::SetPlayerID(int playerID)
|
|
|
|
{
|
|
|
|
m_PlayerID = playerID;
|
|
|
|
if (m_TurnManager)
|
|
|
|
m_TurnManager->SetPlayerID(m_PlayerID);
|
2004-07-27 23:00:53 +02:00
|
|
|
}
|
|
|
|
|
2011-10-30 02:07:28 +02:00
|
|
|
void CGame::StartGame(const CScriptValRooted& attribs, const std::string& savedState)
|
2010-06-30 23:41:04 +02:00
|
|
|
{
|
2010-08-07 00:16:05 +02:00
|
|
|
m_ReplayLogger->StartGame(attribs);
|
|
|
|
|
2011-10-30 02:07:28 +02:00
|
|
|
RegisterInit(attribs, savedState);
|
2010-06-30 23:41:04 +02:00
|
|
|
}
|
2007-02-01 02:34:17 +01:00
|
|
|
|
|
|
|
// TODO: doInterpolate is optional because Atlas interpolates explicitly,
|
|
|
|
// so that it has more control over the update rate. The game might want to
|
|
|
|
// do the same, and then doInterpolate should be redundant and removed.
|
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
bool CGame::Update(const double deltaRealTime, bool doInterpolate)
|
2004-07-27 23:00:53 +02:00
|
|
|
{
|
2007-01-24 21:17:28 +01:00
|
|
|
if (m_Paused)
|
|
|
|
return true;
|
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
if (!m_TurnManager)
|
|
|
|
return true;
|
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
const double deltaSimTime = deltaRealTime * m_SimRate;
|
2006-06-06 08:31:17 +02:00
|
|
|
|
2010-02-07 21:06:16 +01:00
|
|
|
bool ok = true;
|
2012-06-06 21:37:03 +02:00
|
|
|
if (deltaSimTime)
|
2010-05-01 18:20:58 +02:00
|
|
|
{
|
2011-02-21 03:16:12 +01:00
|
|
|
// To avoid confusing the profiler, we need to trigger the new turn
|
|
|
|
// while we're not nested inside any PROFILE blocks
|
2012-06-06 21:37:03 +02:00
|
|
|
if (m_TurnManager->WillUpdate(deltaSimTime))
|
2011-02-21 03:16:12 +01:00
|
|
|
g_Profiler.Turn();
|
|
|
|
|
2010-12-06 20:58:06 +01:00
|
|
|
// At the normal sim rate, we currently want to render at least one
|
|
|
|
// frame per simulation turn, so let maxTurns be 1. But for fast-forward
|
|
|
|
// sim rates we want to allow more, so it's not bounded by framerate,
|
|
|
|
// so just use the sim rate itself as the number of turns per frame.
|
|
|
|
size_t maxTurns = (size_t)m_SimRate;
|
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
if (m_TurnManager->Update(deltaSimTime, maxTurns))
|
2011-02-03 02:12:24 +01:00
|
|
|
{
|
2011-11-09 14:09:01 +01:00
|
|
|
{
|
|
|
|
PROFILE3("gui sim update");
|
|
|
|
g_GUI->SendEventToAll("SimulationUpdate");
|
|
|
|
}
|
|
|
|
|
2011-02-03 02:12:24 +01:00
|
|
|
GetView()->GetLOSTexture().MakeDirty();
|
|
|
|
}
|
2012-08-06 21:10:47 +02:00
|
|
|
|
|
|
|
if (CRenderer::IsInitialised())
|
|
|
|
g_Renderer.GetTimeManager().Update(deltaSimTime);
|
2010-05-01 18:20:58 +02:00
|
|
|
}
|
2010-02-07 21:06:16 +01:00
|
|
|
|
2007-01-24 21:17:28 +01:00
|
|
|
if (doInterpolate)
|
2010-01-09 20:20:14 +01:00
|
|
|
{
|
2012-06-06 21:37:03 +02:00
|
|
|
m_TurnManager->Interpolate(deltaSimTime, deltaRealTime);
|
2013-06-13 14:12:44 +02:00
|
|
|
|
2012-08-31 21:08:41 +02:00
|
|
|
if ( g_SoundManager )
|
|
|
|
g_SoundManager->IdleTask();
|
2010-01-09 20:20:14 +01:00
|
|
|
}
|
2011-04-03 21:15:15 +02:00
|
|
|
|
2007-01-24 21:17:28 +01:00
|
|
|
return ok;
|
2005-12-29 05:52:40 +01:00
|
|
|
}
|
2006-03-21 21:55:45 +01:00
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
void CGame::Interpolate(float simFrameLength, float realFrameLength)
|
2010-05-20 02:59:01 +02:00
|
|
|
{
|
2010-06-30 23:41:04 +02:00
|
|
|
if (!m_TurnManager)
|
|
|
|
return;
|
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
m_TurnManager->Interpolate(simFrameLength, realFrameLength);
|
2010-05-20 02:59:01 +02:00
|
|
|
}
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
static CColor BrokenColor(0.3f, 0.3f, 0.3f, 1.0f);
|
2011-03-26 21:17:21 +01:00
|
|
|
|
|
|
|
void CGame::CachePlayerColours()
|
2005-01-29 01:11:50 +01:00
|
|
|
{
|
2011-03-26 21:17:21 +01:00
|
|
|
m_PlayerColours.clear();
|
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
CmpPtr<ICmpPlayerManager> cmpPlayerManager(*m_Simulation2, SYSTEM_ENTITY);
|
2012-02-08 03:46:15 +01:00
|
|
|
if (!cmpPlayerManager)
|
2011-03-26 21:17:21 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
int numPlayers = cmpPlayerManager->GetNumPlayers();
|
|
|
|
m_PlayerColours.resize(numPlayers);
|
|
|
|
|
|
|
|
for (int i = 0; i < numPlayers; ++i)
|
|
|
|
{
|
|
|
|
CmpPtr<ICmpPlayer> cmpPlayer(*m_Simulation2, cmpPlayerManager->GetPlayerByID(i));
|
2012-02-08 03:46:15 +01:00
|
|
|
if (!cmpPlayer)
|
2011-03-26 21:17:21 +01:00
|
|
|
m_PlayerColours[i] = BrokenColor;
|
|
|
|
else
|
|
|
|
m_PlayerColours[i] = cmpPlayer->GetColour();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CColor CGame::GetPlayerColour(int player) const
|
|
|
|
{
|
|
|
|
if (player < 0 || player >= (int)m_PlayerColours.size())
|
2010-06-30 23:41:04 +02:00
|
|
|
return BrokenColor;
|
2011-03-26 21:17:21 +01:00
|
|
|
|
|
|
|
return m_PlayerColours[player];
|
2005-01-29 01:11:50 +01:00
|
|
|
}
|