mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-20 23:33:59 -07:00
Replace DataTemplateManager simulation component with a globalscript, refs #4868.
Removes the serialization of JSON files, shrinking savegame files and rejoin states sent across the network, refs #3834, #4239, #3909,f24523dc8f. Removes the AI C++ code to read JSON files frome33d4a52e9since the AI can now use the globalscript. Allows the AI to read Aura templates and removal of GUIInterface code to improve performance. Serialization of the JSON objects in other simulation components was removed in9c0e37f2c0/ D1109,a6f14f5631/ D1130. Serialization removal planned by sanderd17 AI part proofread by mimo Simulation part proofread by bb Discussed with Itms on irc Differential Revision: https://code.wildfiregames.com/D1108 This was SVN commit r20737.
This commit is contained in:
parent
1162eefdc2
commit
c90d72deb5
21 changed files with 144 additions and 310 deletions
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file This provides a cache for Aura and Technology templates.
|
||||
* They may not be serialized, otherwise rejoined clients would refer
|
||||
* to different objects, triggering an Out-of-sync error.
|
||||
*/
|
||||
function ModificationTemplates(path)
|
||||
{
|
||||
let suffix = ".json";
|
||||
|
||||
this.names = deepfreeze(listFiles(path, suffix, true));
|
||||
|
||||
this.templates = {};
|
||||
|
||||
for (let name of this.names)
|
||||
this.templates[name] = Engine.ReadJSONFile(path + name + suffix);
|
||||
|
||||
deepfreeze(this.templates);
|
||||
}
|
||||
|
||||
ModificationTemplates.prototype.GetNames = function()
|
||||
{
|
||||
return this.names;
|
||||
};
|
||||
|
||||
ModificationTemplates.prototype.Has = function(name)
|
||||
{
|
||||
return this.names.indexOf(name) != -1;
|
||||
};
|
||||
|
||||
ModificationTemplates.prototype.Get = function(name)
|
||||
{
|
||||
return this.templates[name];
|
||||
};
|
||||
|
||||
ModificationTemplates.prototype.GetAll = function()
|
||||
{
|
||||
return this.templates;
|
||||
};
|
||||
|
||||
|
||||
function LoadModificationTemplates()
|
||||
{
|
||||
global.AuraTemplates = new ModificationTemplates("simulation/data/auras/");
|
||||
global.TechnologyTemplates = new ModificationTemplates("simulation/data/technologies/");
|
||||
}
|
||||
|
|
@ -347,7 +347,7 @@ m.Template = m.Class({
|
|||
if (tech.indexOf("{civ}") == -1)
|
||||
continue;
|
||||
let civTech = tech.replace("{civ}", civ);
|
||||
techs[i] = gameState.techTemplates[civTech] ?
|
||||
techs[i] = TechnologyTemplates.Has(civTech) ?
|
||||
civTech : tech.replace("{civ}", "generic");
|
||||
}
|
||||
return techs;
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ m.GameState = function() {
|
|||
this.ai = null; // must be updated by the AIs.
|
||||
};
|
||||
|
||||
m.GameState.prototype.init = function(SharedScript, state, player) {
|
||||
m.GameState.prototype.init = function(SharedScript, state, player)
|
||||
{
|
||||
this.sharedScript = SharedScript;
|
||||
this.EntCollecNames = SharedScript._entityCollectionsName;
|
||||
this.timeElapsed = SharedScript.timeElapsed;
|
||||
this.circularMap = SharedScript.circularMap;
|
||||
this.templates = SharedScript._templates;
|
||||
this.techTemplates = SharedScript._techTemplates;
|
||||
this.entities = SharedScript.entities;
|
||||
this.player = player;
|
||||
this.playerData = SharedScript.playersData[this.player];
|
||||
|
|
@ -150,8 +150,8 @@ m.GameState.prototype.isCeasefireActive = function()
|
|||
|
||||
m.GameState.prototype.getTemplate = function(type)
|
||||
{
|
||||
if (this.techTemplates[type] !== undefined)
|
||||
return new m.Technology(this.techTemplates, type);
|
||||
if (TechnologyTemplates.Has(type))
|
||||
return new m.Technology(type);
|
||||
|
||||
if (this.templates[type] === undefined)
|
||||
this.sharedScript.GetTemplate(type);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ m.SharedScript = function(settings)
|
|||
|
||||
this._players = Object.keys(settings.players).map(key => settings.players[key]); // TODO SM55 Object.values(settings.players)
|
||||
this._templates = settings.templates;
|
||||
this._techTemplates = settings.techTemplates;
|
||||
|
||||
this._entityMetadata = {};
|
||||
for (let player of this._players)
|
||||
|
|
@ -30,7 +29,6 @@ m.SharedScript.prototype.Serialize = function()
|
|||
{
|
||||
return {
|
||||
"players": this._players,
|
||||
"techTemplates": this._techTemplates,
|
||||
"templatesModifications": this._templatesModifications,
|
||||
"entitiesModifications": this._entitiesModifications,
|
||||
"metadata": this._entityMetadata
|
||||
|
|
@ -44,7 +42,6 @@ m.SharedScript.prototype.Serialize = function()
|
|||
m.SharedScript.prototype.Deserialize = function(data)
|
||||
{
|
||||
this._players = data.players;
|
||||
this._techTemplates = data.techTemplates;
|
||||
this._templatesModifications = data.templatesModifications;
|
||||
this._entitiesModifications = data.entitiesModifications;
|
||||
this._entityMetadata = data.metadata;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
LoadModificationTemplates();
|
||||
|
||||
var API3 = function(m)
|
||||
{
|
||||
|
||||
/** Wrapper around a technology template */
|
||||
|
||||
m.Technology = function(allTemplates, templateName)
|
||||
m.Technology = function(templateName)
|
||||
{
|
||||
this._templateName = templateName;
|
||||
let template = allTemplates[templateName];
|
||||
let template = TechnologyTemplates.Get(templateName);
|
||||
|
||||
// check if this is one of two paired technologies.
|
||||
this._isPair = template.pair !== undefined;
|
||||
if (this._isPair)
|
||||
{
|
||||
if (allTemplates[template.pair].top == templateName)
|
||||
this._pairedWith = allTemplates[template.pair].bottom;
|
||||
else
|
||||
this._pairedWith = allTemplates[template.pair].top;
|
||||
let pairTech = TechnologyTemplates.Get(template.pair);
|
||||
this._pairedWith = pairTech.top == templateName ? pairTech.bottom : pairTech.top;
|
||||
}
|
||||
|
||||
// check if it only defines a pair:
|
||||
this._definesPair = template.top !== undefined;
|
||||
this._template = template;
|
||||
this._techTemplates = allTemplates;
|
||||
};
|
||||
|
||||
/** returns generic, or specific if civ provided. */
|
||||
|
|
@ -45,10 +45,10 @@ m.Technology.prototype.getPairedTechs = function()
|
|||
if (!this._definesPair)
|
||||
return undefined;
|
||||
|
||||
let techOne = new m.Technology(this._techTemplates, this._template.top);
|
||||
let techTwo = new m.Technology(this._techTemplates, this._template.bottom);
|
||||
|
||||
return [techOne,techTwo];
|
||||
return [
|
||||
new m.Technology(this._template.top),
|
||||
new m.Technology(this._template.bottom)
|
||||
];
|
||||
};
|
||||
|
||||
m.Technology.prototype.pair = function()
|
||||
|
|
|
|||
|
|
@ -8,14 +8,11 @@ Auras.prototype.Schema =
|
|||
|
||||
Auras.prototype.Init = function()
|
||||
{
|
||||
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
this.auras = {};
|
||||
this.affectedPlayers = {};
|
||||
|
||||
for (let name of this.GetAuraNames())
|
||||
{
|
||||
this.affectedPlayers[name] = [];
|
||||
this.auras[name] = cmpDataTemplateManager.GetAuraTemplate(name);
|
||||
}
|
||||
|
||||
// In case of autogarrisoning, this component can be called before ownership is set.
|
||||
// So it needs to be completely initialised from the start.
|
||||
this.Clean();
|
||||
|
|
@ -24,7 +21,7 @@ Auras.prototype.Init = function()
|
|||
// We can modify identifier if we want stackable auras in some case.
|
||||
Auras.prototype.GetModifierIdentifier = function(name)
|
||||
{
|
||||
if (this.auras[name].stackable)
|
||||
if (AuraTemplates.Get(name).stackable)
|
||||
return name + this.entity;
|
||||
return name;
|
||||
};
|
||||
|
|
@ -34,7 +31,7 @@ Auras.prototype.GetDescriptions = function()
|
|||
var ret = {};
|
||||
for (let auraID of this.GetAuraNames())
|
||||
{
|
||||
let aura = this.auras[auraID];
|
||||
let aura = AuraTemplates.Get(auraID);
|
||||
ret[auraID] = {
|
||||
"name": aura.auraName,
|
||||
"description": aura.auraDescription || null,
|
||||
|
|
@ -51,7 +48,7 @@ Auras.prototype.GetAuraNames = function()
|
|||
|
||||
Auras.prototype.GetOverlayIcon = function(name)
|
||||
{
|
||||
return this.auras[name].overlayIcon || "";
|
||||
return AuraTemplates.Get(name).overlayIcon || "";
|
||||
};
|
||||
|
||||
Auras.prototype.GetAffectedEntities = function(name)
|
||||
|
|
@ -62,18 +59,18 @@ Auras.prototype.GetAffectedEntities = function(name)
|
|||
Auras.prototype.GetRange = function(name)
|
||||
{
|
||||
if (this.IsRangeAura(name))
|
||||
return +this.auras[name].radius;
|
||||
return +AuraTemplates.Get(name).radius;
|
||||
return undefined;
|
||||
};
|
||||
|
||||
Auras.prototype.GetClasses = function(name)
|
||||
{
|
||||
return this.auras[name].affects;
|
||||
return AuraTemplates.Get(name).affects;
|
||||
};
|
||||
|
||||
Auras.prototype.GetModifications = function(name)
|
||||
{
|
||||
return this.auras[name].modifications;
|
||||
return AuraTemplates.Get(name).modifications;
|
||||
};
|
||||
|
||||
Auras.prototype.GetAffectedPlayers = function(name)
|
||||
|
|
@ -90,13 +87,15 @@ Auras.prototype.GetRangeOverlays = function()
|
|||
if (!this.IsRangeAura(name) || !this[name].isApplied)
|
||||
continue;
|
||||
|
||||
let rangeOverlay = AuraTemplates.Get(name).rangeOverlay;
|
||||
|
||||
rangeOverlays.push(
|
||||
this.auras[name].rangeOverlay ?
|
||||
rangeOverlay ?
|
||||
{
|
||||
"radius": this.GetRange(name),
|
||||
"texture": this.auras[name].rangeOverlay.lineTexture,
|
||||
"textureMask": this.auras[name].rangeOverlay.lineTextureMask,
|
||||
"thickness": this.auras[name].rangeOverlay.lineThickness
|
||||
"texture": rangeOverlay.lineTexture,
|
||||
"textureMask": rangeOverlay.lineTextureMask,
|
||||
"thickness": rangeOverlay.lineThickness
|
||||
} :
|
||||
// Specify default in order not to specify it in about 40 auras
|
||||
{
|
||||
|
|
@ -112,7 +111,7 @@ Auras.prototype.GetRangeOverlays = function()
|
|||
|
||||
Auras.prototype.CalculateAffectedPlayers = function(name)
|
||||
{
|
||||
var affectedPlayers = this.auras[name].affectedPlayers || ["Player"];
|
||||
var affectedPlayers = AuraTemplates.Get(name).affectedPlayers || ["Player"];
|
||||
this.affectedPlayers[name] = [];
|
||||
|
||||
var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
||||
|
|
@ -137,12 +136,14 @@ Auras.prototype.CalculateAffectedPlayers = function(name)
|
|||
|
||||
Auras.prototype.CanApply = function(name)
|
||||
{
|
||||
if (!this.auras[name].requiredTechnology)
|
||||
if (!AuraTemplates.Get(name).requiredTechnology)
|
||||
return true;
|
||||
|
||||
let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
|
||||
if (!cmpTechnologyManager)
|
||||
return false;
|
||||
return cmpTechnologyManager.IsTechnologyResearched(this.auras[name].requiredTechnology);
|
||||
|
||||
return cmpTechnologyManager.IsTechnologyResearched(AuraTemplates.Get(name).requiredTechnology);
|
||||
};
|
||||
|
||||
Auras.prototype.HasFormationAura = function()
|
||||
|
|
@ -162,7 +163,7 @@ Auras.prototype.HasGarrisonedUnitsAura = function()
|
|||
|
||||
Auras.prototype.GetType = function(name)
|
||||
{
|
||||
return this.auras[name].type;
|
||||
return AuraTemplates.Get(name).type;
|
||||
};
|
||||
|
||||
Auras.prototype.IsFormationAura = function(name)
|
||||
|
|
@ -470,7 +471,7 @@ Auras.prototype.OnGlobalResearchFinished = function(msg)
|
|||
return;
|
||||
for (let name of this.GetAuraNames())
|
||||
{
|
||||
let requiredTech = this.auras[name].requiredTechnology;
|
||||
let requiredTech = AuraTemplates.Get(name).requiredTechnology;
|
||||
if (requiredTech && requiredTech == msg.tech)
|
||||
{
|
||||
this.Clean();
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* System component which loads the technology and the aura data files
|
||||
*/
|
||||
function DataTemplateManager() {}
|
||||
|
||||
DataTemplateManager.prototype.Schema =
|
||||
"<a:component type='system'/><empty/>";
|
||||
|
||||
DataTemplateManager.prototype.Init = function()
|
||||
{
|
||||
this.technologiesPath = "simulation/data/technologies/";
|
||||
this.aurasPath = "simulation/data/auras/";
|
||||
|
||||
this.allTechs = {};
|
||||
this.allAuras = {};
|
||||
|
||||
for (let techName of this.ListAllTechs())
|
||||
this.GetTechnologyTemplate(techName);
|
||||
|
||||
for (let auraName of this.ListAllAuras())
|
||||
this.GetAuraTemplate(auraName);
|
||||
|
||||
deepfreeze(this.allTechs);
|
||||
deepfreeze(this.allAuras);
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.GetTechnologyTemplate = function(template)
|
||||
{
|
||||
if (!this.allTechs[template])
|
||||
{
|
||||
this.allTechs[template] = Engine.ReadJSONFile(this.technologiesPath + template + ".json");
|
||||
if (!this.allTechs[template])
|
||||
error("Failed to load technology \"" + template + "\"");
|
||||
}
|
||||
|
||||
return this.allTechs[template];
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.GetAuraTemplate = function(template)
|
||||
{
|
||||
if (!this.allAuras[template])
|
||||
{
|
||||
this.allAuras[template] = Engine.ReadJSONFile(this.aurasPath + template + ".json");
|
||||
if (!this.allAuras[template])
|
||||
error("Failed to load aura \"" + template + "\"");
|
||||
}
|
||||
|
||||
return this.allAuras[template];
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.ListAllTechs = function()
|
||||
{
|
||||
return listFiles(this.technologiesPath, ".json", true);
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.ListAllAuras = function()
|
||||
{
|
||||
return listFiles(this.aurasPath, ".json", true);
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.GetAllTechs = function()
|
||||
{
|
||||
return this.allTechs;
|
||||
};
|
||||
|
||||
DataTemplateManager.prototype.TechnologyExists = function(template)
|
||||
{
|
||||
return !!this.allTechs[template];
|
||||
};
|
||||
|
||||
Engine.RegisterSystemComponentType(IID_DataTemplateManager, "DataTemplateManager", DataTemplateManager);
|
||||
|
|
@ -643,26 +643,17 @@ GuiInterface.prototype.GetTemplateData = function(player, name)
|
|||
if (!template.Auras)
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
|
||||
|
||||
// Add aura name and description loaded from JSON file
|
||||
let auraNames = template.Auras._string.split(/\s+/);
|
||||
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
|
||||
for (let name of auraNames)
|
||||
aurasTemplate[name] = cmpDataTemplateManager.GetAuraTemplate(name);
|
||||
aurasTemplate[name] = AuraTemplates.Get(name);
|
||||
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetTechnologyData = function(player, data)
|
||||
{
|
||||
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
let template = cmpDataTemplateManager.GetTechnologyTemplate(data.name);
|
||||
|
||||
if (!template)
|
||||
{
|
||||
warn("Tried to get data for invalid technology: " + data.name);
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetTechnologyDataHelper(template, data.civ, Resources);
|
||||
return GetTechnologyDataHelper(TechnologyTemplates.Get(data.name), data.civ, Resources);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.IsTechnologyResearched = function(player, data)
|
||||
|
|
|
|||
|
|
@ -163,22 +163,20 @@ 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.TechnologyExists(civTech) ?
|
||||
civTech : tech.replace("{civ}", "generic");
|
||||
techs[i] = TechnologyTemplates.Has(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());
|
||||
return cmpTechnologyManager.CheckTechnologyRequirements(reqs, true);
|
||||
});
|
||||
techs = techs.filter(tech =>
|
||||
cmpTechnologyManager.CheckTechnologyRequirements(
|
||||
DeriveTechnologyRequirements(TechnologyTemplates.Get(tech), cmpPlayer.GetCiv()),
|
||||
true));
|
||||
|
||||
var techList = [];
|
||||
var superseded = {}; // Stores the tech which supersedes the key
|
||||
|
|
@ -192,7 +190,8 @@ ProductionQueue.prototype.GetTechnologiesList = function()
|
|||
var tech = techs[i];
|
||||
if (disabledTechnologies && disabledTechnologies[tech])
|
||||
continue;
|
||||
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
|
||||
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (!template.supersedes || techs.indexOf(template.supersedes) === -1)
|
||||
techList.push(tech);
|
||||
else
|
||||
|
|
@ -223,7 +222,7 @@ ProductionQueue.prototype.GetTechnologiesList = function()
|
|||
continue;
|
||||
}
|
||||
|
||||
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (template.top)
|
||||
ret[i] = {"pair": true, "top": template.top, "bottom": template.bottom};
|
||||
else
|
||||
|
|
@ -248,7 +247,7 @@ ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
|
|||
|
||||
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
|
||||
|
||||
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (template.top)
|
||||
{
|
||||
return (cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top)
|
||||
|
|
@ -346,10 +345,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
}
|
||||
else if (type == "technology")
|
||||
{
|
||||
// Load the technology template
|
||||
var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
var template = cmpDataTemplateManager.GetTechnologyTemplate(templateName);
|
||||
if (!template)
|
||||
if (!TechnologyTemplates.Has(templateName))
|
||||
return;
|
||||
|
||||
if (!this.GetTechnologiesList().some(tech =>
|
||||
|
|
@ -362,6 +358,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
return;
|
||||
}
|
||||
|
||||
let template = TechnologyTemplates.Get(templateName);
|
||||
let techCostMultiplier = this.GetTechCostMultiplier();
|
||||
let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetCheatTimeMultiplier();
|
||||
|
||||
|
|
@ -811,7 +808,7 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
|
|||
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
|
||||
cmpTechnologyManager.ResearchTechnology(item.technologyTemplate);
|
||||
|
||||
var template = cmpTechnologyManager.GetTechnologyTemplate(item.technologyTemplate);
|
||||
let template = TechnologyTemplates.Get(item.technologyTemplate);
|
||||
|
||||
if (template && template.soundComplete)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ TechnologyManager.prototype.Init = function()
|
|||
// Some technologies are automatically researched when their conditions are met. They have no cost and are
|
||||
// researched instantly. This allows civ bonuses and more complicated technologies.
|
||||
this.unresearchedAutoResearchTechs = new Set();
|
||||
var allTechs = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetAllTechs();
|
||||
for (var key in allTechs)
|
||||
let allTechs = TechnologyTemplates.GetAll();
|
||||
for (let key in allTechs)
|
||||
if (allTechs[key].autoResearch || allTechs[key].top)
|
||||
this.unresearchedAutoResearchTechs.add(key);
|
||||
};
|
||||
|
|
@ -61,10 +61,9 @@ TechnologyManager.prototype.OnUpdate = function()
|
|||
// This function checks if the requirements of any autoresearch techs are met and if they are it researches them
|
||||
TechnologyManager.prototype.UpdateAutoResearch = function()
|
||||
{
|
||||
var cmpDataTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
for (let key of this.unresearchedAutoResearchTechs)
|
||||
{
|
||||
var tech = cmpDataTempMan.GetTechnologyTemplate(key);
|
||||
let tech = TechnologyTemplates.Get(key);
|
||||
if ((tech.autoResearch && this.CanResearch(key))
|
||||
|| (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|
||||
{
|
||||
|
|
@ -75,11 +74,6 @@ TechnologyManager.prototype.UpdateAutoResearch = function()
|
|||
}
|
||||
};
|
||||
|
||||
TechnologyManager.prototype.GetTechnologyTemplate = function(tech)
|
||||
{
|
||||
return Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetTechnologyTemplate(tech);
|
||||
};
|
||||
|
||||
// Checks an entity template to see if its technology requirements have been met
|
||||
TechnologyManager.prototype.CanProduce = function (templateName)
|
||||
{
|
||||
|
|
@ -110,7 +104,7 @@ TechnologyManager.prototype.IsTechnologyStarted = function(tech)
|
|||
// Checks the requirements for a technology to see if it can be researched at the current time
|
||||
TechnologyManager.prototype.CanResearch = function(tech)
|
||||
{
|
||||
let template = this.GetTechnologyTemplate(tech);
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
|
||||
if (!template)
|
||||
{
|
||||
|
|
@ -270,17 +264,10 @@ TechnologyManager.prototype.ResearchTechnology = function(tech)
|
|||
{
|
||||
this.StoppedResearch(tech, false);
|
||||
|
||||
var template = this.GetTechnologyTemplate(tech);
|
||||
|
||||
if (!template)
|
||||
{
|
||||
error("Tried to research invalid technology: " + uneval(tech));
|
||||
return;
|
||||
}
|
||||
|
||||
var modifiedComponents = {};
|
||||
this.researchedTechs.add(tech);
|
||||
// store the modifications in an easy to access structure
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (template.modifications)
|
||||
{
|
||||
let derivedModifiers = DeriveModificationsFromTech(template);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,22 @@ Engine.LoadComponentScript("interfaces/TechnologyManager.js");
|
|||
Engine.LoadComponentScript("Auras.js");
|
||||
Engine.LoadComponentScript("AuraManager.js");
|
||||
|
||||
global.AuraTemplates = {
|
||||
"Get": name => {
|
||||
let template = {
|
||||
"type": name,
|
||||
"affectedPlayers": ["Ally"],
|
||||
"affects": ["CorrectClass"],
|
||||
"modifications": [{ "value": "Component/Value", "add": 10 }],
|
||||
"auraName": "name",
|
||||
"auraDescription": "description"
|
||||
};
|
||||
if (name == "range")
|
||||
template.radius = auraRange;
|
||||
return template;
|
||||
}
|
||||
};
|
||||
|
||||
let playerID = [0, 1, 2];
|
||||
let playerEnt = [10, 11, 12];
|
||||
let playerState = "active";
|
||||
|
|
@ -34,22 +50,6 @@ function testAuras(name, test_function)
|
|||
"GetEntitiesByPlayer": id => [30, 31, 32]
|
||||
});
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
|
||||
"GetAuraTemplate": (name) => {
|
||||
let template = {
|
||||
"type": name,
|
||||
"affectedPlayers": ["Ally"],
|
||||
"affects": ["CorrectClass"],
|
||||
"modifications": [{ "value": "Component/Value", "add": 10 }],
|
||||
"auraName": "name",
|
||||
"auraDescription": "description"
|
||||
};
|
||||
if (name == "range")
|
||||
template.radius = auraRange;
|
||||
return template;
|
||||
}
|
||||
});
|
||||
|
||||
AddMock(playerEnt[1], IID_Player, {
|
||||
"IsAlly": id => id == playerID[1] || id == playerID[2],
|
||||
"IsEnemy": id => id != playerID[1] || id != playerID[2],
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ Engine.LoadComponentScript("interfaces/TechnologyManager.js");
|
|||
Engine.LoadComponentScript("interfaces/ProductionQueue.js");
|
||||
Engine.LoadComponentScript("ProductionQueue.js");
|
||||
|
||||
global.TechnologyTemplates = {
|
||||
"Has": name => name == "phase_town_athen" || name == "phase_city_athen",
|
||||
"Get": () => ({})
|
||||
};
|
||||
|
||||
const productionQueueId = 6;
|
||||
const playerId = 1;
|
||||
const playerEntityID = 2;
|
||||
|
|
@ -32,10 +37,6 @@ AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
|
|||
"GetPlayerByID": id => playerEntityID
|
||||
});
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
|
||||
"TechnologyExists": name => name == "phase_town_athen" || name == "phase_city_athen"
|
||||
});
|
||||
|
||||
AddMock(playerEntityID, IID_Player, {
|
||||
"GetCiv": () => "iber",
|
||||
"GetDisabledTechnologies": () => ({}),
|
||||
|
|
@ -45,7 +46,6 @@ AddMock(playerEntityID, IID_Player, {
|
|||
|
||||
AddMock(playerEntityID, IID_TechnologyManager, {
|
||||
"CheckTechnologyRequirements": () => true,
|
||||
"GetTechnologyTemplate": tech => tech,
|
||||
"IsInProgress": () => false,
|
||||
"IsTechnologyResearched": () => false
|
||||
});
|
||||
|
|
@ -125,7 +125,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmpProductionQueue.GetTechnologiesList(), ["phase_town_a
|
|||
|
||||
AddMock(playerEntityID, IID_TechnologyManager, {
|
||||
"CheckTechnologyRequirements": () => true,
|
||||
"GetTechnologyTemplate": tech => tech,
|
||||
"IsInProgress": () => false,
|
||||
"IsTechnologyResearched": tech => tech == "phase_town_athen"
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
Engine.LoadComponentScript("interfaces/TechnologyManager.js");
|
||||
Engine.LoadComponentScript("TechnologyManager.js");
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
|
||||
"GetAllTechs": () => {}
|
||||
});
|
||||
global.TechnologyTemplates = {
|
||||
"GetAll": () => []
|
||||
};
|
||||
|
||||
let cmpTechnologyManager = ConstructComponent(SYSTEM_ENTITY, "TechnologyManager", {});
|
||||
|
||||
|
|
|
|||
|
|
@ -88,9 +88,7 @@ function Cheat(input)
|
|||
else
|
||||
return;
|
||||
|
||||
// check if specialised tech exists (like phase_town_athen)
|
||||
var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
if (cmpDataTemplateManager.ListAllTechs().indexOf(parameter + "_" + cmpPlayer.civ) > -1)
|
||||
if (TechnologyTemplates.Has(parameter + "_" + cmpPlayer.civ))
|
||||
parameter += "_" + cmpPlayer.civ;
|
||||
else
|
||||
parameter += "_generic";
|
||||
|
|
@ -140,13 +138,8 @@ function Cheat(input)
|
|||
}
|
||||
}
|
||||
|
||||
// check, if technology exists
|
||||
var template = cmpTechnologyManager.GetTechnologyTemplate(techname);
|
||||
if (!template)
|
||||
return;
|
||||
|
||||
// check, if technology is already researched
|
||||
if (!cmpTechnologyManager.IsTechnologyResearched(techname))
|
||||
if (TechnologyTemplates.Has(techname) &&
|
||||
!cmpTechnologyManager.IsTechnologyResearched(techname))
|
||||
cmpTechnologyManager.ResearchTechnology(techname);
|
||||
return;
|
||||
case "metaCheat":
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
// Loads the Aura and Technology JSON files
|
||||
LoadModificationTemplates();
|
||||
|
|
@ -97,7 +97,6 @@ bool CMapGeneratorWorker::Run()
|
|||
|
||||
// Replace RNG with a seeded deterministic function
|
||||
m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG);
|
||||
m_ScriptInterface->LoadGlobalScripts();
|
||||
|
||||
// Functions for RMS
|
||||
JSI_VFS::RegisterScriptFunctions_Maps(*m_ScriptInterface);
|
||||
|
|
@ -110,6 +109,9 @@ bool CMapGeneratorWorker::Run()
|
|||
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates");
|
||||
m_ScriptInterface->RegisterFunction<int, CMapGeneratorWorker::GetTerrainTileSize>("GetTerrainTileSize");
|
||||
|
||||
// Globalscripts may use VFS script functions
|
||||
m_ScriptInterface->LoadGlobalScripts();
|
||||
|
||||
// Parse settings
|
||||
JS::RootedValue settingsVal(cx);
|
||||
if (!m_ScriptInterface->ParseJSON(m_Settings, &settingsVal) && settingsVal.isUndefined())
|
||||
|
|
|
|||
|
|
@ -165,9 +165,6 @@ COMPONENT(SoundManager)
|
|||
INTERFACE(ValueModificationManager)
|
||||
COMPONENT(ValueModificationManagerScripted)
|
||||
|
||||
INTERFACE(DataTemplateManager)
|
||||
COMPONENT(DataTemplateManagerScripted)
|
||||
|
||||
INTERFACE(Terrain)
|
||||
COMPONENT(Terrain)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "simulation2/components/ICmpObstructionManager.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
#include "simulation2/components/ICmpTemplateManager.h"
|
||||
#include "simulation2/components/ICmpDataTemplateManager.h"
|
||||
#include "simulation2/components/ICmpTerritoryManager.h"
|
||||
#include "simulation2/helpers/LongPathfinder.h"
|
||||
#include "simulation2/serialization/DebugSerializer.h"
|
||||
|
|
@ -216,14 +215,12 @@ public:
|
|||
m_HasSharedComponent(false),
|
||||
m_SerializablePrototypes(new ObjectIdCache<std::wstring>(g_ScriptRuntime)),
|
||||
m_EntityTemplates(g_ScriptRuntime->m_rt),
|
||||
m_TechTemplates(g_ScriptRuntime->m_rt),
|
||||
m_SharedAIObj(g_ScriptRuntime->m_rt),
|
||||
m_PassabilityMapVal(g_ScriptRuntime->m_rt),
|
||||
m_TerritoryMapVal(g_ScriptRuntime->m_rt)
|
||||
{
|
||||
|
||||
m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG);
|
||||
m_ScriptInterface->LoadGlobalScripts();
|
||||
|
||||
m_ScriptInterface->SetCallbackData(static_cast<void*> (this));
|
||||
|
||||
|
|
@ -240,6 +237,9 @@ public:
|
|||
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CAIWorker::GetTemplate>("GetTemplate");
|
||||
|
||||
JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get()));
|
||||
|
||||
// Globalscripts may use VFS script functions
|
||||
m_ScriptInterface->LoadGlobalScripts();
|
||||
}
|
||||
|
||||
~CAIWorker()
|
||||
|
|
@ -400,7 +400,7 @@ public:
|
|||
m_RNG.seed(seed);
|
||||
}
|
||||
|
||||
bool TryLoadSharedComponent(bool hasTechs)
|
||||
bool TryLoadSharedComponent()
|
||||
{
|
||||
JSContext* cx = m_ScriptInterface->GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
|
@ -455,18 +455,6 @@ public:
|
|||
ENSURE(m_HasLoadedEntityTemplates);
|
||||
m_ScriptInterface->SetProperty(settings, "templates", m_EntityTemplates, false);
|
||||
|
||||
if (hasTechs)
|
||||
{
|
||||
m_ScriptInterface->SetProperty(settings, "techTemplates", m_TechTemplates, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// won't get the tech templates directly.
|
||||
JS::RootedValue fakeTech(cx);
|
||||
m_ScriptInterface->Eval("({})", &fakeTech);
|
||||
m_ScriptInterface->SetProperty(settings, "techTemplates", fakeTech, false);
|
||||
}
|
||||
|
||||
JS::AutoValueVector argv(cx);
|
||||
argv.append(settings);
|
||||
m_ScriptInterface->CallConstructor(ctor, argv, &m_SharedAIObj);
|
||||
|
|
@ -627,11 +615,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void RegisterTechTemplates(const shared_ptr<ScriptInterface::StructuredClone>& techTemplates)
|
||||
{
|
||||
m_ScriptInterface->ReadStructuredClone(techTemplates, &m_TechTemplates);
|
||||
}
|
||||
|
||||
void LoadEntityTemplates(const std::vector<std::pair<std::string, const CParamNode*> >& templates)
|
||||
{
|
||||
JSContext* cx = m_ScriptInterface->GetContext();
|
||||
|
|
@ -754,8 +737,7 @@ public:
|
|||
deserializer.Bool("useSharedScript", m_HasSharedComponent);
|
||||
if (m_HasSharedComponent)
|
||||
{
|
||||
TryLoadSharedComponent(false);
|
||||
|
||||
TryLoadSharedComponent();
|
||||
JS::RootedValue sharedData(cx);
|
||||
deserializer.ScriptVal("sharedData", &sharedData);
|
||||
if (!m_ScriptInterface->CallFunctionVoid(m_SharedAIObj, "Deserialize", sharedData))
|
||||
|
|
@ -922,7 +904,6 @@ private:
|
|||
|
||||
JS::PersistentRootedValue m_EntityTemplates;
|
||||
bool m_HasLoadedEntityTemplates;
|
||||
JS::PersistentRootedValue m_TechTemplates;
|
||||
|
||||
std::map<VfsPath, JS::Heap<JS::Value> > m_PlayerMetadata;
|
||||
std::vector<shared_ptr<CAIPlayer> > m_Players; // use shared_ptr just to avoid copying
|
||||
|
|
@ -1026,19 +1007,7 @@ public:
|
|||
|
||||
virtual void TryLoadSharedComponent()
|
||||
{
|
||||
const ScriptInterface& scriptInterface = GetSimContext().GetScriptInterface();
|
||||
JSContext* cx = scriptInterface.GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
// load the technology templates
|
||||
CmpPtr<ICmpDataTemplateManager> cmpDataTemplateManager(GetSystemEntity());
|
||||
ENSURE(cmpDataTemplateManager);
|
||||
|
||||
JS::RootedValue techTemplates(cx);
|
||||
cmpDataTemplateManager->GetAllTechs(&techTemplates);
|
||||
m_Worker.RegisterTechTemplates(scriptInterface.WriteStructuredClone(techTemplates));
|
||||
|
||||
m_Worker.TryLoadSharedComponent(true);
|
||||
m_Worker.TryLoadSharedComponent();
|
||||
}
|
||||
|
||||
virtual void RunGamestateInit()
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ICmpDataTemplateManager.h"
|
||||
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
#include "simulation2/scripting/ScriptComponent.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(DataTemplateManager)
|
||||
END_INTERFACE_WRAPPER(DataTemplateManager)
|
||||
|
||||
class CCmpDataTemplateManagerScripted : public ICmpDataTemplateManager
|
||||
{
|
||||
public:
|
||||
DEFAULT_SCRIPT_WRAPPER(DataTemplateManagerScripted)
|
||||
|
||||
virtual void GetAllTechs(JS::MutableHandleValue ret)
|
||||
{
|
||||
m_Script.CallRef("GetAllTechs", ret);
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_SCRIPT_WRAPPER(DataTemplateManagerScripted)
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* Copyright (C) 2012 Wildfire Games.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_ICMPDATATEMPLATEMANAGER
|
||||
#define INCLUDED_ICMPDATATEMPLATEMANAGER
|
||||
|
||||
#include "simulation2/system/Interface.h"
|
||||
|
||||
#include "maths/Fixed.h"
|
||||
|
||||
/**
|
||||
* Data template manager interface.
|
||||
* (This interface only includes the functions needed by native code for accessing
|
||||
* json template data, the associated logic is handled in scripts)
|
||||
*/
|
||||
class ICmpDataTemplateManager : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual void GetAllTechs(JS::MutableHandleValue ret) = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(DataTemplateManager)
|
||||
};
|
||||
|
||||
#endif // INCLUDED_ICMPDATATEMPLATEMANAGER
|
||||
|
|
@ -63,7 +63,6 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
|
|||
|
||||
m_ScriptInterface.SetCallbackData(static_cast<void*> (this));
|
||||
m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG);
|
||||
m_ScriptInterface.LoadGlobalScripts();
|
||||
|
||||
// For component script tests, the test system sets up its own scripted implementation of
|
||||
// these functions, so we skip registering them here in those cases
|
||||
|
|
@ -87,6 +86,9 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
|
|||
m_ScriptInterface.RegisterFunction<void, CComponentManager::Script_FlushDestroyedEntities> ("FlushDestroyedEntities");
|
||||
}
|
||||
|
||||
// Globalscripts may use VFS script functions
|
||||
m_ScriptInterface.LoadGlobalScripts();
|
||||
|
||||
// Define MT_*, IID_* as script globals, and store their names
|
||||
#define MESSAGE(name) m_ScriptInterface.SetGlobal("MT_" #name, (int)MT_##name);
|
||||
#define INTERFACE(name) \
|
||||
|
|
|
|||
Loading…
Reference in a new issue