add support for civ specific player template, see #2877

This was SVN commit r16092.
This commit is contained in:
mimo 2014-12-31 09:31:41 +00:00
parent f984ba40ee
commit 9329506e0d
4 changed files with 79 additions and 3 deletions

View file

@ -11,7 +11,7 @@ PlayerManager.prototype.Init = function()
PlayerManager.prototype.AddPlayer = function(ent)
{
var id = this.playerEntities.length;
var cmpPlayer = Engine.QueryInterface(ent, IID_Player)
var cmpPlayer = Engine.QueryInterface(ent, IID_Player);
cmpPlayer.SetPlayerID(id);
this.playerEntities.push(ent);
// initialize / update the diplomacy arrays
@ -28,6 +28,41 @@ PlayerManager.prototype.AddPlayer = function(ent)
return id;
};
/**
* To avoid possible problems with cached quantities (as in TechnologyManager),
* we first remove all entities from this player, and add them back after the replacement.
* Futhermore, because of the Engine.FlushDestroyedComponents, it should only be called during setup/init
* and not during the game
*/
PlayerManager.prototype.ReplacePlayer = function(id, ent)
{
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
var entities = cmpRangeManager.GetEntitiesByPlayer(id);
for (var e of entities)
{
var cmpOwnership = Engine.QueryInterface(e, IID_Ownership);
if (cmpOwnership)
cmpOwnership.SetOwner(-1);
}
var oldent = this.playerEntities[id];
var cmpPlayer = Engine.QueryInterface(oldent, IID_Player);
var diplo = cmpPlayer.GetDiplomacy();
var cmpPlayer = Engine.QueryInterface(ent, IID_Player);
cmpPlayer.SetPlayerID(id);
this.playerEntities[id] = ent;
cmpPlayer.SetDiplomacy(diplo);
Engine.DestroyEntity(oldent);
Engine.FlushDestroyedComponents();
for (var e of entities)
{
var cmpOwnership = Engine.QueryInterface(e, IID_Ownership);
if (cmpOwnership)
cmpOwnership.SetOwner(id);
}
};
/**
* Returns the player entity ID for the given player ID.
* The player ID must be valid (else there will be an error message).

View file

@ -25,6 +25,10 @@ function LoadPlayerSettings(settings, newPlayers)
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var numPlayers = cmpPlayerManager.GetNumPlayers();
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templatesList = cmpTemplateManager.FindAllTemplates(false);
var previousPlayers = numPlayers;
// Remove existing players or add new ones
if (newPlayers)
{
@ -35,11 +39,23 @@ function LoadPlayerSettings(settings, newPlayers)
else
warn("Player.js: Setup has no player data - using defaults");
previousPlayers = Math.min(numPlayers, settingsNumPlayers);
while (settingsNumPlayers > numPlayers)
{
// Add player entity to engine
// TODO: Get player template name from civ data
var entID = Engine.AddEntity("special/player");
var playerTemplate = "special/player";
if (numPlayers > 0)
{
var pDefs = playerDefaults ? playerDefaults[numPlayers] : {};
var pData = settings.PlayerData ? settings.PlayerData[numPlayers-1] : {};
var civ = getSetting(pData, pDefs, "Civ");
}
else
var civ = "gaia";
if (templatesList.indexOf("special/"+civ+"_player") !== -1)
playerTemplate = "special/"+civ+"_player";
var entID = Engine.AddEntity(playerTemplate);
var cmpPlayer = Engine.QueryInterface(entID, IID_Player);
if (!cmpPlayer)
throw("Player.js: Error creating player entity " + numPlayers);
@ -55,6 +71,23 @@ function LoadPlayerSettings(settings, newPlayers)
}
}
// Even when no new player, we must check the template compatibility as player template may be civ dependent
for (var i = 1; i < previousPlayers; ++i)
{
var pDefs = playerDefaults ? playerDefaults[i] : {};
var pData = settings.PlayerData ? settings.PlayerData[i-1] : {};
var civ = getSetting(pData, pDefs, "Civ");
var neededTemplate = "special/player";
if (templatesList.indexOf("special/"+civ+"_player") !== -1)
neededTemplate = "special/"+civ+"_player";
var entID = cmpPlayerManager.GetPlayerByID(i);
if (cmpTemplateManager.GetCurrentTemplateName(entID) === neededTemplate)
continue;
// We need to recreate this player to have the right template
entID = Engine.AddEntity(neededTemplate);
cmpPlayerManager.ReplacePlayer(i, entID);
}
// Initialize the player data
for (var i = 0; i < numPlayers; ++i)
{

View file

@ -84,6 +84,7 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddEntity> ("AddEntity");
m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddLocalEntity> ("AddLocalEntity");
m_ScriptInterface.RegisterFunction<void, int, CComponentManager::Script_DestroyEntity> ("DestroyEntity");
m_ScriptInterface.RegisterFunction<void, CComponentManager::Script_FlushDestroyedComponents> ("FlushDestroyedComponents");
m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadJSONFile> ("ReadJSONFile");
m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadCivJSONFile> ("ReadCivJSONFile");
m_ScriptInterface.RegisterFunction<std::vector<std::string>, std::wstring, bool, CComponentManager::Script_FindJSONFiles> ("FindJSONFiles");
@ -507,6 +508,12 @@ void CComponentManager::Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPriv
componentManager->DestroyComponentsSoon(ent);
}
void CComponentManager::Script_FlushDestroyedComponents(ScriptInterface::CxPrivate *pCxPrivate)
{
CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
componentManager->FlushDestroyedComponents();
}
void CComponentManager::ResetState()
{
// Delete all dynamic message subscriptions

View file

@ -283,6 +283,7 @@ private:
static int Script_AddEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName);
static int Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName);
static void Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent);
static void Script_FlushDestroyedComponents(ScriptInterface::CxPrivate* pCxPrivate);
static CScriptVal Script_ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName);
static CScriptVal Script_ReadCivJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName);
static std::vector<std::string> Script_FindJSONFiles(ScriptInterface::CxPrivate* pCxPrivate, std::wstring subPath, bool recursive);