diff --git a/compendium/wfrp4e-core.prayers.json b/compendium/wfrp4e-core.prayers.json
index 59f8909..02f421d 100644
--- a/compendium/wfrp4e-core.prayers.json
+++ b/compendium/wfrp4e-core.prayers.json
@@ -698,7 +698,7 @@
"wfrp4e": {
"effectApplication": "apply",
"effectTrigger": "oneTime",
- "script": "if (args.actor.data.traits.find(t => t.name == \"Mort-vivant\"))\n{\n let damage = new Roll(\"1d10\").roll().total\n args.actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL})\n}"
+ "script": "if (args.actor.has(\"Mort-vivant\"))\n{\n let damage = (await new Roll(\"1d10\")).roll().total\n args.actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL})\n}"
}
},
"icon": "modules/wfrp4e-core/icons/prayers/miracles.png",
@@ -839,7 +839,7 @@
"wfrp4e": {
"effectApplication": "apply",
"effectTrigger": "oneTime",
- "script": "if (args.actor.data.traits.find(t => t.name == \"Mort-vivant\") && args.actor.data.traits.find(t => t.name == \"Construct\"))\n args.actor.addCondition(\"dead\")"
+ "script": "if (args.actor.has(\"Mort-vivant\") && args.actor.has(\"Construct\"))\n args.actor.addCondition(\"dead\")"
}
},
"icon": "modules/wfrp4e-core/icons/prayers/miracles.png",
@@ -1142,7 +1142,7 @@
"wfrp4e": {
"effectApplication": "apply",
"effectTrigger": "oneTime",
- "script": "let damage = new Roll(\"1d10\").roll().total\n args.actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL})\n\nif (args.actor.data.traits.find(t => t.name == \"Mort-vivant\") || args.actor.data.traits.find(t => t.name == \"Démoniaque\"))\n{\n args.actor.addCondition(\"ablaze\")\n}"
+ "script": "let damage = (await new Roll(\"1d10\")).roll().total\n args.actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL})\n\nif (args.actor.has(\"Mort-vivant\") || args.actor.data.has(\"Démoniaque\"))\n{\n args.actor.addCondition(\"ablaze\")\n}"
}
},
"icon": "modules/wfrp4e-core/icons/prayers/miracles.png",
diff --git a/fr.json b/fr.json
index 56c96ac..49206ca 100644
--- a/fr.json
+++ b/fr.json
@@ -196,7 +196,9 @@
"ACTOR.TypeCreature": "Créature",
"ACTOR.ClearMount":"Enlever la monture",
"ACTOR.AdvancementError":"Impossible de progresser : {action} {item}, pas assez d'expérience disponible",
-
+ "ACTOR.ErrorAdd":"ajouter",
+ "ACTOR.ErrorImprove":"améliorer",
+
"ITEM.PenniesValue" : "Valeur (en Sous de Cuivre)",
"ITEM.MeleeDamage" : "Dommages Mêlée",
"ITEM.RangedDamage" : "Dommages Projectiles",
@@ -491,7 +493,9 @@
"Intruders": "Intrus",
"Monsters": "Monstres",
"Law": "Loi",
-
+ "SinReduced":"Péché réduit de 1",
+ "TargetingCancelled":"Ciblage échoué: Un Test opposé est déja en cours",
+
"Career Selector":"Selecteur de Carrière",
"Completed":"Completé",
"CondRound":"- Round {round}",
@@ -595,7 +599,9 @@
"MOO.Penetrating":"Cette arme est très effice pour pénétrer des armures. Elle permet d'ignorer (Rating) PA.",
"MOO.Prone":"
Règles Maison de MooMan: Vous êtes considéré une portée plus loin lors de la déterlination de la portée des attaques par projectiles.",
"MOO.Simple":"Les armes simples peuvent être utilisées avec Corps à Coprs Simple sans pénalité.",
-
+ "MOO.CriticalChanelling":"Focalisation Critique DR Bonus",
+ "MOO.FailedCast":"Une Echec d'Incantation pendant une Focalisation compte comme une interruption.",
+
"ErrorMountNotFound": "Erreur lors de la recherche de la monture. Essyez de retirer la monture",
"ErrorDamagePermission": "Vous n'avez pas la permission pour appliquer des dommages à cette cible",
"ErrorMacroItemMissing": "Votre personnage n'a pas d'objet nommé",
@@ -710,6 +716,10 @@
"DIALOG.ItemQuantity": "Quantité",
"DIALOG.QuantityHint": "La quantité est la quantité d'objets dans chaque note du chat.
La quantité totale déduite sera la quantité affichée mutipliée par la quantité d'objets
Sélectionner 'Infini' ne déduira pas la quantité",
"DIALOG.ShowTableHint":"Montrer les tables aux joueurs et le sous menu '/table'",
+ "DIALOG.GainPrayer":"Apprendre un Miracle",
+ "DIALOG.GainPrayerContent":"Apprendre ce miracle vous coutera {xp} XP.",
+ "DIALOG.MemorizeSpell":"Mémoriser un Sort",
+ "DIALOG.MemorizeSpellContent":"Mémoriser ce sort vous coutera {xp} XP.",
"CHAT.CareerChoose" : "Choisissez votre carrière",
"CHAT.DamageError" : "Erreur de calcul des dégâts:",
@@ -843,7 +853,11 @@
"CHAT.MutateTable":"Lancer sur la Table des Corruptions:",
"CHAT.CausesFear":"provoque {fear} à",
"CHAT.OvercastReset":"Reset Sur-Incantation",
-
+ "CHAT.CommandLine.Help.Properties.Title":"Propriétés d'Item",
+ "CHAT.CommandLine.Help.Properties.Usage.Command":"/prop ",
+ "CHAT.CommandLine.Help.Properties.Usage.Example":"
/prop impact
/prop shoddy",
+ "CHAT.CommandLine.Help.Properties.Usage.Note":"cherchera la propriété la plus proche syntaxquement et l'affiche (eg. /prop préc == /prop précise)",
+
"Error.SpeciesSkills" : "Impossible d'ajouter des compétences pour les races",
"Error.SpeciesTalents" : "Impossible d'ajouter des talents pour les races",
"Error.CriticalWound" : "Erreur lors de l'application des blessures",
@@ -873,8 +887,13 @@
"ERROR.Experience":"Les points d'EXP doivent être des valeurs numérique.",
"ERROR.ID":"ID pour {name} existe déja dans la collection concernée. Ce Document a reçu un ID unique.",
"ERROR.EFFECT":"Une erreur est survenue lors de l'execution de l'Effet {effect}, merci de consulter la console (F12)",
-
+ "ERROR.Column":"Vous devez spécifier une colonne pour réaliser le jet",
+ "ERROR.Opposed":"L'attaquant et le défenseur doivent réaliser un test pour calculer l'opposition",
+ "ERROR.Property":"Les jets doivent indiquer la propriété de l'Item",
+ "ERROR.Speaker":"Les jets doivent indiquer le 'speaker'",
+
"WARNING.Target":"Select a target to apply the effect.",
+ "WARNING.ActorTest":"Les classes de jet d'acteurne sont plus utilisées. Appelez désormais `roll()` sur l'objet lui-même.",
"INCOME.YouEarn" : "Vous gagnez",
"INCOME.Failure" : "Vous avez eu une très mauvaise semaine, et vous ne gagnez rien (ou votre argent a été volé).",
@@ -1539,6 +1558,7 @@
"SHEET.LoadingCareers":"Chargement des carrières...",
"SHEET.Target":"Cible",
"SHEET.ToggleTraits":"Basculer le(s) Trait(s) de Creature",
+ "SHEET.SortItems":"Trier les items",
"DISEASE.IncubationFinished" : "Incubation de la maladie {disease} terminée. ",
@@ -1683,7 +1703,9 @@
"CHATOPT.UseFortuneSL":"Utiliser un Point de Chance pour ajouter +1 DR",
"CHATOPT.DarkDeal": "Conclure un Sombre Pacte pour relancer (+1 Point de Corruption)",
"CHATOPT.OpposeTarget": "Opposé avec les Cibles",
-
+ "CHATOPT.ApplyAllDamage":"Appliquer tout les dommages",
+ "CHATOPT.CompleteUnopposed":"Finier tout les tests opposés",
+
"Shipwright": "Constructeur de bateaux",
"Riverways or Sea Lanes": "Rivières ou Voies Maritimes",
"Embalmer": "Embaumeur",
@@ -1775,7 +1797,9 @@
"EFFECT.Applied":"{name} appliqué à ",
"EFFECT.Prevent":"Ajout de l'effet {name} annulé: l'Effet existe déja",
"EFFECT.Target":"Cible: ",
-
+ "EFFECT.QuantityError":"Quantité insuffisante",
+ "EFFECT.ReduceQuantityOption":"Réduire la quantité à l'usage",
+
"GRIEVANCE.Warning1":"Attention",
"GRIEVANCE.Warning2":": Cette information est envoyé sur l'espace Github, qui est un espace publique, donc le Tag Discord est préférable. Sinon, contactez moi (MooMan) directement. Si vous avez l'impression que le bug concerne le module FR, contactez LeRatierBretonnier (Discord Foundry FR)",
"GRIEVANCE.Warning3":"Avant de soumettre un rapport de bug",
@@ -1840,6 +1864,9 @@
"RANDOMIZER.S":"C",
"RANDOMIZER.T":"T",
+ "LOG.GainPrayer":" Prière {name} acquis",
+ "LOG.MemorizedSpell": "Sort {name} mémorisé",
+
"EiS.MinorDhar" : "Tout les êtres vivants dans un rayon de FM mètres subissent une @Corruption[minor]{Influence Corruptrice Mineure} et une Incantation Imparfait Mineure; un seul tirage pour toutes les créatures dans l'aire d'effet.",
"EiS.MajorDhar" : "Tout les êtres vivants dans un rayon de FM mètres subissent une @Corruption[major]{Influence Corruptrice Majeure} et une Incantation Imparfait Majeure; un seul tirage pour toutes les créatures dans l'aire d'effet.",
"EiS.DoubleRolled" : "Compte comme une @Corruption[minor]{Influence Corruptrice Mineure}"
diff --git a/module.json b/module.json
index a105091..1bbb799 100644
--- a/module.json
+++ b/module.json
@@ -6,7 +6,7 @@
"authors": [],
"url": "https://gitlab.com/LeRatierBretonnien/foundryvtt-wh4-lang-fr-fr",
"flags": {},
- "version": "5.1.3",
+ "version": "5.1.4",
"minimumCoreVersion": "0.8.0",
"compatibleCoreVersion": "9",
"scripts": [],
diff --git a/modules/import-stat-2.js b/modules/import-stat-2.js
index eebb4ae..2747570 100644
--- a/modules/import-stat-2.js
+++ b/modules/import-stat-2.js
@@ -1,5 +1,22 @@
/************************************************************************************/
// Some internal test strings
+let strfr = `LA TERREUR DE LA TEUFEL, TROLL DE RIVIÈRE RUSÉ
+M
+ CC CT
+ F
+ E
+ I
+ Ag Dex Int FM Soc B
+4
+ 40 15
+ 55
+ 45
+ 20
+ 15 15 30 20 5 38
+Traits : Amphibie, Arme +9, Armure (2), Dur à Cuire, Insensible
+à la douleur, Morsure +8, Régénération, Taille (Grande), Vision
+Nocturne, Vomissement`
+
let str1 = `JABBERSLYTHE
M WS BS S T I Agi Dex
Int WP Fel W
@@ -27,16 +44,22 @@ Talents: Briber, Criminal, Dealmaker,
Etiquette (Criminals, Doktor, Guilder)
Trappings: Dagger, Hand Weapon (Sword)
`
-import ItemWfrp4e from "/systems/wfrp4e/modules/item/item-wfrp4e.js";
-import WFRP_Utility from "/systems/wfrp4e/modules/system/utility-wfrp4e.js";
+import ItemWfrp4e from "/systems/wfrp4e/modules/item/item-wfrp4e.js"
/************************************************************************************/
import "./xregexp-all.js";
const us_carac = 'm\\s+ws\\s+bs\\s+s\\s+t\\s+i\\s+agi?\\s+dex\\s+int\\s+\\wp\\s+fel\\s+w';
-const fr_carac = 'm\\s+ws\\s+bs\\s+s\\s+t\\s+i\\s+agi?\\s+dex\\s+int\\s+\\wp\\s+fel\\s+w';
+const fr_carac = 'm\\s+cc\\s+ct\\s+f\\s+e\\s+i\\s+agi?\\s+dex\\s+int\\s+fm\\s+soc\\s+b';
const carac_val = '(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-]+)\\s+(?[0-9\\-\*]+)';
const name_val = '(?[a-zA-Z\\s\\-,]*)[\\s\\r\\na-zA-Z]*(?.*|[\\(\\)a-z0-9]+)';
-let sectionData = [
+let sectionDataFR = [
+ { name: "trait", toFind: "Traits\\s*:", secondParse: '(?[a-zàéè\\s]*)[\\s\\+]*(?.*|[\\+0-9]+)', index: -1 },
+ { name: "skill", toFind: "Compétences\\s*:", secondParse: '(?[a-zàéè\\s\\(\\)]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 },
+ { name: "talent", toFind: "Talents\\s*:", secondParse: '(?[a-zàéè\\-\\s!/]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 },
+ { name: "mutation", toFind: "Mutations\\s*:", secondParse: '(?[a-zàéè\\s]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 },
+ { name: "trapping", toFind: "Equiement\\s*:", secondParse: '(?[a-zàéè\\s]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 }
+];
+let sectionDataUS = [
{ name: "trait", toFind: "Traits\\s*:", secondParse: '(?[a-z\\s]*)[\\s\\+]*(?.*|[\\+0-9]+)', index: -1 },
{ name: "skill", toFind: "Skills\\s*:", secondParse: '(?[a-z\\s\\(\\)]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 },
{ name: "talent", toFind: "Talents\\s*:", secondParse: '(?[a-z\\-\\s!/]*)[\\s\\+]*(?.*|[0-9]+)', index: -1 },
@@ -156,8 +179,8 @@ async function __findTalent(talentName) {
/************************************************************************************/
function __patchName ( name) {
if (name.toLowerCase == 'magic sense')
- name = 'Magical Sense';
- return name;
+ name = 'Magical Sense'
+ return name
}
/************************************************************************************/
@@ -167,15 +190,24 @@ export default async function statParserFR(statString, type = "npc") {
// Patch wront/strange carac value before processing
statString = statString.replace(/ –/g, " 0")
- let reg1 = XRegExp(us_carac, 'gi');
- let res = reg1.test(statString);
+ let statNameReg = us_carac
+ let sectionData = sectionDataUS
+ // Detect French stat block
+ if (statString.includes('CC') && statString.includes('CT') && statString.includes('FM')) {
+ ui.notifications.warn("Le parsing de stablock en Français n'est pas encore prêt")
+ statNameReg = fr_carac
+ sectionData = sectionDataFR
+ }
+
+ let reg1 = XRegExp(statNameReg, 'gi')
+ let res = reg1.test(statString)
if (res) { //stat block identified go on
// Extract the name
- let res1 = XRegExp.exec(statString, reg1);
- console.log("REG", res1);
- let pnjStr = statString.substring(0, res1.index);
- let nameRes = XRegExp.exec(pnjStr, regName);
- console.log(nameRes);
+ let res1 = XRegExp.exec(statString, reg1)
+ console.log("REG", res1)
+ let pnjStr = statString.substring(0, res1.index)
+ let nameRes = XRegExp.exec(pnjStr, regName)
+ console.log(nameRes)
if (nameRes.tiers && nameRes.tiers.length > 0 && hasProperty(model, "details.status.value")) {
let regTiers = XRegExp("(?[A-Za-z]*)\\s+(?[0-9]*)");
let resTiers = XRegExp.exec(nameRes.tiers, regTiers);
@@ -195,16 +227,16 @@ export default async function statParserFR(statString, type = "npc") {
pnjName = pnjName.join(" ")
// Get the carac values
- let reg2 = XRegExp(carac_val, 'gi');
- let resCarac = XRegExp.exec(statString, reg2); // resr contains all carac found
+ let reg2 = XRegExp(carac_val, 'gi')
+ let resCarac = XRegExp.exec(statString, reg2) // resr contains all carac found
// Setup carac
//console.log("CARAC", resCarac)
if (resCarac["Agi"]) resCarac["Ag"] = resCarac["Agi"] // Auto patch
- model.details.move.value = Number(resCarac["m"]);
+ model.details.move.value = Number(resCarac["m"])
for (let key in model.characteristics) {
- if (resCarac[key] === '-') resCarac[key] = 0;
- model.characteristics[key].initial = Number(resCarac[key]);
+ if (resCarac[key] === '-') resCarac[key] = 0
+ model.characteristics[key].initial = Number(resCarac[key])
}
//console.log("CARAC", model.characteristics);
@@ -223,12 +255,12 @@ export default async function statParserFR(statString, type = "npc") {
for (let i = 0; i < sectionData.length; i++) {
let def = sectionData[i];
if (def.index > -1) {
- let maxIndex = statString.length;
+ let maxIndex = statString.length
if (sectionData[i + 1] && sectionData[i + 1].index > -1)
- maxIndex = sectionData[i + 1].index;
- def.substring = statString.substring(def.index, maxIndex);
- def.substring = XRegExp.replace(def.substring, def.regDef, "");
- def.substring = XRegExp.replace(def.substring, regLine1, " ");
+ maxIndex = sectionData[i + 1].index
+ def.substring = statString.substring(def.index, maxIndex)
+ def.substring = XRegExp.replace(def.substring, def.regDef, "")
+ def.substring = XRegExp.replace(def.substring, regLine1, " ")
// At this point, def.substring contains the items list as a string
// Then create a table of it in termList, with specific sub-parsing rules
@@ -236,28 +268,30 @@ export default async function statParserFR(statString, type = "npc") {
for (let name of termList) {
let itemFound, subres, value;
if (def.secondParse) {
- subres = XRegExp.exec(name, XRegExp(def.secondParse, 'gi'));
- name = subres.name.trim().replace("\n", "").replace("\r", "");
- value = XRegExp.replace(subres.value, "(", "");
- value = XRegExp.replace(subres.value, ")", "");
+ subres = XRegExp.exec(name, XRegExp(def.secondParse, 'gi'))
+ name = subres.name.trim().replace("\n", "").replace("\r", "")
+ value = XRegExp.replace(subres.value, "(", "")
+ value = XRegExp.replace(value, ")", "")
}
- name = __patchName(name);
+ name = __patchName(name)
if (def.name == 'trait') {
try {
- itemFound = await __findItem(name, "trait");
+ itemFound = await __findItem(name, "trait")
}
catch { }
if (itemFound)
- itemFound = itemFound.toObject();
- if (itemFound && subres && subres.value.length > 0) {
- if (name.toLowerCase == 'weapon') {
- itemFound.data.specification.value = Number(value) - Math.floor( Number(model.characteristics.s.initial) / 10);
+ itemFound = itemFound.toObject()
+ if (itemFound && value && value.length > 0) {
+ if (name.toLowerCase() == 'weapon' || name.toLowerCase() == "bite" || name.toLowerCase() == "tail" ||
+ name.toLowerCase() == 'arme' || name.toLowerCase() == "morsure" || name.toLowerCase() == "queue") {
+ itemFound.data.specification.value = Number(value) - Math.floor( Number(model.characteristics.s.initial) / 10)
} else {
- itemFound.data.specification.value = game.i18n.localize(value);
+ itemFound.data.specification.value = game.i18n.localize(value)
}
}
if (!itemFound)
ui.notifications.error("Trait non trouvé, à ajouter manuellement : " + name, { permanent: true })
+
} else if (def.name == 'skill') {
try {
itemFound = await __findSkill(name, value);
@@ -324,11 +358,3 @@ export default async function statParserFR(statString, type = "npc") {
ui.notifications.error("Impossible de convertir ces statitiques, les caractéristiques n'ont pas été trouvées", { permanent: true })
}
-/************************************************************************************/
-Hooks.once('ready', () => {
-
- //var fullskills = game.packs.get('wfrp4e-core.skills');
- //console.log("Skills", game.wfrp4e.apps.StatBlockParser.prototype);
-
-})
-