Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/helpers/Requirements.js
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
function RequirementsHelper() {} | |||||
RequirementsHelper.prototype.DEFAULT_RECURSION_DEPTH = 1; | |||||
Stan: Means it can't be overriden by mods? Refs @nani's ticket | |||||
RequirementsHelper.prototype.EntityRequirementsSchema = | |||||
"<element name='Entities' a:help='Entities that need to be controlled.'>" + | |||||
"<oneOrMore>" + | |||||
"<element a:help='Class of entity that needs to be controlled.'>" + | |||||
"<anyName/>" + | |||||
"<oneOrMore>" + | |||||
"<choice>" + | |||||
"<element name='Count' a:help='Number of entities required.'>" + | |||||
"<data type='nonNegativeInteger'/>" + | |||||
"</element>" + | |||||
"<element name='Variants' a:help='Number of different entities of this class required.'>" + | |||||
"<data type='nonNegativeInteger'/>" + | |||||
"</element>" + | |||||
"</choice>" + | |||||
"</oneOrMore>" + | |||||
"</element>" + | |||||
"</oneOrMore>" + | |||||
"</element>"; | |||||
RequirementsHelper.prototype.TechnologyRequirementsSchema = | |||||
"<element name='Techs' a:help='White-space separated list of technologies that need to be researched. ! negates a tech.'>" + | |||||
"<attribute name='datatype'>" + | |||||
Done Inline ActionsFor a future patch: Nothing prevents us from having classed techs. Such that one can define to research a specific tech, or a specific class of tech. (E.g. "Requires phase_town." versus "Requires two technologies of class military.", ideally with support for mixes "Requires two technologies with classes town+military." for military upgrades from the town phase.) Freagarach: For a future patch: Nothing prevents us from having classed techs. Such that one can define to… | |||||
"<value>tokens</value>" + | |||||
"</attribute>" + | |||||
"<text/>" + | |||||
"</element>"; | |||||
/** | |||||
* @param {number} recursionDepth - How deep we recurse. | |||||
* @return {string} - A RelaxRNG schema for requirements. | |||||
*/ | |||||
RequirementsHelper.prototype.RequirementsSchema = function(recursionDepth) | |||||
{ | |||||
return "" + | |||||
"<oneOrMore>" + | |||||
this.ChoicesSchema(--recursionDepth) + | |||||
"</oneOrMore>"; | |||||
}; | |||||
/** | |||||
* @param {number} recursionDepth - How deep we recurse. | |||||
* @return {string} - A RelaxRNG schema for chosing requirements. | |||||
*/ | |||||
RequirementsHelper.prototype.ChoicesSchema = function(recursionDepth) | |||||
{ | |||||
const allAnySchema = recursionDepth > 0 ? "" + | |||||
"<element name='All' a:help='Requires all of the conditions to be met.'>" + | |||||
this.RequirementsSchema(recursionDepth) + | |||||
"</element>" + | |||||
"<element name='Any' a:help='Requires at least one of the following conditions met.'>" + | |||||
this.RequirementsSchema(recursionDepth) + | |||||
"</element>" : ""; | |||||
return "" + | |||||
"<choice>" + | |||||
allAnySchema + | |||||
this.EntityRequirementsSchema + | |||||
this.TechnologyRequirementsSchema + | |||||
"</choice>"; | |||||
}; | |||||
/** | |||||
* @param {number} recursionDepth - How deeply recursive we build the schema. | |||||
* @return {string} - A RelaxRNG schema for requirements. | |||||
*/ | |||||
RequirementsHelper.prototype.BuildSchema = function(recursionDepth = this.DEFAULT_RECURSION_DEPTH) | |||||
{ | |||||
return "" + | |||||
"<element name='Requirements' a:help='The requirements that ought to be met before this entity can be produced.'>" + | |||||
"<optional>" + | |||||
this.ChoicesSchema(recursionDepth) + | |||||
"</optional>" + | |||||
"</element>"; | |||||
}; | |||||
/** | |||||
* @param {Object} template - The requirements template as defined above. | |||||
* @param {number} playerID - The player ID to check the requirements for. | |||||
* @return {boolean} - Whether the requirements are met. | |||||
*/ | |||||
RequirementsHelper.prototype.AreRequirementsMet = function(template, playerID) | |||||
{ | |||||
if (!template || !Object.keys(template).length) | |||||
return true; | |||||
const cmpTechManager = QueryPlayerIDInterface(playerID, IID_TechnologyManager); | |||||
if (template.All) | |||||
return this.AllRequirementsMet(template.All, cmpTechManager); | |||||
if (template.Any) | |||||
return this.AnyRequirementsMet(template.Any, cmpTechManager); | |||||
return true; | |||||
}; | |||||
Done Inline ActionsEnum? Stan: Enum? | |||||
Done Inline ActionsThat is difficult for it also needs to be in the schema then. And makes it not really readable. Freagarach: That is difficult for it also needs to be in the schema then. And makes it not really readable. | |||||
/** | |||||
* @param {Object} template - The requirements template for "all". | |||||
* @param {component} cmpTechManager - The technologyManager component to use when checking. | |||||
* @return {boolean} - Whether all given requirements are met. | |||||
*/ | |||||
RequirementsHelper.prototype.AllRequirementsMet = function(template, cmpTechManager) | |||||
{ | |||||
for (const requirementType in template) | |||||
{ | |||||
const requirement = template[requirementType]; | |||||
if (requirementType === "All" && !this.AllRequirementsMet(requirement, cmpTechManager)) | |||||
return false; | |||||
if (requirementType === "Any" && !this.AnyRequirementsMet(requirement, cmpTechManager)) | |||||
return false; | |||||
if (requirementType === "Entities") | |||||
{ | |||||
for (const className in requirement) | |||||
{ | |||||
const entReq = requirement[className]; | |||||
if ("Count" in entReq && (!(className in cmpTechManager.classCounts) || cmpTechManager.classCounts[className] < entReq.Count)) | |||||
return false; | |||||
if ("Variants" in entReq && (!(className in cmpTechManager.typeCountsByClass) || Object.keys(cmpTechManager.typeCountsByClass[className]).length < entReq.Variants)) | |||||
return false; | |||||
} | |||||
} | |||||
if (requirementType === "Techs") | |||||
{ | |||||
for (const tech of requirement.split(" ")) | |||||
{ | |||||
const negate = tech[0] === "!"; | |||||
if (negate && cmpTechManager.IsTechnologyResearched(tech.substring(1))) | |||||
return false; | |||||
if (!negate && !cmpTechManager.IsTechnologyResearched(tech)) | |||||
return false; | |||||
} | |||||
} | |||||
} | |||||
return true; | |||||
}; | |||||
/** | |||||
* @param {Object} template - The requirements template for "any". | |||||
* @param {component} cmpTechManager - The technologyManager component to use when checking. | |||||
* @return {boolean} - Whether any of the given requirements is met. | |||||
*/ | |||||
RequirementsHelper.prototype.AnyRequirementsMet = function(template, cmpTechManager) | |||||
{ | |||||
for (const requirementType in template) | |||||
{ | |||||
const requirement = template[requirementType]; | |||||
if (requirementType === "All" && this.AllRequirementsMet(requirement, cmpTechManager)) | |||||
return true; | |||||
if (requirementType === "Any" && this.AnyRequirementsMet(requirement, cmpTechManager)) | |||||
return true; | |||||
if (requirementType === "Entities") | |||||
{ | |||||
for (const className in requirement) | |||||
{ | |||||
const entReq = requirement[className]; | |||||
if ("Count" in entReq && className in cmpTechManager.classCounts && cmpTechManager.classCounts[className] >= entReq.Count) | |||||
return true; | |||||
if ("Variants" in entReq && className in cmpTechManager.typeCountsByClass && Object.keys(cmpTechManager.typeCountsByClass[className]).length >= entReq.Variants) | |||||
return true; | |||||
} | |||||
} | |||||
if (requirementType === "Techs") | |||||
{ | |||||
for (const tech of requirement.split(" ")) | |||||
{ | |||||
const negate = tech[0] === "!"; | |||||
if (negate && !cmpTechManager.IsTechnologyResearched(tech.substring(1))) | |||||
return true; | |||||
if (!negate && cmpTechManager.IsTechnologyResearched(tech)) | |||||
return true; | |||||
} | |||||
} | |||||
} | |||||
return false; | |||||
}; | |||||
Engine.RegisterGlobal("RequirementsHelper", new RequirementsHelper()); |
Wildfire Games · Phabricator
Means it can't be overriden by mods? Refs @nani's ticket