1
0
forked from 0ad/0ad

Clean up LoadPlayerSettings.

Include gaia to make iteration easier.
Add TemplateExists() to the TemplateLoader. Refs #2877.

This was SVN commit r16099.
This commit is contained in:
leper 2015-01-01 23:10:24 +00:00
parent 8e30410109
commit a472944689
9 changed files with 113 additions and 110 deletions

View File

@ -31,8 +31,7 @@ PlayerManager.prototype.AddPlayer = function(ent)
/** /**
* To avoid possible problems with cached quantities (as in TechnologyManager), * 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. * 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 * Note: This should only be called during setup/init and not during the game
* and not during the game
*/ */
PlayerManager.prototype.ReplacePlayer = function(id, ent) PlayerManager.prototype.ReplacePlayer = function(id, ent)
{ {

View File

@ -24,21 +24,21 @@ function InitGame(settings)
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (settings.ExploreMap) if (settings.ExploreMap)
for (var i = 0; i < settings.PlayerData.length; i++) for (let i = 1; i < settings.PlayerData.length; ++i)
cmpRangeManager.ExploreAllTiles(i+1); cmpRangeManager.ExploreAllTiles(i);
else else
// Explore the map only inside the players' territory borders // Explore the map only inside the players' territory borders
cmpRangeManager.ExploreTerritories(); cmpRangeManager.ExploreTerritories();
let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
let cmpAIManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIManager); let cmpAIManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIManager);
for (let i = 0; i < settings.PlayerData.length; ++i) for (let i = 1; i < settings.PlayerData.length; ++i)
{ {
let cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i+1), IID_Player); let cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
cmpPlayer.SetCheatsEnabled(!!settings.CheatsEnabled); cmpPlayer.SetCheatsEnabled(!!settings.CheatsEnabled);
if (settings.PlayerData[i] && settings.PlayerData[i].AI && settings.PlayerData[i].AI != "") if (settings.PlayerData[i] && settings.PlayerData[i].AI && settings.PlayerData[i].AI != "")
{ {
cmpAIManager.AddPlayer(settings.PlayerData[i].AI, i+1, +settings.PlayerData[i].AIDiff); cmpAIManager.AddPlayer(settings.PlayerData[i].AI, i, +settings.PlayerData[i].AIDiff);
cmpPlayer.SetAI(true); cmpPlayer.SetAI(true);
// Sandbox: 50%, very easy: 50%, easy: 66%, Medium: 100%, hard: 133%, very hard: 166% // Sandbox: 50%, very easy: 50%, easy: 66%, Medium: 100%, hard: 133%, very hard: 166%
cmpPlayer.SetGatherRateMultiplier(Math.max(0.5,(+settings.PlayerData[i].AIDiff)/3.0)); cmpPlayer.SetGatherRateMultiplier(Math.max(0.5,(+settings.PlayerData[i].AIDiff)/3.0));

View File

@ -19,43 +19,35 @@ function LoadPlayerSettings(settings, newPlayers)
if (!(rawData && rawData.PlayerData)) if (!(rawData && rawData.PlayerData))
throw("Player.js: Error reading player_defaults.json"); throw("Player.js: Error reading player_defaults.json");
// Add gaia to simplify iteration
if (settings.PlayerData)
settings.PlayerData.unshift({});
var playerDefaults = rawData.PlayerData; var playerDefaults = rawData.PlayerData;
var playerData = settings.PlayerData;
// Get player manager // Get player manager
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var numPlayers = cmpPlayerManager.GetNumPlayers(); var numPlayers = cmpPlayerManager.GetNumPlayers();
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templatesList = cmpTemplateManager.FindAllTemplates(false);
var previousPlayers = numPlayers;
// Remove existing players or add new ones // Remove existing players or add new ones
if (newPlayers) if (newPlayers)
{ {
var settingsNumPlayers = 9; // default 8 players + gaia var settingsNumPlayers = 9; // default 8 players + gaia
if (settings.PlayerData) if (playerData)
settingsNumPlayers = settings.PlayerData.length + 1; // including gaia settingsNumPlayers = playerData.length; // includes gaia (see above)
else else
warn("Player.js: Setup has no player data - using defaults"); warn("Player.js: Setup has no player data - using defaults");
previousPlayers = Math.min(numPlayers, settingsNumPlayers);
while (settingsNumPlayers > numPlayers) while (settingsNumPlayers > numPlayers)
{ {
// Add player entity to engine // Add player entity to engine
var playerTemplate = "special/player"; var civ = getSetting(playerData, playerDefaults, i, "Civ");
if (numPlayers > 0) var template = cmpTemplateManager.TemplateExists("special/"+civ+"_player") ? "special/"+civ+"_player" : "special/player";
{ var entID = Engine.AddEntity(template);
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); var cmpPlayer = Engine.QueryInterface(entID, IID_Player);
if (!cmpPlayer) if (!cmpPlayer)
throw("Player.js: Error creating player entity " + numPlayers); throw("Player.js: Error creating player entity " + numPlayers);
@ -72,19 +64,15 @@ function LoadPlayerSettings(settings, newPlayers)
} }
// Even when no new player, we must check the template compatibility as player template may be civ dependent // 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) for (var i = 0; i < numPlayers; ++i)
{ {
var pDefs = playerDefaults ? playerDefaults[i] : {}; var civ = getSetting(playerData, playerDefaults, i, "Civ");
var pData = settings.PlayerData ? settings.PlayerData[i-1] : {}; var template = cmpTemplateManager.TemplateExists("special/"+civ+"_player") ? "special/"+civ+"_player" : "special/player";
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); var entID = cmpPlayerManager.GetPlayerByID(i);
if (cmpTemplateManager.GetCurrentTemplateName(entID) === neededTemplate) if (cmpTemplateManager.GetCurrentTemplateName(entID) === template)
continue; continue;
// We need to recreate this player to have the right template // We need to recreate this player to have the right template
entID = Engine.AddEntity(neededTemplate); entID = Engine.AddEntity(template);
cmpPlayerManager.ReplacePlayer(i, entID); cmpPlayerManager.ReplacePlayer(i, entID);
} }
@ -92,36 +80,42 @@ function LoadPlayerSettings(settings, newPlayers)
for (var i = 0; i < numPlayers; ++i) for (var i = 0; i < numPlayers; ++i)
{ {
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player); var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
var pDefs = playerDefaults ? playerDefaults[i] : {}; cmpPlayer.SetName(getSetting(playerData, playerDefaults, i, "Name"));
cmpPlayer.SetCiv(getSetting(playerData, playerDefaults, i, "Civ"));
// Skip gaia var colour = getSetting(playerData, playerDefaults, i, "Colour");
if (i > 0)
{
var pData = settings.PlayerData ? settings.PlayerData[i-1] : {};
cmpPlayer.SetName(getSetting(pData, pDefs, "Name"));
cmpPlayer.SetCiv(getSetting(pData, pDefs, "Civ"));
var colour = getSetting(pData, pDefs, "Colour");
cmpPlayer.SetColour(colour.r, colour.g, colour.b); cmpPlayer.SetColour(colour.r, colour.g, colour.b);
// Special case for gaia
if (i == 0)
{
// Gaia should be its own ally.
cmpPlayer.SetAlly(0);
// Gaia is everyone's enemy
for (var j = 1; j < numPlayers; ++j)
cmpPlayer.SetEnemy(j);
continue;
}
// Note: this is not yet implemented but I leave it commented to highlight it's easy // Note: this is not yet implemented but I leave it commented to highlight it's easy
// If anyone ever adds handicap. // If anyone ever adds handicap.
//if (getSetting(pData, pDefs, "GatherRateMultiplier") !== undefined) //if (getSetting(playerData, playerDefaults, i, "GatherRateMultiplier") !== undefined)
// cmpPlayer.SetGatherRateMultiplier(getSetting(pData, pDefs, "GatherRateMultiplier")); // cmpPlayer.SetGatherRateMultiplier(getSetting(playerData, playerDefaults, i, "GatherRateMultiplier"));
if (getSetting(pData, pDefs, "PopulationLimit") !== undefined) if (getSetting(playerData, playerDefaults, i, "PopulationLimit") !== undefined)
cmpPlayer.SetMaxPopulation(getSetting(pData, pDefs, "PopulationLimit")); cmpPlayer.SetMaxPopulation(getSetting(playerData, playerDefaults, i, "PopulationLimit"));
if (getSetting(pData, pDefs, "Resources") !== undefined) if (getSetting(playerData, playerDefaults, i, "Resources") !== undefined)
cmpPlayer.SetResourceCounts(getSetting(pData, pDefs, "Resources")); cmpPlayer.SetResourceCounts(getSetting(playerData, playerDefaults, i, "Resources"));
// If diplomacy explicitly defined, use that; otherwise use teams // If diplomacy explicitly defined, use that; otherwise use teams
if (getSetting(pData, pDefs, "Diplomacy") !== undefined) if (getSetting(playerData, playerDefaults, i, "Diplomacy") !== undefined)
cmpPlayer.SetDiplomacy(getSetting(pData, pDefs, "Diplomacy")); cmpPlayer.SetDiplomacy(getSetting(playerData, playerDefaults, i, "Diplomacy"));
else else
{ {
// Init diplomacy // Init diplomacy
var myTeam = getSetting(pData, pDefs, "Team"); var myTeam = getSetting(playerData, playerDefaults, i, "Team");
// Set all but self as enemies as SetTeam takes care of allies // Set all but self as enemies as SetTeam takes care of allies
for (var j = 0; j < numPlayers; ++j) for (var j = 0; j < numPlayers; ++j)
@ -135,7 +129,7 @@ function LoadPlayerSettings(settings, newPlayers)
} }
// If formations explicitly defined, use that; otherwise use civ defaults // If formations explicitly defined, use that; otherwise use civ defaults
var formations = getSetting(pData, pDefs, "Formations"); var formations = getSetting(playerData, playerDefaults, i, "Formations");
if (formations !== undefined) if (formations !== undefined)
cmpPlayer.SetFormations(formations); cmpPlayer.SetFormations(formations);
else else
@ -147,25 +141,10 @@ function LoadPlayerSettings(settings, newPlayers)
cmpPlayer.SetFormations(rawFormations.Formations); cmpPlayer.SetFormations(rawFormations.Formations);
} }
var startCam = getSetting(pData, pDefs, "StartingCamera"); var startCam = getSetting(playerData, playerDefaults, i, "StartingCamera");
if (startCam !== undefined) if (startCam !== undefined)
cmpPlayer.SetStartingCamera(startCam.Position, startCam.Rotation); cmpPlayer.SetStartingCamera(startCam.Position, startCam.Rotation);
} }
else
{
// Copy gaia data from defaults
cmpPlayer.SetName(pDefs.Name);
cmpPlayer.SetCiv(pDefs.Civ);
cmpPlayer.SetColour(pDefs.Colour.r, pDefs.Colour.g, pDefs.Colour.b);
// Gaia should be its own ally.
cmpPlayer.SetAlly(0);
// Gaia is everyone's enemy
for (var j = 1; j < numPlayers; ++j)
cmpPlayer.SetEnemy(j);
}
}
// NOTE: We need to do the team locking here, as otherwise // NOTE: We need to do the team locking here, as otherwise
// SetTeam can't ally the players. // SetTeam can't ally the players.
@ -178,14 +157,14 @@ function LoadPlayerSettings(settings, newPlayers)
} }
// Get a setting if it exists or return default // Get a setting if it exists or return default
function getSetting(settings, defaults, property) function getSetting(settings, defaults, idx, property)
{ {
if (settings && (property in settings)) if (settings && settings[idx] && (property in settings[idx]))
return settings[property]; return settings[idx][property];
// Use defaults // Use defaults
if (defaults && (property in defaults)) if (defaults && defaults[idx] && (property in defaults[idx]))
return defaults[property]; return defaults[idx][property];
return undefined; return undefined;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -206,6 +206,13 @@ static Status AddActorToTemplates(const VfsPath& pathname, const CFileInfo& UNUS
return INFO::OK; return INFO::OK;
} }
bool CTemplateLoader::TemplateExists(const std::string& templateName)
{
size_t pos = templateName.rfind('|');
std::string baseName(pos != std::string::npos ? templateName.substr(pos+1) : templateName);
return VfsFileExists(VfsPath(TEMPLATE_ROOT) / wstring_from_utf8(baseName + ".xml"));
}
std::vector<std::string> CTemplateLoader::FindPlaceableTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType, ScriptInterface& scriptInterface) std::vector<std::string> CTemplateLoader::FindPlaceableTemplates(const std::string& path, bool includeSubdirectories, ETemplatesType templatesType, ScriptInterface& scriptInterface)
{ {
JSContext* cx = scriptInterface.GetContext(); JSContext* cx = scriptInterface.GetContext();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -54,6 +54,11 @@ public:
*/ */
const CParamNode& GetTemplateFileData(const std::string& templateName); const CParamNode& GetTemplateFileData(const std::string& templateName);
/**
* Check if the template XML file exits, without trying to load it.
*/
bool TemplateExists(const std::string& templateName);
/** /**
* Returns a list of strings that could be validly passed as @c templateName to LoadTemplateFile. * Returns a list of strings that could be validly passed as @c templateName to LoadTemplateFile.
* (This includes "actor|foo" etc names). * (This includes "actor|foo" etc names).

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -124,6 +124,8 @@ public:
virtual const CParamNode* GetTemplateWithoutValidation(std::string templateName); virtual const CParamNode* GetTemplateWithoutValidation(std::string templateName);
virtual bool TemplateExists(std::string templateName);
virtual const CParamNode* LoadLatestTemplate(entity_id_t ent); virtual const CParamNode* LoadLatestTemplate(entity_id_t ent);
virtual std::string GetCurrentTemplateName(entity_id_t ent); virtual std::string GetCurrentTemplateName(entity_id_t ent);
@ -212,6 +214,11 @@ const CParamNode* CCmpTemplateManager::GetTemplateWithoutValidation(std::string
return &templateRoot; return &templateRoot;
} }
bool CCmpTemplateManager::TemplateExists(std::string templateName)
{
return m_templateLoader.TemplateExists(templateName);
}
const CParamNode* CCmpTemplateManager::LoadLatestTemplate(entity_id_t ent) const CParamNode* CCmpTemplateManager::LoadLatestTemplate(entity_id_t ent)
{ {
std::map<entity_id_t, std::string>::const_iterator it = m_LatestTemplates.find(ent); std::map<entity_id_t, std::string>::const_iterator it = m_LatestTemplates.find(ent);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -24,6 +24,7 @@
BEGIN_INTERFACE_WRAPPER(TemplateManager) BEGIN_INTERFACE_WRAPPER(TemplateManager)
DEFINE_INTERFACE_METHOD_1("GetTemplate", const CParamNode*, ICmpTemplateManager, GetTemplate, std::string) DEFINE_INTERFACE_METHOD_1("GetTemplate", const CParamNode*, ICmpTemplateManager, GetTemplate, std::string)
DEFINE_INTERFACE_METHOD_1("GetTemplateWithoutValidation", const CParamNode*, ICmpTemplateManager, GetTemplateWithoutValidation, std::string) DEFINE_INTERFACE_METHOD_1("GetTemplateWithoutValidation", const CParamNode*, ICmpTemplateManager, GetTemplateWithoutValidation, std::string)
DEFINE_INTERFACE_METHOD_1("TemplateExists", bool, ICmpTemplateManager, TemplateExists, std::string)
DEFINE_INTERFACE_METHOD_1("GetCurrentTemplateName", std::string, ICmpTemplateManager, GetCurrentTemplateName, entity_id_t) DEFINE_INTERFACE_METHOD_1("GetCurrentTemplateName", std::string, ICmpTemplateManager, GetCurrentTemplateName, entity_id_t)
DEFINE_INTERFACE_METHOD_1("FindAllTemplates", std::vector<std::string>, ICmpTemplateManager, FindAllTemplates, bool) DEFINE_INTERFACE_METHOD_1("FindAllTemplates", std::vector<std::string>, ICmpTemplateManager, FindAllTemplates, bool)
DEFINE_INTERFACE_METHOD_1("GetEntitiesUsingTemplate", std::vector<entity_id_t>, ICmpTemplateManager, GetEntitiesUsingTemplate, std::string) DEFINE_INTERFACE_METHOD_1("GetEntitiesUsingTemplate", std::vector<entity_id_t>, ICmpTemplateManager, GetEntitiesUsingTemplate, std::string)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -73,6 +73,11 @@ public:
*/ */
virtual const CParamNode* GetTemplateWithoutValidation(std::string templateName) = 0; virtual const CParamNode* GetTemplateWithoutValidation(std::string templateName) = 0;
/**
* Check if the template XML file exists, without trying to load it.
*/
virtual bool TemplateExists(std::string templateName) = 0;
/** /**
* Returns the template most recently specified for the entity 'ent'. * Returns the template most recently specified for the entity 'ent'.
* Used during deserialization. * Used during deserialization.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -668,7 +668,7 @@ void PlayerSettingsControl::ReadFromEngine()
m_NumPlayers = MAX_NUM_PLAYERS; m_NumPlayers = MAX_NUM_PLAYERS;
} }
else else
m_NumPlayers = player.count(); m_NumPlayers = player.count() - 1; // skip gaia
wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS && m_NumPlayers != 0); wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS && m_NumPlayers != 0);