foundryvtt-wh4-lang-fr-fr/babele-register.js

570 lines
22 KiB
JavaScript
Raw Normal View History

/************************************************************************************/
/* Override some methods of the WFRP4 actor class, mainly to compute spells/weapons */
2020-04-12 08:59:47 +02:00
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") )
2020-04-20 10:16:26 +02:00
formula = formula.replace('yard', "mètre" );
2020-04-12 08:59:47 +02:00
if (formula.includes("yds") )
2020-04-20 10:16:26 +02:00
formula = formula.replace('yds', "m." );
2020-04-12 08:59:47 +02:00
// 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
2020-06-05 09:15:43 +02:00
if (formula.includes('bonus')) {
formula = formula.replace( "bonus de force mentale", actorData.data.characteristics["wp"].bonus);
formula = formula.replace( "force mentale bonus", actorData.data.characteristics["wp"].bonus);
} else
2020-04-12 08:59:47 +02:00
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
2020-06-05 09:15:43 +02:00
if (formula.includes('bonus')) {
2020-04-12 08:59:47 +02:00
formula = formula.replace("bonus de " + WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].bonus);
2020-06-05 09:15:43 +02:00
formula = formula.replace(WFRP4E.characteristics[ch].toLowerCase() + " bonus", actorData.data.characteristics[ch].bonus);
}
2020-04-12 08:59:47 +02:00
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
2020-06-05 09:15:43 +02:00
if (formula.includes('bonus')) {
2020-04-12 08:59:47 +02:00
formula = formula.replace( "bonus de force mentale", actorData.data.characteristics["wp"].bonus);
2020-06-05 09:15:43 +02:00
formula = formula.replace( "force mentale bonus", actorData.data.characteristics["wp"].bonus);
}
2020-04-12 08:59:47 +02:00
else
formula = formula.replace("force mentale", actorData.data.characteristics["wp"].value);
}
if (formula.includes("yard") )
2020-04-20 10:16:26 +02:00
formula = formula.replace('yard', "mètre" );
2020-04-12 08:59:47 +02:00
if (formula.includes("yds") )
2020-04-20 10:16:26 +02:00
formula = formula.replace('yds', "m." );
2020-04-12 08:59:47 +02:00
// 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
2020-06-05 09:15:43 +02:00
if (formula.includes('bonus')) {
2020-04-12 08:59:47 +02:00
formula = formula.replace("bonus de " + WFRP4E.characteristics[ch].toLowerCase(), actorData.data.characteristics[ch].bonus);
2020-06-05 09:15:43 +02:00
formula = formula.replace(WFRP4E.characteristics[ch].toLowerCase() + " bonus", actorData.data.characteristics[ch].bonus);
}
2020-04-12 08:59:47 +02:00
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();
}
}
/************************************************************************************/
2020-03-25 20:37:09 +01:00
Hooks.once('init', () => {
2020-04-12 08:59:47 +02:00
// Replace to manage specific bonuses/char. computations
CONFIG.Actor.entityClass = ActorWfrp4e_fr;
WFRP4E.talentBonuses = {
"perspicace": "int",
"affable": "fel",
"tireur de précision": "bs",
"très fort": "s",
"vivacité": "i",
"reflexes foudroyants": "ag",
"imperturbable": "wp",
"très résistant": "t",
"doigts de fée": "dex",
"guerrier né": "ws"
}
WFRP4E.speciesSkills = {
"human": [
"Soins aux animaux",
"Charme",
"Calme",
"Evaluation",
"Ragot",
"Marchandage",
"Langue (Bretonnien)",
"Langue (Wastelander)",
"Commandement",
"Savoir (Reikland)",
"Corps à corps (Base)",
"Projectiles (Arc)"
],
"dwarf": [
"Résistance à l'alcool",
"Calme",
"Endurance",
"Divertissement (Raconter)",
"Evaluation",
"Intimidation",
"Langue (Khazalid)",
"Savoir (Nains)",
"Savoir (Geologie)",
"Savoir (Metallurgie)",
"Corps à corps (Base)",
"Métier (Au choix)"
],
"halfling": [
"Charme",
"Résistance à l'alcool",
"Esquive",
"Pari",
"Marchandage",
"Intuition",
"Langue (Mootland)",
"Savoir (Reikland)",
"Perception",
"Escamotage",
"Discrétion (Au choix)",
"Métier (Cuisinier)"
],
"helf": [
"Calme",
"Divertissement (Chant)",
"Evaluation",
"Langue (Eltharin)",
"Commandement",
"Corps à corps (Base)",
"Navigation",
"Perception",
"Musicien (Au choix)",
"Projectiles (Arc)",
"Voile",
"Natation"
],
"welf": [
"Athlétisme",
"Escalade",
"Endurance",
"Divertissement (Chant)",
"Intimidation",
"Langue (Eltharin)",
"Corps à corps (Base)",
"Survie en extérieur",
"Perception",
"Projectiles (Arc)",
"Discrétion (Rural)",
"Pistage"
],
}
WFRP4E.speciesTalents = {
"human": [
"Destinée",
"Affable, Perspicace",
3
],
"dwarf": [
"Résistance à la Magie",
"Vision Nocturne",
"Lire/Ecrire, Impitoyable",
"Déterminé, Obstiné",
"Costaud",
0
],
"halfling": [
"Sens Aiguisé (Gout)",
"Vision Nocturne",
"Résistance (Chaos)",
"Petit",
0
],
"helf": [
"Sens Aiguisé (Vue)",
"Imperturbable, Perspicace",
"Vision Nocturne",
"Seconde Vue, Sixième Sens",
"Lire/Ecrire",
0
],
"welf": [
"Sens Aiguisé (Sight)",
"Dur à cuire, Seconde Vue",
"Vision Nocturne",
"Seconde Vue, Sixth Sense",
"Lire/Ecrire",
0
],
}
WFRP4E.species = {
"human": "Humain",
"dwarf": "Nain",
"halfling": "Halfling",
"helf": "Haut Elfe",
"welf": "Elfe Sylvain"
}
2020-03-25 20:37:09 +01:00
if(typeof Babele !== 'undefined') {
Babele.get().register({
module: 'WH4-fr-translation',
lang: 'fr',
dir: 'compendium'
});
Babele.get().registerConverters({
2020-03-31 09:03:19 +02:00
"career_skills": (skills_list) => {
var compendium = game.packs.find(p => p.collection === 'wfrp4e.skills');
//console.log( "Thru here ...", compendium, skills_list);
2020-05-05 09:21:03 +02:00
if ( skills_list ) {
var i;
var len = skills_list.length;
var re = /(.*)\((.*)\)/i;
for (i = 0; i < len; i++) {
var transl = compendium.i18nName( { name: skills_list[i] } );
//console.log("List ...", skills_list[i]);
if ( transl == skills_list[i] ) {
var res = re.exec( skills_list[i]);
if (res) {
//console.log("Matched/split:", res[1], res[2]);
var subword = game.i18n.localize(res[2].trim() );
var s1 = res[1].trim() + " ()";
var translw = compendium.i18nName( { name: s1} );
if (translw != s1) {
var res2 = re.exec(translw);
transl = res2[1] + "(" + subword + ")";
} else {
s1 = res[1].trim() + " ( )";
translw = compendium.i18nName( { name: s1} );
var res2 = re.exec(translw);
transl = res2[1] + "(" + subword + ")";
}
}
}
2020-05-05 09:21:03 +02:00
skills_list[i] = transl;
}
}
return skills_list;
},
"career_talents": (talents_list) => {
var compendium = game.packs.find(p => p.collection === 'wfrp4e.talents');
var i;
2020-05-05 09:21:03 +02:00
if ( talents_list ) {
var len = talents_list.length;
var re = /(.*)\((.*)\)/i;
for (i = 0; i < len; i++) {
var transl = compendium.i18nName( { name: talents_list[i]} );
if ( transl == talents_list[i] ) {
var res = re.exec( talents_list[i]);
if (res) {
//console.log("Matched/split:", res[1], res[2]);
var subword = game.i18n.localize(res[2].trim() );
var s1 = res[1].trim(); // No () in talents table
var translw = compendium.i18nName( { name: s1 } );
if (translw != s1) {
transl = translw + "(" + subword + ")";
} else {
s1 = res[1].trim() + " ( )";
translw = compendium.i18nName( { name: s1 } );
var res2 = re.exec(translw);
transl = res2[1] + "(" + subword + ")";
}
}
}
2020-05-05 09:21:03 +02:00
talents_list[i] = transl;
}
}
return talents_list;
2020-03-31 09:27:04 +02:00
},
"npc_characteristics": (chars) => { // Auto-convert char names in the sheet
for (var key in chars) {
var char = chars[key];
//console.log("Was here !", key, char );
var abrev = char["abrev"];
2020-06-06 13:27:59 +02:00
let toTransl = "CHAR." + abrev;
if ( game.i18n.localize( toTransl ) != toTransl) { // Manages unknown language
char["label"] = game.i18n.localize( "CHAR." + abrev );
char["abrev"] = game.i18n.localize( "CHARAbbrev." + abrev );
}
}
return chars;
},
2020-04-22 20:22:34 +02:00
"bestiary_traits": (beast_traits, translations) => {
var fulltraits = game.packs.get('wfrp4e.traits');
var fullskills = game.packs.get('wfrp4e.skills');
var fulltalents = game.packs.get('wfrp4e.talents');
var fullcareers = game.packs.get('wfrp4e.careers');
var fulltrappings = game.packs.get('wfrp4e.trappings');
var fullspells = game.packs.get('wfrp4e.spells');
var fullprayers = game.packs.get('wfrp4e.prayers');
var eisitems = game.packs.get('eis.eisitems');
var eisspells = game.packs.get('eis.eisspells');
2020-04-22 20:22:34 +02:00
for (let trait_en of beast_traits)
{
var special = "";
var nbt = "";
2020-04-22 20:22:34 +02:00
var name_en = trait_en.name.trim(); // strip \r in some traits name
if ( trait_en.type == "trait") {
if ( name_en.includes("Tentacles") ) { // Process specific Tentacles case
var re = /(.d*)x Tentacles/i;
2020-04-22 20:22:34 +02:00
var res = re.exec( name_en );
if ( res && res[1] )
nbt = res[1] + "x ";
name_en = "Tentacles";
} else if ( name_en.includes("(") && name_en.includes(")") ) { // Then process specific traits name with (xxxx) inside
var re = /(.*) \((.*)\)/i;
var res = re.exec( name_en );
name_en = res[1]; // Get the root traits name
special = " (" + game.i18n.localize( res[2].trim() ) + ")"; // And the special keyword
}
var trait_fr = fulltraits.translate( { name: name_en } );
2020-05-11 10:01:50 +02:00
//console.log(">>>>> Trait ?", name_en, nbt, trait_fr.name, special);
trait_en.name = nbt + trait_fr.name + special;
if ( trait_fr.data && trait_fr.data.description && trait_fr.data.description.value ) {
trait_en.data.description.value = trait_fr.data.description.value;
} else if ( eisitems ) { // No description in the FR compendium -> test other compendium if presenr
trait_fr = eisitems.translate( { name: name_en } );
trait_en.name = nbt + trait_fr.name + special;
if ( trait_fr.data && trait_fr.data.description && trait_fr.data.description.value )
trait_en.data.description.value = trait_fr.data.description.value;
}
if ( isNaN(trait_en.data.specification.value) ) { // This is a string, so translate it
//console.log("Translating : ", trait_en.data.specification.value);
trait_en.data.specification.value = game.i18n.localize( trait_en.data.specification.value.trim() );
}
} else if ( trait_en.type == "skill") {
if ( name_en.includes("(") && name_en.includes(")") ) { // Then process specific skills name with (xxxx) inside
var re = /(.*) +\((.*)\)/i;
var res = re.exec( name_en );
name_en = res[1].trim(); // Get the root skill name
special = " (" + game.i18n.localize( res[2].trim() ) + ")"; // And the special keyword
}
var trait_fr = fullskills.translate( { name: name_en } );
//console.log(">>>>> Skill ?", name_en, special, trait_fr.name, trait_fr);
if (trait_fr.translated) {
trait_en.name = trait_fr.name + special;
2020-06-06 13:18:20 +02:00
if ( trait_fr.data ) {
2020-06-06 12:10:31 +02:00
trait_en.data.description.value = trait_fr.data.description.value;
}
}
} else if ( trait_en.type == "prayer") {
var trait_fr = fullprayers.translate( { name: name_en } );
//console.log(">>>>> Prayer ?", name_en, special, trait_fr.name );
trait_en.name = trait_fr.name + special;
if ( trait_fr.data && trait_fr.data.description && trait_fr.data.description.value )
trait_en.data.description.value = trait_fr.data.description.value;
} else if ( trait_en.type == "spell") {
var trait_fr = fullspells.translate( { name: name_en } );
if ( (!trait_fr.data || !trait_fr.data.description || !trait_fr.data.description.value) && eisspells) { // If no translation, test eisspells
trait_fr = eisspells.translate( { name: name_en } );
}
2020-05-11 10:01:50 +02:00
//console.log(">>>>> Spell ?", name_en, special, trait_fr.name );
trait_en.name = trait_fr.name + special;
if ( trait_fr.data && trait_fr.data.description && trait_fr.data.description.value )
trait_en.data.description.value = trait_fr.data.description.value;
} else if ( trait_en.type == "talent") {
if ( name_en.includes("(") && name_en.includes(")") ) { // Then process specific skills name with (xxxx) inside
var re = /(.*) +\((.*)\)/i;
var res = re.exec( name_en );
name_en = res[1].trim(); // Get the root talent name, no parenthesis this time...
special = " (" + game.i18n.localize( res[2].trim() ) + ")"; // And the special keyword
}
var trait_fr = fulltalents.translate( { name: name_en } );
2020-05-11 10:01:50 +02:00
//console.log(">>>>> Talent ?", name_en, special, trait_fr.name);
if ( trait_fr.translated) {
trait_en.name = trait_fr.name + special;
2020-06-05 00:30:56 +02:00
if ( trait_fr.data ) {
trait_en.data.description.value = trait_fr.data.description.value;
}
}
} else if ( trait_en.type == "career") {
var career_fr = fullcareers.translate( trait_en );
2020-05-11 10:01:50 +02:00
//console.log(">>>>> Career ?", name_en, career_fr.name);
trait_en = career_fr;
} else if ( trait_en.type == "trapping" || trait_en.type == "weapon" || trait_en.type == "armour" || trait_en.type == "container" || trait_en.type == "money") {
var trapping_fr = fulltrappings.translate( trait_en );
2020-05-11 10:01:50 +02:00
//console.log(">>>>> Trapping ?", name_en, trapping_fr.name);
trait_en.name = trapping_fr.name;
2020-06-05 00:30:56 +02:00
if ( trapping_fr.data) {
trait_en.data.description = trapping_fr.data.description;
}
2020-04-22 20:22:34 +02:00
}
}
return beast_traits;
},
2020-03-31 09:27:04 +02:00
// To avoid duplicateing class for all careers
2020-03-31 17:44:46 +02:00
"generic_localization": (value) => {
2020-04-01 00:41:20 +02:00
if ( value )
return game.i18n.localize( value.trim() );
2020-04-10 15:11:26 +02:00
},
2020-04-01 00:41:20 +02:00
"trapping_qualities_flaws": (value) => {
if ( value ) {
var list = value.split( "," );
var i=0;
var re = /(.*) (\d+)/i;
for (i=0; i<list.length; i++) {
var splitted = re.exec( list[i].trim() );
if ( splitted ) {
//console.log("FOund:", splitted[0], splitted[1], splitted[2] );
list[i] = game.i18n.localize( splitted[1] ) + " " + splitted[2];
} else {
list[i] = game.i18n.localize( list[i].trim() ) ;
}
2020-03-31 17:44:46 +02:00
}
2020-04-01 00:41:20 +02:00
return list.toString();
2020-03-31 17:44:46 +02:00
}
},
2020-03-31 09:27:04 +02:00
// Search back in careers the translated name of the groupe (as it is the name of the level career itself)
"career_careergroup": (value) => {
var compendium = game.packs.find(p => p.collection === 'wfrp4e.careers');
2020-04-14 17:16:25 +02:00
return compendium.i18nName( { name: value } );
2020-04-10 15:11:26 +02:00
},
"mutations_modifier": (value) => {
console.log("Parsing mutation :", value);
value = value.toLowerCase();
value = value.replace("weapon skill" ,"Capacité de Combat");
value = value.replace("ballistic skill", "Capacité de Tir");
value = value.replace("strength", "Force");
value = value.replace("toughness", "Endurance");
value = value.replace("agility", "Agilité");
value = value.replace("dexterity", "Dextérité");
value = value.replace("willpower", "Force Mentale");
value = value.replace("fellowship", "Sociabilité");
value = value.replace("initiative", "Initiative");
value = value.replace("intelligence", "Intelligence");
return value;
},
2020-04-10 15:11:26 +02:00
// Auto-translate duration
"spells_duration_range_target_damage": (value) => {
2020-04-10 17:36:32 +02:00
//console.log("Spell duration/range/damage/target :", value);
2020-04-10 15:11:26 +02:00
if ( value == "" ) return ""; // Hop !
if ( value == "Touch" ) return "Contact"; // Hop !
if ( value == "You" ) return "Vous"; // Hop !
if ( value == "Instant" ) return "Instantané"; // Hop !
var translw = value;
var re = /(.*) Bonus (\w*)/i;
var res = re.exec( value );
var unit = "";
if ( res ) { // Test "<charac> Bonus <unit>" pattern
if ( res[1] ) { // We have char name, then convert it
translw = "Bonus de " + game.i18n.localize( res[1].trim() );
}
unit = res[2];
} else {
re = /(\d+) (\w+)/i;
res = re.exec( value );
if (res) { // Test : "<number> <unit>" pattern
translw = res[1];
unit = res[2];
} else { // Test
re = /(\w+) (\w+)/i;
res = re.exec( value );
if (res) { // Test : "<charac> <unit>" pattern
translw = game.i18n.localize( res[1].trim() );
unit = res[2];
}
}
}
if ( unit == "hour") unit = "heure";
if ( unit == "hours") unit = "heures";
if ( unit == "days") unit = "jours";
if ( unit == "yard") unit = "mètre";
if ( unit == "yards") unit = "mètres";
translw += " " + unit;
return translw;
2020-03-31 17:44:46 +02:00
}
});
2020-03-27 23:12:43 +01:00
}
2020-03-25 21:03:36 +01:00
} );
2020-04-12 08:59:47 +02:00