diff --git a/babele-register.js b/babele-register.js index 910b227..65a135a 100644 --- a/babele-register.js +++ b/babele-register.js @@ -1,6 +1,157 @@ +class ActorWfrp4e_fr extends ActorWfrp4e { + + /** + * Calculates a weapon's range or damage formula. + * + * Takes a weapon formula for Damage or Range (SB + 4 or SBx3) and converts to a numeric value. + * + * @param {String} formula formula to be processed (SBx3 => 9). + * + * @return {Number} Numeric formula evaluation + */ + calculateRangeOrDamage(formula) + { + //console.log("FR function calculateRangeOrDamage !", formula); + let actorData = this.data + try + { + formula = formula.toLowerCase(); + // Iterate through characteristics + for(let ch in actorData.data.characteristics) + { + // Determine if the formula includes the characteristic's abbreviation + B (SB, WPB, etc.) + if (formula.includes(ch.concat('b'))) + { + // Replace that abbreviation with the Bonus value + formula = formula.replace(ch.concat('b'), actorData.data.characteristics[ch].bonus.toString()); + } + } + if (formula.includes("yard") ) + formula = formula.replace(ch.concat('yard'), "mètre" ); + if (formula.includes("yds") ) + formula = formula.replace(ch.concat('yds'), "m." ); + // To evaluate multiplication, replace x with * + formula = formula.replace('x', '*'); + + return eval(formula); + } + catch + { + return formula + } + } + +/** + * Turns a formula into a processed string for display + * + * Processes damage formula based - same as calculateSpellAttributes, but with additional + * consideration to whether its a magic missile or not + * + * @param {String} formula Formula to process - "Willpower Bonus + 4" + * @param {boolean} isMagicMissile Whether or not it's a magic missile - used in calculating additional damage + * @returns {String} Processed formula + */ + calculateSpellDamage(formula, isMagicMissile) + { + let actorData = this.data + formula = formula.toLowerCase(); + + if (isMagicMissile) // If it's a magic missile, damage includes willpower bonus + { + formula += "+ " + actorData.data.characteristics["wp"].bonus + } + + // Specific case, to avoid wrong matching with "Force" + if (formula.includes("force mentale")) + { + // Determine if it's looking for the bonus or the value + if (formula.includes('bonus')) + formula = formula.replace( "bonus de force mentale", ); + else + formula = formula.replace("force mentale", actorData.data.characteristics["wp"].value); + } + + // Iterate through characteristics + for(let ch in actorData.data.characteristics) + { + // If formula includes characteristic name + while (formula.includes(actorData.data.characteristics[ch].label.toLowerCase())) + { + // Determine if it's looking for the bonus or the value + if (formula.includes('bonus')) + formula = formula.replace("bonus de " + WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].bonus); + else + formula = formula.replace(WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].value); + } + } + + //console.log("calculateSpellDamage -> " + formula ); + return eval(formula); + } + + /** + * Turns a formula into a processed string for display + * + * Turns a spell attribute such as "Willpower Bonus Rounds" into a more user friendly, processed value + * such as "4 Rounds". If the aoe is checked, it wraps the result in AoE (Result). + * + * @param {String} formula Formula to process - "Willpower Bonus Rounds" + * @param {boolean} aoe Whether or not it's calculating AoE (changes string return) + * @returns {String} formula processed formula + */ + calculateSpellAttributes(formula, aoe=false) + { + let actorData = this.data + formula = formula.toLowerCase(); + + // Do not process these special values + if (formula != game.i18n.localize("Vous").toLowerCase() && formula != game.i18n.localize("Special").toLowerCase() && formula != game.i18n.localize("Instantané").toLowerCase()) + { + // Specific case, to avoid wrong matching with "Force" + if (formula.includes("force mentale")) + { + // Determine if it's looking for the bonus or the value + if (formula.includes('bonus')) + formula = formula.replace( "bonus de force mentale", actorData.data.characteristics["wp"].bonus); + else + formula = formula.replace("force mentale", actorData.data.characteristics["wp"].value); + } + if (formula.includes("yard") ) + formula = formula.replace(ch.concat('yard'), "mètre" ); + if (formula.includes("yds") ) + formula = formula.replace(ch.concat('yds'), "m." ); + // Iterate through remaining characteristics + for(let ch in actorData.data.characteristics) + { + // If formula includes characteristic name + //console.log("Testing :", ch, WFRP4E.characteristics[ch].toLowerCase()); + if (formula.includes(WFRP4E.characteristics[ch].toLowerCase())) + { + // Determine if it's looking for the bonus or the value + if (formula.includes('bonus')) + formula = formula.replace("bonus de " + WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].bonus); + else + formula = formula.replace(WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].value); + } + } + } + + // If AoE - wrap with AoE ( ) + if (aoe) + formula = "AoE (" + formula.capitalize() + ")"; + + //console.log("calculateSpellAttributes -> " + formula ); + return formula.capitalize(); + } + +} + Hooks.once('init', () => { + // Replace to manage specific bonuses/char. computations + CONFIG.Actor.entityClass = ActorWfrp4e_fr; + if(typeof Babele !== 'undefined') { Babele.get().register({ @@ -138,3 +289,4 @@ Hooks.once('init', () => { } } ); + diff --git a/module.json b/module.json index e1178eb..3b4a572 100644 --- a/module.json +++ b/module.json @@ -2,11 +2,11 @@ "name": "WH4-fr-translation", "title": "Traduction du module WH4 en Français.", "description": "La traduction du module WH4.", - "version": "0.43", + "version": "0.44", "minimumCoreVersion" : "0.5.1", "author": "LeRatierBretonnien", "esmodules": ["babele-register.js"], - "scripts": [], + "scripts": [ "scripts/actor-wfrp4e-fr.js"], "styles": [], "packs": [], diff --git a/scripts/actor-wfrp4e-fr.js b/scripts/actor-wfrp4e-fr.js new file mode 100644 index 0000000..e69de29 diff --git a/tables/astral.json b/tables/astral.json new file mode 100644 index 0000000..70b8af5 --- /dev/null +++ b/tables/astral.json @@ -0,0 +1,108 @@ +{ + "die": "1d100", + "name": "Signe astral", + "rows": [ + { + "name": "Wymund l'Anachorète", + "description": "Signe de l'Endurance", + "range": [1,5] + }, + { + "name": "La Grande Croix", + "description": "Signe de Clairvoyance", + "range": [6,10] + }, + { + "name": "Le Trait du Peintre", + "description": "Signe de Précision et de Perfection", + "range": [11,15] + }, + { + "name": "Gnuthus le Buffle", + "description": "Signe du Dévouement et de la Loyauté", + "range": [16,25] + }, + { + "name": "Dragomas le Dragon", + "description": "Signe de Bravoure", + "range": [26,30] + }, + { + "name": " Le Crépuscule", + "description": "Signe d’Illusion et de Mystère", + "range": [31,35] + }, + { + "name": "Le Fourreau de Grungni", + "description": "Signe des Armes et de la Guerre", + "range": [36,40] + }, + { + "name": "Mammit le Sage", + "description": "Signe de Sagesse", + "range": [41,45] + }, + { + "name": "Mummit le Fou", + "description": "Signe d'Intuition", + "range": [46,50] + }, + { + "name": "Les Deux Boeufs", + "description": "Signe de la Terre et de la Belle Ouvrage", + "range": [51,55] + }, + { + "name": "Le Danseur", + "description": "Signe de Séduction et d’Amour", + "range": [56,60] + }, + { + "name": "Le Tambour", + "description": "Signe du Plaisir et des Excès", + "range": [61,65] + }, + { + "name": "Le Flûtiste", + "description": "Signe du Roublard", + "range": [66,70] + }, + { + "name": "Vobist le Pâle", + "description": "Signe de Doute et d'Incertitude", + "range": [71,75] + }, + { + "name": "La Charrette Brisée", + "description": "Signe de Talent et d'Apprentissage", + "range": [76,80] + }, + { + "name": "La Chèvre Sauvage", + "description": "Signe de Passions Interdites", + "range": [81,85] + }, + { + "name": "Le Chaudron de Rhya", + "description": "Signe de Miséricorde, Mort et Création", + "range": [86,90] + }, + { + "name": "Cackelfax le Coq", + "description": "Signe de Richesse et de Négoce", + "range": [91,95] + }, + { + "name": "Le Grimoire", + "description": "Signe de Compétence et d'Étude", + "range": [96,98] + }, + { + "name": "L'Étoile du Sorcier", + "description": "Signe de Magie", + "range": [96,98] + } + ] +} + +