Changeset View
Standalone View
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 Object with mapping of property names to | * @param currentTechModifications Object with mapping of property names to | ||||
* modification arrays, retrieved from the intended player's TechnologyManager. | * modification arrays, retrieved from the intended player's TechnologyManager. | ||||
* @param classes Array contianing the class list of the template. | * @param classes Array contianing the class list of the template. | ||||
* @param propertyName String encoding the name of the value. | * @param propertyName String encoding the name of the value. | ||||
* @param propertyValue Number storing the original value. Can also be | * @param propertyValue Variable storing the original value. | ||||
* non-numberic, but then only "replace" techs can be supported. | * This can be a numerical value, or a non-numerical value. | ||||
* If it is non-numerical, only "replace" and "tokens" are supported. | |||||
Freagarach: (`numeric`) | |||||
Not Done Inline Actions^ Freagarach: ^ | |||||
*/ | */ | ||||
function GetTechModifiedProperty(currentTechModifications, classes, propertyName, propertyValue) | function GetTechModifiedProperty(currentTechModifications, classes, propertyName, propertyValue) | ||||
{ | { | ||||
let modifications = currentTechModifications[propertyName] || []; | let modifications = currentTechModifications[propertyName] || []; | ||||
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(propertyValue, modification.tokens); | |||||
if (modification.multiply) | if (modification.multiply) | ||||
Not Done Inline ActionsDo these returns mean that if one has multiple modifications which replace/handle tokens, only the first one is applied? Freagarach: Do these returns mean that if one has multiple modifications which replace/handle tokens, only… | |||||
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 (modifying " + propertyName + "): " + uneval(modification)); | warn("GetTechModifiedProperty: modification format not recognised (modifying " + propertyName + "): " + uneval(modification)); | ||||
} | } | ||||
// Note, some components pass non-numeric values (for which only the "replace" modification makes sense) | // Note, some components pass non-numeric values (for which only the "replace" modification makes sense) | ||||
Done Inline Actions(Not true anymore.) Freagarach: (Not true anymore.) | |||||
if (typeof propertyValue == "number") | if (typeof propertyValue == "number") | ||||
return propertyValue * multiply + add; | return propertyValue * multiply + add; | ||||
return propertyValue; | return propertyValue; | ||||
} | } | ||||
/** | /** | ||||
* 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. | |||||
Not Done Inline ActionsCould it be like: Freagarach: Could it be like:
`"A>B" to replace A by B, "-A" to remove A, "+A" to add A and rest will… | |||||
Done Inline ActionsModifiers already support replace to replace all, which I think is sufficient, so I do't see much the point. I guess it could still be A>B -A and +A though. wraitii: Modifiers already support `replace` to replace all, which I think is sufficient, so I do't see… | |||||
Done Inline ActionsAh yes of course. Freagarach: Ah yes of course. | |||||
*/ | |||||
function HandleTokens(propertyValue, modification) | |||||
{ | |||||
let tokens = propertyValue.split(/\s+/); | |||||
Not Done Inline ActionsDo we get tabs here? I know we don't for datatype tokens as it is handled by cpp but I don't know there Stan: Do we get tabs here? I know we don't for datatype tokens as it is handled by cpp but I don't… | |||||
Done Inline ActionsThere is a bunch of other code using /\s+/ and some using ' '. I'm leaving this as is, for consistency one should do an actual check someday. wraitii: There is a bunch of other code using /\s+/ and some using ' '. I'm leaving this as is, for… | |||||
let newTokens = modification.split(/\s+/); | |||||
for (let token of newTokens) | |||||
{ | |||||
if (token.search(">") !== -1) | |||||
Not Done Inline ActionsIndexOf ? No regexp here https://stackoverflow.com/questions/354110/what-is-the-difference-between-indexof-and-search Stan: IndexOf ? No regexp here https://stackoverflow.com/questions/354110/what-is-the-difference… | |||||
Done Inline Actionsyup. wraitii: yup. | |||||
{ | |||||
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 225 Lines • Show Last 20 Lines |
(numeric)