Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/globalscripts/Technologies.js
/** | /** | ||||
* This file contains shared logic for applying tech modifications in GUI, AI, | * This file contains shared logic for applying tech modifications in GUI, AI, | ||||
* and simulation scripts. As such it must be fully deterministic and not store | * and simulation scripts. As such it must be fully deterministic and not store | ||||
* any global state, but each context should do its own caching as needed. | * any global state, but each context should do its own caching as needed. | ||||
* Also it cannot directly access the simulation and requires data passed to it. | * Also it cannot directly access the simulation and requires data passed to it. | ||||
*/ | */ | ||||
/** | /** | ||||
* Returns modified property value modified by the applicable tech | * Returns modified property value modified by the applicable tech | ||||
* modifications. | * modifications. | ||||
* | * | ||||
* @param currentTechModifications array of modificiations | * @param modifications array of modificiations | ||||
* @param classes Array containing the class list of the template. | * @param classes Array containing the class list of the template. | ||||
* @param originalValue Number storing the original value. Can also be | * @param originalValue Number storing the original value. Can also be | ||||
* non-numberic, but then only "replace" techs can be supported. | * non-numeric, but then only "replace" and "tokens" techs can be supported. | ||||
*/ | */ | ||||
function GetTechModifiedProperty(modifications, classes, originalValue) | function GetTechModifiedProperty(modifications, classes, originalValue) | ||||
{ | { | ||||
if (!modifications.length) | |||||
return originalValue; | |||||
let multiply = 1; | let multiply = 1; | ||||
let add = 0; | let add = 0; | ||||
for (let modification of modifications) | for (let modification of modifications) | ||||
{ | { | ||||
if (!DoesModificationApply(modification, classes)) | if (!DoesModificationApply(modification, classes)) | ||||
continue; | continue; | ||||
if (modification.replace !== undefined) | if (modification.replace !== undefined) | ||||
return modification.replace; | return modification.replace; | ||||
if (modification.tokens !== undefined) | |||||
return HandleTokens(originalValue, modification.tokens); | |||||
if (modification.multiply) | if (modification.multiply) | ||||
multiply *= modification.multiply; | multiply *= modification.multiply; | ||||
else if (modification.add) | else if (modification.add) | ||||
add += modification.add; | add += modification.add; | ||||
else | else | ||||
warn("GetTechModifiedProperty: modification format not recognised : " + uneval(modification)); | warn("GetTechModifiedProperty: modification format not recognised : " + uneval(modification)); | ||||
} | } | ||||
// Note, some components pass non-numeric values (for which only the "replace" modification makes sense) | |||||
if (typeof originalValue == "number") | |||||
return originalValue * multiply + add; | return originalValue * multiply + add; | ||||
return originalValue; | |||||
} | } | ||||
/** | /** | ||||
* Returns whether the given modification applies to the entity containing the given class list | * Returns whether the given modification applies to the entity containing the given class list | ||||
*/ | */ | ||||
function DoesModificationApply(modification, classes) | function DoesModificationApply(modification, classes) | ||||
{ | { | ||||
return MatchesClassList(classes, modification.affects); | return MatchesClassList(classes, modification.affects); | ||||
} | } | ||||
/** | /** | ||||
* Returns a modified list of tokens. | |||||
* Supports "A>B" to replace A by B, "-A" to remove A, and the rest will add tokens. | |||||
*/ | |||||
function HandleTokens(originalValue, modification) | |||||
{ | |||||
let tokens = originalValue === "" ? [] : originalValue.split(/\s+/); | |||||
let newTokens = modification === "" ? [] : modification.split(/\s+/); | |||||
for (let token of newTokens) | |||||
{ | |||||
if (token.indexOf(">") !== -1) | |||||
{ | |||||
let [oldToken, newToken] = token.split(">"); | |||||
let index = tokens.indexOf(oldToken); | |||||
if (index !== -1) | |||||
tokens[index] = newToken; | |||||
} | |||||
else if (token[0] == "-") | |||||
{ | |||||
let index = tokens.indexOf(token.substr(1)); | |||||
if (index !== -1) | |||||
tokens.splice(index, 1); | |||||
} | |||||
else | |||||
tokens.push(token); | |||||
} | |||||
return tokens.join(" "); | |||||
} | |||||
/** | |||||
* Derives the technology requirements from a given technology template. | * Derives the technology requirements from a given technology template. | ||||
* Takes into account the `supersedes` attribute. | * Takes into account the `supersedes` attribute. | ||||
* | * | ||||
* @param {object} template - The template object. Loading of the template must have already occured. | * @param {object} template - The template object. Loading of the template must have already occured. | ||||
* | * | ||||
* @return Derived technology requirements. See `InterpretTechRequirements` for object's syntax. | * @return Derived technology requirements. See `InterpretTechRequirements` for object's syntax. | ||||
*/ | */ | ||||
function DeriveTechnologyRequirements(template, civ) | function DeriveTechnologyRequirements(template, civ) | ||||
▲ Show 20 Lines • Show All 256 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator