forked from public/foundryvtt-wh4-lang-fr-fr
		
	Fix char import
This commit is contained in:
		| @@ -27,6 +27,8 @@ 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 "./xregexp-all.js"; | ||||
| @@ -35,19 +37,19 @@ const fr_carac = 'm\\s+ws\\s+bs\\s+s\\s+t\\s+i\\s+agi?\\s+dex\\s+int\\s+\\wp\\s+ | ||||
| const carac_val = '(?<m>[0-9-]+)\\s+(?<ws>[0-9-]+)\\s+(?<bs>[0-9-]+)\\s+(?<s>[0-9-]+)\\s+(?<t>[0-9-]+)\\s+(?<i>[0-9-]+)\\s+(?<ag>[0-9-]+)\\s+(?<dex>[0-9-]+)\\s+(?<int>[0-9-]+)\\s+(?<wp>[0-9-]+)\\s+(?<fel>[0-9-]+)\\s+(?<w>[0-9-\*]+)'; | ||||
| const name_val = '(?<name>[a-zA-Z\\s\\-,]*)[\\s\\r\\na-zA-Z]*(?<tiers>.*|[\\(\\)a-z0-9]+)'; | ||||
| let sectionData = [ | ||||
|     { name: "trait", toFind:"Traits\\s*:", secondParse: '(?<name>[a-z\\s]*)[\\s\\+]*(?<value>.*|[0-9]+)', index:-1 }, | ||||
|     { name: "skill", toFind:"Skills\\s*:", secondParse: '(?<name>[a-z\\s\\(\\)]*)[\\s\\+]*(?<value>.*|[0-9]+)', index:-1 }, | ||||
|     { name: "talent", toFind:"Talents\\s*:", secondParse: '(?<name>[a-z\\-\\s!/]*)[\\s\\+]*(?<value>.*|[0-9]+)', index:-1 },  | ||||
|     { name: "trapping", toFind:"Trappings\\s*:", secondParse: '(?<name>[a-z\\s]*)[\\s\\+]*(?<value>.*|[0-9]+)', index:-1 } | ||||
|   ]; | ||||
|   { name: "trait", toFind: "Traits\\s*:", secondParse: '(?<name>[a-z\\s]*)[\\s\\+]*(?<value>.*|[0-9]+)', index: -1 }, | ||||
|   { name: "skill", toFind: "Skills\\s*:", secondParse: '(?<name>[a-z\\s\\(\\)]*)[\\s\\+]*(?<value>.*|[0-9]+)', index: -1 }, | ||||
|   { name: "talent", toFind: "Talents\\s*:", secondParse: '(?<name>[a-z\\-\\s!/]*)[\\s\\+]*(?<value>.*|[0-9]+)', index: -1 }, | ||||
|   { name: "trapping", toFind: "Trappings\\s*:", secondParse: '(?<name>[a-z\\s]*)[\\s\\+]*(?<value>.*|[0-9]+)', index: -1 } | ||||
| ]; | ||||
| let regSep = XRegExp('\\s*,\\s*', 'gi'); // Term separator, with auto trim | ||||
| let regLine1 = XRegExp('[\\r\\n\\.]', 'gi'); // Term separator, with auto trim | ||||
| let regName = XRegExp(name_val, 'gi'); | ||||
|  | ||||
| /************************************************************************************/ | ||||
| async function __findItem(itemName, itemType, location = null) { | ||||
|   itemName = itemName.trim(); | ||||
|   let items = game.items.entities.filter(i => i.type == itemType) | ||||
|   let toSearch = itemName.toLowerCase().trim(); | ||||
|   let items = game.items.contents.filter(i => i.type == itemType) | ||||
|  | ||||
|   // Search imported items first | ||||
|   for (let i of items) { | ||||
| @@ -63,52 +65,54 @@ async function __findItem(itemName, itemType, location = null) { | ||||
|         location.split(".")[1] == p.metadata.name | ||||
|     }) | ||||
|     if (pack) { | ||||
|       if (pack.translations[itemName])  { | ||||
|         let translItemName = pack.translations[itemName].name; | ||||
|         await pack.getIndex().then(index => itemList = index); | ||||
|         let searchResult = itemList.find(t => t.name == translItemName) | ||||
|         if (searchResult) | ||||
|           return await pack.getEntity(searchResult._id) | ||||
|       } | ||||
|       await pack.getIndex().then(index => itemList = index); | ||||
|       let searchResult = itemList.find(t => (t.translated && t.originalName.toLowerCase() == toSearch) || (t.name.toLowerCase() == toSearch) ); | ||||
|       if (searchResult) | ||||
|         return await pack.getDocument(searchResult._id) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // If all else fails, search each pack | ||||
|   for (let p of game.packs.filter(p => p.metadata.tags && p.metadata.tags.includes(itemType))) { | ||||
|     if (p.translations[itemName])  { | ||||
|       let translItemName = p.translations[itemName].name; | ||||
|       await p.getIndex().then(index => itemList = index); | ||||
|       let searchResult = itemList.find(t => t.name == translItemName) | ||||
|       if (searchResult) | ||||
|         return await p.getEntity(searchResult._id) | ||||
|     } | ||||
|   for (let p of game.wfrp4e.tags.getPacksWithTag(itemType)) { | ||||
|     await p.getIndex().then(index => itemList = index); | ||||
|     let searchResult = itemList.find(t => (t.translated && t.originalName.toLowerCase() == toSearch) || (t.name.toLowerCase() == toSearch) ); | ||||
|     if (searchResult) | ||||
|       return await p.getDocument(searchResult._id) | ||||
|   } | ||||
| } | ||||
|  | ||||
| /************************************************************************************/ | ||||
| async function __findSkill(skillName) { | ||||
|   skillName = skillName.trim(); | ||||
|   // First try world items | ||||
|   let worldItem = game.items.entities.filter(i => i.type == "skill" && i.name == skillName)[0]; | ||||
|   if (worldItem) return worldItem | ||||
|  | ||||
|   let skillList = []; | ||||
|   let packs = game.packs.filter(p => p.metadata.tags && p.metadata.tags.includes("skill")) | ||||
| /************************************************************************************/ | ||||
| async function __findSkill(skillName, value = undefined) { | ||||
|   let toSearch = skillName.toLowerCase().trim(); | ||||
|   let parseStr = '(?<name>[a-z\\s]*)[\\s\\+]*(?<specialized>[a-z\\s\\(\\)]*)'; | ||||
|   let skillSplit = XRegExp.exec(skillName, XRegExp(parseStr, 'gi')); | ||||
|  | ||||
|   // First try world items | ||||
|   let worldItem = game.items.contents.filter(i => i.type == "skill" && i.name.toLowerCase() == toSearch)[0]; | ||||
|   if (worldItem) return worldItem; | ||||
|  | ||||
|   let packs = game.wfrp4e.tags.getPacksWithTag("skill"); | ||||
|   for (let pack of packs) { | ||||
|     //console.log("SEARCH : ", skillName, pack); | ||||
|     if ( pack.translations[skillName] ) { | ||||
|       let translSkillName = pack.translations[skillName].name; | ||||
|       skillList = await pack.getIndex() | ||||
|       // Search for specific skill (won't find unlisted specializations) | ||||
|       let searchResult = skillList.find(s => s.name == translSkillName) | ||||
|       if (!searchResult) | ||||
|         searchResult = skillList.find(s => s.name.split("(")[0].trim() == skillName.split("(")[0].trim()) | ||||
|       if (searchResult) { | ||||
|         let dbSkill; | ||||
|         await pack.getEntity(searchResult._id).then(packSkill => dbSkill = packSkill); | ||||
|         dbSkill.data.name = translSkillName; // This is important if a specialized skill wasn't found. Without it, <Skill ()> would be added instead of <Skill (Specialization)> | ||||
|         return dbSkill; | ||||
|     let skillList = await pack.getIndex(); | ||||
|     // Search for specific skill (won't find unlisted specializations) | ||||
|     let searchResult = skillList.find(s => (s.translated && s.originalName.toLowerCase() == toSearch) || (s.name.toLowerCase() == toSearch ) ); | ||||
|     if (!searchResult) { | ||||
|       let toSearchClean = toSearch.split("(")[0].trim(); | ||||
|       searchResult = skillList.find(s => (s.translated && s.originalName.toLowerCase().split("(")[0].trim() == toSearchClean) ||  | ||||
|                 (s.name.toLowerCase().split("(")[0].trim() == toSearchClean)   ); | ||||
|     } | ||||
|     if (searchResult) { | ||||
|       let dbSkill; | ||||
|       await pack.getDocument(searchResult._id).then(packSkill => dbSkill = packSkill); | ||||
|       if (skillSplit.specialized && ( dbSkill.name.includes('()') || dbSkill.name.includes('( )' ) ) ) { | ||||
|         let spec = XRegExp.replace(skillSplit.specialized, "(", ""); | ||||
|         spec = XRegExp.replace(spec, ")", ""); | ||||
|         let skillSplit2 = XRegExp.exec(dbSkill.name, XRegExp(parseStr, 'gi')); | ||||
|         dbSkill.data.update( { name: skillSplit2.name + '(' + game.i18n.localize( spec.trim() ) + ')' } ); | ||||
|       } | ||||
|       //game.babele.translate('wfrp4e-core.skills', dbSkill); | ||||
|       return dbSkill; | ||||
|     } | ||||
|   } | ||||
|   throw "Could not find skill (or specialization of) " + skillName + " in compendum or world" | ||||
| @@ -116,35 +120,40 @@ async function __findSkill(skillName) { | ||||
|  | ||||
| /************************************************************************************/ | ||||
| async function __findTalent(talentName) { | ||||
|   talentName = talentName.trim(); | ||||
|   let parseStr = '(?<name>[a-z\\s]*)[\\s\\+]*(?<specialized>[a-z\\s\\(\\)]*)'; | ||||
|   let talentSplit = XRegExp.exec(talentName, XRegExp(parseStr, 'gi')); | ||||
|   let toSearch = talentSplit.name.toLowerCase().trim(); | ||||
|  | ||||
|   // First try world items | ||||
|   let worldItem = game.items.entities.filter(i => i.type == "talent" && i.name == talentName)[0]; | ||||
|   if (worldItem) return worldItem | ||||
|   let worldItem = game.items.contents.filter(i => i.type == "talent" && i.name.toLowerCase() == toSearch)[0]; | ||||
|   if (worldItem) return worldItem; | ||||
|  | ||||
|   let talentList = []; | ||||
|   let packs = game.packs.filter(p => p.metadata.tags && p.metadata.tags.includes("talent")) | ||||
|   let packs = game.wfrp4e.tags.getPacksWithTag("talent"); | ||||
|   for (let pack of packs) { | ||||
|     if ( pack.translations[talentName] ) { | ||||
|       let translTalentName = pack.translations[talentName].name; | ||||
|       talentList = await pack.getIndex() | ||||
|       // Search for specific talent (won't find unlisted specializations) | ||||
|       let searchResult = talentList.find(t => t.name == translTalentName) | ||||
|       if (!searchResult) | ||||
|         searchResult = talentList.find(t => t.name.split("(")[0].trim() == talentName.split("(")[0].trim()) | ||||
|  | ||||
|       if (searchResult) { | ||||
|         let dbTalent; | ||||
|         await pack.getEntity(searchResult._id).then(packTalent => dbTalent = packTalent); | ||||
|         dbTalent.data.name = translTalentName; // This is important if a specialized talent wasn't found. Without it, <Talent ()> would be added instead of <Talent (Specialization)> | ||||
|         return dbTalent; | ||||
|     let talentList = await pack.getIndex(); | ||||
|     // Search for specific skill (won't find unlisted specializations) | ||||
|     let searchResult = talentList.find(s => (s.translated && s.originalName.toLowerCase() == toSearch) || (s.name.toLowerCase() == toSearch ) ); | ||||
|     if (!searchResult) { | ||||
|       let toSearchClean = toSearch.split("(")[0].trim(); | ||||
|       searchResult = talentList.find(s => (s.translated && s.originalName.toLowerCase().split("(")[0].trim() == toSearchClean) ||  | ||||
|                 (s.name.toLowerCase().split("(")[0].trim() == toSearchClean)   ); | ||||
|     } | ||||
|     if (searchResult) { | ||||
|       let dbTalent; | ||||
|       await pack.getDocument(searchResult._id).then(packTalent => dbTalent = packTalent); | ||||
|       if ( talentSplit.specialized  ) { | ||||
|         let spec = XRegExp.replace(talentSplit.specialized, "(", ""); | ||||
|         spec = XRegExp.replace(spec, ")", ""); | ||||
|         dbTalent.data.update( { name: talentSplit.name + '(' + game.i18n.localize( spec.trim() ) + ')' } ); | ||||
|       } | ||||
|       return dbTalent; | ||||
|     } | ||||
|   } | ||||
|   throw "Could not find talent (or specialization of) " + talentName + " in compendium or world" | ||||
| } | ||||
|  | ||||
| /************************************************************************************/ | ||||
| export default async function statParserFR( statString, type = "npc") { | ||||
| export default async function statParserFR(statString, type = "npc") { | ||||
|   let model = duplicate(game.system.model.Actor[type]); | ||||
|  | ||||
|   let reg1 = XRegExp(us_carac, 'gi'); | ||||
| @@ -154,30 +163,30 @@ export default async function statParserFR( statString, type = "npc") { | ||||
|     let res1 = XRegExp.exec(statString, reg1); | ||||
|     console.log("REG", res1); | ||||
|     let pnjStr = statString.substring(0, res1.index); | ||||
|     let nameRes = XRegExp.exec(pnjStr, regName ); | ||||
|     let nameRes = XRegExp.exec(pnjStr, regName); | ||||
|     console.log(nameRes); | ||||
|     if ( nameRes.tiers && nameRes.tiers.length > 0 && hasProperty(model, "details.status.value") )  { | ||||
|     if (nameRes.tiers && nameRes.tiers.length > 0 && hasProperty(model, "details.status.value")) { | ||||
|       let regTiers = XRegExp("(?<name>[A-Za-z]*)\\s+(?<level>[0-9]*)"); | ||||
|       let resTiers = XRegExp.exec(nameRes.tiers, regTiers); | ||||
|       console.log(resTiers); | ||||
|       model.details.status.value = game.i18n.localize(resTiers.name.trim()) + " " +  resTiers.level; | ||||
|       model.details.status.value = game.i18n.localize(resTiers.name.trim()) + " " + resTiers.level; | ||||
|     } | ||||
|     // Compute the PNJ name | ||||
|     let pnjName = nameRes.name.split("—")[0].split(" ").filter(f => !!f); | ||||
|     pnjName = pnjName.map(word => { | ||||
|         if (word == "VON") | ||||
|             return word.toLowerCase(); | ||||
|       if (word == "VON") | ||||
|         return word.toLowerCase(); | ||||
|  | ||||
|         word = word.toLowerCase(); | ||||
|         word = word[0].toUpperCase() + word.substring(1, word.length); | ||||
|         return word; | ||||
|       word = word.toLowerCase(); | ||||
|       word = word[0].toUpperCase() + word.substring(1, word.length); | ||||
|       return word; | ||||
|     }) | ||||
|     pnjName = pnjName.join(" ") | ||||
|  | ||||
|     // Get the carac values | ||||
|     let reg2 = XRegExp(carac_val, 'gi'); | ||||
|     let resCarac = XRegExp.exec(statString, reg2); // resr contains all carac found | ||||
|      | ||||
|  | ||||
|     // Setup carac | ||||
|     if (resCarac["Agi"]) resCarac["Ag"] = resCarac["Agi"]; // Auto patch | ||||
|     model.details.move.value = Number(resCarac["m"]); | ||||
| @@ -188,55 +197,55 @@ export default async function statParserFR( statString, type = "npc") { | ||||
|     //console.log("CARAC", model.characteristics); | ||||
|  | ||||
|     // Search position of skills/talents/... | ||||
|     for( let def of sectionData ) { | ||||
|     for (let def of sectionData) { | ||||
|       def.regDef = XRegExp(def.toFind, 'gi'); | ||||
|       let res = XRegExp.exec(statString, def.regDef); | ||||
|       if (res ) def.index = res.index; // Get the index in the string | ||||
|       if (res) def.index = res.index; // Get the index in the string | ||||
|       //console.log("   Parsing", def.name, res); | ||||
|     } | ||||
|     // Sort to split position of various substring | ||||
|     sectionData.sort( function(a, b) { return a.index - b.index; } ); | ||||
|      | ||||
|     sectionData.sort(function (a, b) { return a.index - b.index; }); | ||||
|  | ||||
|     let globalItemList = []; | ||||
|     // Then loop again and process each item type | ||||
|     for(let i=0; i< sectionData.length; i++ ) { | ||||
|     for (let i = 0; i < sectionData.length; i++) { | ||||
|       let def = sectionData[i]; | ||||
|       if ( def.index > -1) { | ||||
|       if (def.index > -1) { | ||||
|         let maxIndex = statString.length; | ||||
|         if ( sectionData[i+1] && sectionData[i+1].index > -1 ) | ||||
|           maxIndex = sectionData[i+1].index; | ||||
|         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, " "); | ||||
|         // 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 | ||||
|         let termList = XRegExp.split(def.substring, regSep); | ||||
|         for (let name of termList) { | ||||
|           let itemFound, subres;           | ||||
|           if (def.secondParse) {  | ||||
|             subres = XRegExp.exec( name, XRegExp(def.secondParse, 'gi') ); | ||||
|             name = subres.name.trim(); | ||||
|           } | ||||
|           if ( def.name == 'trait') { | ||||
|             try {  | ||||
|           let itemFound, subres, value; | ||||
|           if (def.secondParse) { | ||||
|             subres = XRegExp.exec(name, XRegExp(def.secondParse, 'gi')); | ||||
|             name  = subres.name.trim(); | ||||
|             value = XRegExp.replace(subres.value, "(", ""); | ||||
|             value = XRegExp.replace(subres.value, ")", ""); | ||||
|         } | ||||
|           if (def.name == 'trait') { | ||||
|             try { | ||||
|               itemFound = await __findItem(name, "trait"); | ||||
|             } | ||||
|             catch {} | ||||
|             if ( itemFound && subres && subres.value.length > 0 ) { | ||||
|               subres.value = XRegExp.replace(subres.value, "(", ""); | ||||
|               subres.value = XRegExp.replace(subres.value, ")", ""); | ||||
|               itemFound.data.data.specification.value = game.i18n.localize( subres.value); | ||||
|             catch { } | ||||
|             if (itemFound && subres && subres.value.length > 0) { | ||||
|               itemFound.data.data.specification.value = game.i18n.localize(value); | ||||
|             } | ||||
|             if (!itemFound) | ||||
|               ui.notifications.error("Trait non trouvé, à ajouter manuellemen : " + name, { permanent: true }) | ||||
|           } else if  ( def.name == 'skill') { | ||||
|               ui.notifications.error("Trait non trouvé, à ajouter manuellement : " + name, { permanent: true }) | ||||
|           } else if (def.name == 'skill') { | ||||
|             try { | ||||
|               itemFound = await __findSkill(name); | ||||
|               itemFound = await __findSkill(name, value); | ||||
|             } | ||||
|             catch {} | ||||
|             if ( itemFound && subres && subres.value) { | ||||
|               itemFound.data.data.advances.value = Number(subres.value) - Number(resCarac[itemFound.data.data.characteristic.value]); | ||||
|             catch { } | ||||
|             if (itemFound && subres && value) { | ||||
|               itemFound.data.data.advances.value = Number(value) - Number(model.characteristics[itemFound.data.data.characteristic.value].initial); | ||||
|             } | ||||
|             if (!itemFound) | ||||
|               ui.notifications.error("Compétence non trouvée, à ajouter manuellement : " + name, { permanent: true }) | ||||
| @@ -244,23 +253,23 @@ export default async function statParserFR( statString, type = "npc") { | ||||
|             try { | ||||
|               itemFound = await __findTalent(name); | ||||
|             } | ||||
|             catch {} | ||||
|             if ( itemFound && subres && subres.value) | ||||
|               itemFound.data.data.advances.value = Number(subres.value); | ||||
|             catch { } | ||||
|             if (itemFound && subres && value) | ||||
|               itemFound.data.data.advances.value = Number(value); | ||||
|             if (!itemFound) | ||||
|               ui.notifications.error("Talent non trouvé, à ajouter manuellement : " + name, { permanent: true }) | ||||
|           } else if (def.name == 'trapping') { | ||||
|             try { | ||||
|               itemFound = await __findItem(name, "trapping"); | ||||
|             } | ||||
|             catch {} | ||||
|             catch { } | ||||
|             if (!itemFound) { | ||||
|               itemFound = new game.wfrp4e.entities.ItemWfrp4e({ img: "systems/wfrp4e/icons/blank.png", name: name, type: "trapping", data: game.system.model.Item.trapping }) | ||||
|               itemFound = new ItemWfrp4e({ img: "systems/wfrp4e/icons/blank.png", name: name, type: "trapping", data: game.system.model.Item.trapping }) | ||||
|               itemFound.data.data.trappingType.value = "misc" | ||||
|             }  | ||||
|             } | ||||
|           } | ||||
|           if (itemFound) | ||||
|             globalItemList.push( itemFound ); | ||||
|             globalItemList.push(itemFound); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| @@ -270,18 +279,23 @@ export default async function statParserFR( statString, type = "npc") { | ||||
|     globalItemList = globalItemList.concat(moneyItems); | ||||
|     //console.log("My liste :", globalItemList); | ||||
|     let name = pnjName; | ||||
|     return { name, type, data: model, items: globalItemList } | ||||
|  | ||||
|     let effects = globalItemList.reduce((total, globItem) => total.concat(globItem.data.effects), []) | ||||
|     effects = effects.filter(e => !!e) | ||||
|     effects = effects.filter(e => e.transfer) | ||||
|  | ||||
|     return { name, type, data: model, items: globalItemList, effects } | ||||
|   } | ||||
|  | ||||
|   // If the carac string has not been found | ||||
|   ui.notifications.error("Impossible de convertir ces statitiques, les caractéristiques n'ont pas été trouvées", { permanent: true } ) | ||||
|   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); | ||||
|  | ||||
| } ) | ||||
| }) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user