Allow civ specific techs with {civ}
Discussed with leper Reviewed By: bb Trac Tickets: #4589 Differential Revision: https://code.wildfiregames.com/D1024 This was SVN commit r20551.
This commit is contained in:
parent
752005c4a4
commit
8de5c26540
@ -121,8 +121,16 @@ function getTemplateListsFromUnit(templateName)
|
||||
|
||||
if (template.ProductionQueue.Technologies)
|
||||
for (let research of template.ProductionQueue.Technologies._string.split(" "))
|
||||
{
|
||||
if (research.indexOf("{civ}") != -1)
|
||||
{
|
||||
let civResearch = research.replace("{civ}", g_SelectedCiv);
|
||||
research = techDataExists(civResearch) ?
|
||||
civResearch : research.replace("{civ}", "generic");
|
||||
}
|
||||
if (templateLists.techs.indexOf(research) === -1)
|
||||
templateLists.techs.push(research);
|
||||
}
|
||||
}
|
||||
|
||||
return templateLists;
|
||||
@ -157,8 +165,16 @@ function getTemplateListsFromStructure(templateName)
|
||||
|
||||
if (template.ProductionQueue.Technologies && template.ProductionQueue.Technologies._string)
|
||||
for (let research of template.ProductionQueue.Technologies._string.split(" "))
|
||||
{
|
||||
if (research.indexOf("{civ}") != -1)
|
||||
{
|
||||
let civResearch = research.replace("{civ}", g_SelectedCiv);
|
||||
research = techDataExists(civResearch) ?
|
||||
civResearch : research.replace("{civ}", "generic");
|
||||
}
|
||||
if (templateLists.techs.indexOf(research) === -1)
|
||||
templateLists.techs.push(research);
|
||||
}
|
||||
}
|
||||
|
||||
if (template.WallSet)
|
||||
|
@ -69,6 +69,11 @@ function loadTechData(templateName)
|
||||
return g_TechnologyData[templateName];
|
||||
}
|
||||
|
||||
function techDataExists(templateName)
|
||||
{
|
||||
return Engine.FileExists("simulation/data/technologies/" + templateName + ".json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads raw aura template.
|
||||
*
|
||||
@ -121,11 +126,19 @@ function loadUnit(templateName)
|
||||
{
|
||||
unit.production.techs = [];
|
||||
for (let research of template.ProductionQueue.Technologies._string.split(" "))
|
||||
{
|
||||
if (research.indexOf("{civ}") != -1)
|
||||
{
|
||||
let civResearch = research.replace("{civ}", g_SelectedCiv);
|
||||
research = techDataExists(civResearch) ?
|
||||
civResearch : research.replace("{civ}", "generic");
|
||||
}
|
||||
if (isPairTech(research))
|
||||
for (let tech of loadTechnologyPair(research).techs)
|
||||
unit.production.techs.push(tech);
|
||||
else
|
||||
unit.production.techs.push(research);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,11 +190,19 @@ function loadStructure(templateName)
|
||||
|
||||
if (template.ProductionQueue.Technologies && template.ProductionQueue.Technologies._string)
|
||||
for (let research of template.ProductionQueue.Technologies._string.split(" "))
|
||||
{
|
||||
if (research.indexOf("{civ}") != -1)
|
||||
{
|
||||
let civResearch = research.replace("{civ}", g_SelectedCiv);
|
||||
research = techDataExists(civResearch) ?
|
||||
civResearch : research.replace("{civ}", "generic");
|
||||
}
|
||||
if (isPairTech(research))
|
||||
for (let tech of loadTechnologyPair(research).techs)
|
||||
structure.production.technology.push(tech);
|
||||
else
|
||||
structure.production.technology.push(research);
|
||||
}
|
||||
}
|
||||
|
||||
if (structure.upgrades)
|
||||
|
@ -338,13 +338,21 @@ m.Template = m.Class({
|
||||
return templates.split(/\s+/);
|
||||
},
|
||||
|
||||
"researchableTechs": function(civ) {
|
||||
"researchableTechs": function(gameState, civ) {
|
||||
let templates = this.get("ProductionQueue/Technologies/_string");
|
||||
if (!templates)
|
||||
return undefined;
|
||||
if (civ)
|
||||
templates = templates.replace(/\{civ\}/g, civ);
|
||||
return templates.split(/\s+/);
|
||||
let techs = templates.split(/\s+/);
|
||||
for (let i = 0; i < techs.length; ++i)
|
||||
{
|
||||
let tech = techs[i];
|
||||
if (tech.indexOf("{civ}") == -1)
|
||||
continue;
|
||||
let civTech = tech.replace("{civ}", civ);
|
||||
techs[i] = gameState.techTemplates[civTech] ?
|
||||
civTech : tech.replace("{civ}", "generic");
|
||||
}
|
||||
return techs;
|
||||
},
|
||||
|
||||
"resourceSupplyType": function() {
|
||||
|
@ -109,9 +109,9 @@ m.Filters = {
|
||||
"dynamicProperties": ['trainingQueue']};
|
||||
},
|
||||
|
||||
"byResearchAvailable": function(civ){
|
||||
"byResearchAvailable": function(gameState, civ){
|
||||
return {"func" : function(ent){
|
||||
return ent.researchableTechs(civ) !== undefined;
|
||||
return ent.researchableTechs(gameState, civ) !== undefined;
|
||||
},
|
||||
"dynamicProperties": []};
|
||||
},
|
||||
|
@ -31,7 +31,7 @@ m.GameState.prototype.init = function(SharedScript, state, player) {
|
||||
if (!cctemplate)
|
||||
return;
|
||||
let civ = this.getPlayerCiv();
|
||||
let techs = cctemplate.researchableTechs(civ);
|
||||
let techs = cctemplate.researchableTechs(this, civ);
|
||||
for (let phase of this.phases)
|
||||
{
|
||||
phase.requirements = [];
|
||||
@ -586,7 +586,7 @@ m.GameState.prototype.getOwnTrainingFacilities = function()
|
||||
|
||||
m.GameState.prototype.getOwnResearchFacilities = function()
|
||||
{
|
||||
return this.updatingGlobalCollection("player-" + this.player + "-research-facilities", m.Filters.byResearchAvailable(this.playerData.civ), this.getOwnEntities());
|
||||
return this.updatingGlobalCollection("player-" + this.player + "-research-facilities", m.Filters.byResearchAvailable(this, this.playerData.civ), this.getOwnEntities());
|
||||
};
|
||||
|
||||
|
||||
@ -748,7 +748,7 @@ m.GameState.prototype.findAvailableTech = function()
|
||||
let civ = this.playerData.civ;
|
||||
for (let ent of this.getOwnEntities().values())
|
||||
{
|
||||
let searchable = ent.researchableTechs(civ);
|
||||
let searchable = ent.researchableTechs(this, civ);
|
||||
if (!searchable)
|
||||
continue;
|
||||
for (let tech of searchable)
|
||||
@ -831,7 +831,7 @@ m.GameState.prototype.hasResearchers = function(templateName, noRequirementCheck
|
||||
|
||||
for (let ent of this.getOwnResearchFacilities().values())
|
||||
{
|
||||
let techs = ent.researchableTechs(civ);
|
||||
let techs = ent.researchableTechs(this, civ);
|
||||
for (let tech of techs)
|
||||
{
|
||||
let temp = this.getTemplate(tech);
|
||||
@ -860,7 +860,7 @@ m.GameState.prototype.findResearchers = function(templateName, noRequirementChec
|
||||
let civ = this.playerData.civ;
|
||||
|
||||
return this.getOwnResearchFacilities().filter(function(ent) {
|
||||
let techs = ent.researchableTechs(civ);
|
||||
let techs = ent.researchableTechs(self, civ);
|
||||
for (let tech of techs)
|
||||
{
|
||||
let thisTemp = self.getTemplate(tech);
|
||||
|
@ -60,4 +60,9 @@ DataTemplateManager.prototype.GetAllTechs = function()
|
||||
return this.allTechs;
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.TechFileExists = function(template)
|
||||
{
|
||||
return Engine.DataFileExists("technologies/" + template + ".json");
|
||||
};
|
||||
|
||||
Engine.RegisterSystemComponentType(IID_DataTemplateManager, "DataTemplateManager", DataTemplateManager);
|
||||
|
@ -23,7 +23,7 @@ ProductionQueue.prototype.Schema =
|
||||
"</element>" +
|
||||
"</optional>" +
|
||||
"<optional>" +
|
||||
"<element name='Technologies' a:help='Space-separated list of technology names that this building can research.'>" +
|
||||
"<element name='Technologies' a:help='Space-separated list of technology names that this building can research. When present, the special string \"{civ}\" will be automatically replaced either by the civ code of the building's owner if such a tech exists, or by \"generic\".'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
@ -160,6 +160,18 @@ ProductionQueue.prototype.GetTechnologiesList = function()
|
||||
|
||||
var techs = string.split(/\s+/);
|
||||
|
||||
// Replace the civ specific technologies
|
||||
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
for (let i = 0; i < techs.length; ++i)
|
||||
{
|
||||
let tech = techs[i];
|
||||
if (tech.indexOf("{civ}") == -1)
|
||||
continue;
|
||||
let civTech = tech.replace("{civ}", cmpPlayer.GetCiv());
|
||||
techs[i] = cmpDataTemplateManager.TechFileExists(civTech) ?
|
||||
civTech : tech.replace("{civ}", "generic");
|
||||
}
|
||||
|
||||
// Remove any technologies that can't be researched by this civ
|
||||
techs = techs.filter(tech => {
|
||||
let reqs = DeriveTechnologyRequirements(cmpTechnologyManager.GetTechnologyTemplate(tech), cmpPlayer.GetCiv());
|
||||
|
@ -1,21 +1,5 @@
|
||||
{
|
||||
"genericName": "City Phase",
|
||||
"specificName": {
|
||||
"mace": "Megalópolis",
|
||||
"spart": "Megalópolis"
|
||||
},
|
||||
"description": "Advances from a bustling town to a veritable metropolis, full of the wonders of modern technology.",
|
||||
"cost": { "food": 0, "wood": 0, "stone": 750, "metal": 750 },
|
||||
"requirements": { "all": [{ "entity": { "class": "Town", "number": 4 } }, { "notciv": "athen" }] },
|
||||
"requirementsTooltip": "Requires 4 new Town Phase structures (except Walls and Civic Centers).",
|
||||
"supersedes": "phase_town",
|
||||
"icon": "city_phase.png",
|
||||
"researchTime": 60,
|
||||
"tooltip": "Advance to City Phase, which unlocks more structures and units. Territory radius for Civic Centers increased by another +50%. Citizen soldiers max health increased by +10%. All structures +9 garrisoned regeneration rate.",
|
||||
"modifications": [
|
||||
{ "value": "TerritoryInfluence/Radius", "multiply": 1.50, "affects": "CivCentre" },
|
||||
{ "value": "Health/Max", "multiply": 1.1, "affects": "CitizenSoldier" },
|
||||
{ "value": "Capturable/GarrisonRegenRate", "add": 9.0, "affects": "Structure" }
|
||||
],
|
||||
"soundComplete": "interface/alarm/alarm_phase.xml"
|
||||
"description": "Dummy technology for use in templates requirements, replaced by phase_city_generic or phase_city_{civ}.",
|
||||
"icon": "city_phase.png"
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
},
|
||||
"description": "Advances from a bustling town to a veritable metropolis, full of the wonders of modern technology. This is the Athenian city phase, where metal gathering rates are boosted because of the 'Silver Owls' bonus.",
|
||||
"cost": { "food": 0, "wood": 0, "stone": 750, "metal": 750 },
|
||||
"requirements": { "all": [{ "entity": { "class": "Town", "number": 4 } }, { "civ": "athen" }] },
|
||||
"requirements": { "entity": { "class": "Town", "number": 4 } },
|
||||
"requirementsTooltip": "Requires 4 new Town Phase structures (except Walls and Civic Centers).",
|
||||
"supersedes": "phase_town_athen",
|
||||
"replaces": ["phase_city"],
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"genericName": "City Phase",
|
||||
"specificName": {
|
||||
"mace": "Megalópolis",
|
||||
"spart": "Megalópolis"
|
||||
},
|
||||
"description": "Advances from a bustling town to a veritable metropolis, full of the wonders of modern technology.",
|
||||
"cost": { "food": 0, "wood": 0, "stone": 750, "metal": 750 },
|
||||
"requirements": { "entity": { "class": "Town", "number": 4 } },
|
||||
"requirementsTooltip": "Requires 4 new Town Phase structures (except Walls and Civic Centers).",
|
||||
"supersedes": "phase_town_generic",
|
||||
"replaces": ["phase_city"],
|
||||
"icon": "city_phase.png",
|
||||
"researchTime": 60,
|
||||
"tooltip": "Advance to City Phase, which unlocks more structures and units. Territory radius for Civic Centers increased by another +50%. Citizen soldiers max health increased by +10%. All structures +9 garrisoned regeneration rate.",
|
||||
"modifications": [
|
||||
{ "value": "TerritoryInfluence/Radius", "multiply": 1.50, "affects": "CivCentre" },
|
||||
{ "value": "Health/Max", "multiply": 1.1, "affects": "CitizenSoldier" },
|
||||
{ "value": "Capturable/GarrisonRegenRate", "add": 9.0, "affects": "Structure" }
|
||||
],
|
||||
"soundComplete": "interface/alarm/alarm_phase.xml"
|
||||
}
|
@ -1,21 +1,5 @@
|
||||
{
|
||||
"genericName": "Town Phase",
|
||||
"specificName": {
|
||||
"mace": "Kōmópolis",
|
||||
"spart": "Kōmópolis"
|
||||
},
|
||||
"description": "Advances from a small village to a bustling town, ready to expand rapidly.",
|
||||
"cost": { "food": 500, "wood": 500, "stone": 0, "metal": 0 },
|
||||
"requirements": { "all": [{ "entity": { "class": "Village", "number": 5 } }, { "notciv": "athen" }] },
|
||||
"requirementsTooltip": "Requires 5 Village Phase structures (except Palisades and Farm Fields).",
|
||||
"supersedes": "phase_village",
|
||||
"icon": "town_phase.png",
|
||||
"researchTime": 30,
|
||||
"tooltip": "Advance to Town Phase, which unlocks more structures and units. Territory radius for Civic Centers increased by +30%. Citizen soldiers max health increased by +20%. All structures +7 garrisoned regeneration rate.",
|
||||
"modifications": [
|
||||
{ "value": "TerritoryInfluence/Radius", "multiply": 1.30, "affects": "CivCentre" },
|
||||
{ "value": "Health/Max", "multiply": 1.2, "affects": "CitizenSoldier" },
|
||||
{ "value": "Capturable/GarrisonRegenRate", "add": 7.0, "affects": "Structure" }
|
||||
],
|
||||
"soundComplete": "interface/alarm/alarm_phase.xml"
|
||||
"description": "Dummy technology for use in templates requirements, replaced by phase_town_generic or phase_town_{civ}.",
|
||||
"icon": "town_phase.png"
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
},
|
||||
"description": "Advances from a small village to a bustling town, ready to expand rapidly. This is the Athenian town phase, where metal gathering rates are boosted because of the 'Silver Owls' bonus.",
|
||||
"cost": { "food": 500, "wood": 500, "stone": 0, "metal": 0 },
|
||||
"requirements": { "all": [{ "entity": { "class": "Village", "number": 5 } }, { "civ": "athen" }] },
|
||||
"requirements": { "entity": { "class": "Village", "number": 5 } },
|
||||
"requirementsTooltip": "Requires 5 Village Phase structures (except Palisades and Farm Fields).",
|
||||
"supersedes": "phase_village",
|
||||
"replaces": ["phase_town"],
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"genericName": "Town Phase",
|
||||
"specificName": {
|
||||
"mace": "Kōmópolis",
|
||||
"spart": "Kōmópolis"
|
||||
},
|
||||
"description": "Advances from a small village to a bustling town, ready to expand rapidly.",
|
||||
"cost": { "food": 500, "wood": 500, "stone": 0, "metal": 0 },
|
||||
"requirements": { "entity": { "class": "Village", "number": 5 } },
|
||||
"requirementsTooltip": "Requires 5 Village Phase structures (except Palisades and Farm Fields).",
|
||||
"supersedes": "phase_village",
|
||||
"replaces": ["phase_town"],
|
||||
"icon": "town_phase.png",
|
||||
"researchTime": 30,
|
||||
"tooltip": "Advance to Town Phase, which unlocks more structures and units. Territory radius for Civic Centers increased by +30%. Citizen soldiers max health increased by +20%. All structures +7 garrisoned regeneration rate.",
|
||||
"modifications": [
|
||||
{ "value": "TerritoryInfluence/Radius", "multiply": 1.30, "affects": "CivCentre" },
|
||||
{ "value": "Health/Max", "multiply": 1.2, "affects": "CitizenSoldier" },
|
||||
{ "value": "Capturable/GarrisonRegenRate", "add": 7.0, "affects": "Structure" }
|
||||
],
|
||||
"soundComplete": "interface/alarm/alarm_phase.xml"
|
||||
}
|
@ -35,8 +35,7 @@
|
||||
units/{civ}_ship_trireme
|
||||
</Entities>
|
||||
<Technologies datatype="tokens">
|
||||
-phase_town
|
||||
-phase_town_athen
|
||||
-phase_town_{civ}
|
||||
</Technologies>
|
||||
</ProductionQueue>
|
||||
<RallyPointRenderer>
|
||||
|
@ -94,10 +94,8 @@
|
||||
units/{civ}_support_female_citizen
|
||||
</Entities>
|
||||
<Technologies datatype="tokens">
|
||||
phase_town
|
||||
phase_town_athen
|
||||
phase_city
|
||||
phase_city_athen
|
||||
phase_town_{civ}
|
||||
phase_city_{civ}
|
||||
unlock_spies
|
||||
spy_counter
|
||||
</Technologies>
|
||||
|
@ -41,10 +41,8 @@
|
||||
</Obstruction>
|
||||
<ProductionQueue>
|
||||
<Technologies datatype="tokens">
|
||||
-phase_town
|
||||
-phase_town_athen
|
||||
-phase_city
|
||||
-phase_city_athen
|
||||
-phase_town_{civ}
|
||||
-phase_city_{civ}
|
||||
upgrade_rank_advanced_mercenary
|
||||
</Technologies>
|
||||
</ProductionQueue>
|
||||
|
@ -83,6 +83,7 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
|
||||
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_FlushDestroyedEntities> ("FlushDestroyedEntities");
|
||||
m_ScriptInterface.RegisterFunction<bool, std::wstring, CComponentManager::Script_DataFileExists> ("DataFileExists");
|
||||
m_ScriptInterface.RegisterFunction<JS::Value, std::wstring, CComponentManager::Script_ReadJSONFile> ("ReadJSONFile");
|
||||
m_ScriptInterface.RegisterFunction<JS::Value, std::wstring, CComponentManager::Script_ReadCivJSONFile> ("ReadCivJSONFile");
|
||||
m_ScriptInterface.RegisterFunction<std::vector<std::string>, std::wstring, bool, CComponentManager::Script_FindJSONFiles> ("FindJSONFiles");
|
||||
@ -1185,6 +1186,12 @@ std::string CComponentManager::GenerateSchema() const
|
||||
return schema;
|
||||
}
|
||||
|
||||
bool CComponentManager::Script_DataFileExists(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& fileName)
|
||||
{
|
||||
VfsPath path = VfsPath(L"simulation/data") / fileName;
|
||||
return VfsFileExists(path);
|
||||
}
|
||||
|
||||
JS::Value CComponentManager::Script_ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& fileName)
|
||||
{
|
||||
return ReadJSONFile(pCxPrivate, L"simulation/data", fileName);
|
||||
|
@ -332,6 +332,7 @@ private:
|
||||
static int Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName);
|
||||
static void Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent);
|
||||
static void Script_FlushDestroyedEntities(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
static bool Script_DataFileExists(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& fileName);
|
||||
static JS::Value Script_ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& fileName);
|
||||
static JS::Value Script_ReadCivJSONFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& fileName);
|
||||
static std::vector<std::string> Script_FindJSONFiles(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& subPath, bool recursive);
|
||||
|
Loading…
Reference in New Issue
Block a user