Fix Foundry v13/v14 and Babele 2.8+ compatibility breaks

- Remove dead import of babele/script/translated-compendium.js (404,
  MIME-type block on load) and its unused TranslatedCompendium usage
- Replace broken game.babele.converters.X() cross-calls (career_skills,
  career_careergroup, tableResults) with direct function references,
  since Babele 2.8+ wraps converters as objects
- Rename RollTable fields data.text/results[].text -> .description and
  documentCollection -> documentUuid to match Babele's current schema
- Migrate ActiveEffect label -> name (Foundry v13 requires name) with
  legacy fallback in process_effects, bestiary_traits, effects and
  diseases_effects converters
- Fix stray bare duplicate() call and a syntax typo in the infighting
  effect script in config-patch.js
- Bump module.json compatibility to minimum 13 / verified 14
This commit is contained in:
2026-07-20 21:54:57 +02:00
parent 9b09f6d1da
commit 5e2c91c3d4
4 changed files with 66 additions and 49 deletions
+2 -2
View File
@@ -120,8 +120,8 @@
"download": "https://gitea.palmenalzer.de/alzer/wfrp-4e-de/archive/main.zip", "download": "https://gitea.palmenalzer.de/alzer/wfrp-4e-de/archive/main.zip",
"id": "wh4-de-translation", "id": "wh4-de-translation",
"compatibility": { "compatibility": {
"minimum": "11", "minimum": "13",
"verified": "13" "verified": "14"
}, },
"relationships": { "relationships": {
"systems": [ "systems": [
+2 -2
View File
@@ -1,7 +1,7 @@
/************************************************************************************/ /************************************************************************************/
//import WFRP_Tables from "/systems/wfrp4e/modules/system/tables-wfrp4e.js"; //import WFRP_Tables from "/systems/wfrp4e/modules/system/tables-wfrp4e.js";
import { WH4FRPatchConfig } from "./config-patch.js"; import { WH4FRPatchConfig } from "./config-patch.js";
import { TranslatedCompendium } from "../../babele/script/translated-compendium.js"; //import { TranslatedCompendium } from "../../babele/script/translated-compendium.js";
/************************************************************************************/ /************************************************************************************/
const _patch_eis = () => { const _patch_eis = () => {
@@ -365,7 +365,7 @@ const __add_actors_translation = () => {
} }
} }
//console.log(metadata, translations) //console.log(metadata, translations)
game.babele.packs.set(metadata.metadata.id, new TranslatedCompendium(metadata.metadata, translations)) //game.babele.packs.set(metadata.metadata.id, new TranslatedCompendium(metadata.metadata, translations))
} }
} }
} }
+60 -43
View File
@@ -227,9 +227,9 @@ Hooks.once('init', () => {
}, },
) )
game.babele.registerConverters({ // Pre-define functions for cross-converter calls (Babele 2.8+ wraps converters
// as objects, so game.babele.converters.X() no longer works as a plain call)
"career_skills": (skills_list) => { const career_skills_fn = (skills_list) => {
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("skill") let validCompendiums = game.wfrp4e.tags.getPacksWithTag("skill")
//DEBUG: console.log( "Thru here ...", compendium, skills_list); //DEBUG: console.log( "Thru here ...", compendium, skills_list);
if (skills_list) { if (skills_list) {
@@ -274,17 +274,43 @@ Hooks.once('init', () => {
} }
} }
return skills_list return skills_list
}, };
const career_careergroup_fn = (value) => {
// Manage exception - Dirty hack
if (value == 'Slayer') {
return "Slayer";
}
if (value == 'Druidic Priest') {
return "Druide";
}
//console.log("Carre groupe : ", value )
// Per default
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("career")
for (let compData of validCompendiums) {
let newName = game.babele.translate(compData.metadata.id, { name: value }).name
if (!newName) newName = value
return newName
}
ui.notifications.error("Das Übersetzen der Karriere " + value + " ist nicht möglich. Sie ist wahrscheinlich nicht übersetzt.", { permanent: true })
return value
};
game.babele.registerConverters({
"career_skills": career_skills_fn,
"role_skills": (skills) => { "role_skills": (skills) => {
let skills_list = skills.split(','); let skills_list = skills.split(',');
let skillsFR = game.babele.converters.career_skills(skills_list); let skillsFR = career_skills_fn(skills_list);
return skillsFR.join(', ') return skillsFR.join(', ')
}, },
"process_effects": (effectsData, translations, data, tc, tc_translations) => { "process_effects": (effectsData, translations, data, tc, tc_translations) => {
//console.log("Effects :", effectsData, translations, data, tc, tc_translations) //console.log("Effects :", effectsData, translations, data, tc, tc_translations)
for (let e of effectsData) { for (let e of effectsData) {
// Foundry v13 requires name; migrate legacy data where only label was stored
if (e.name == null) e.name = e.label || "";
let origName = e.name let origName = e.name
e.name = tc_translations.name || game.i18n.localize(e.name) e.name = tc_translations.name || game.i18n.localize(e.name) || e.label || ""
if (e.flags?.wfrp4e?.scriptData) { if (e.flags?.wfrp4e?.scriptData) {
for (let script of e.flags.wfrp4e.scriptData) { for (let script of e.flags.wfrp4e.scriptData) {
if (script?.label) { if (script?.label) {
@@ -309,31 +335,32 @@ Hooks.once('init', () => {
if (translated) { if (translated) {
for (let data of results) { for (let data of results) {
if (translated[`${data.range[0]}-${data.range[1]}`]) { if (translated[`${data.range[0]}-${data.range[1]}`]) {
data.text = translated[`${data.range[0]}-${data.range[1]}`] data.description = translated[`${data.range[0]}-${data.range[1]}`]
} }
} }
return results return results
} }
// Auto patch // Auto patch
if (results[0].text.includes("wfrp4e-core.career-descriptions")) { if (results[0].description.includes("wfrp4e-core.career-descriptions")) {
if (game.system.version.match("7.")) { if (game.system.version.match("7.")) {
results[0].text = "wfrp4e-core.journals" results[0].description = "wfrp4e-core.journals"
} else { } else {
results[0].text = "wfrp4e-core.journal-entries" results[0].description = "wfrp4e-core.journal-entries"
} }
} }
if (results[0].text.includes("wfrp4e-core.journal")) { if (results[0].description.includes("wfrp4e-core.journal")) {
for (let data of results) { for (let data of results) {
let career = data.text.match(/{(.*)}/) let career = data.description.match(/{(.*)}/)
//console.log(">>>>>", career) //console.log(">>>>>", career)
if (career && career[1]) { if (career && career[1]) {
let careerFR = game.babele.converters.career_careergroup(career[1]) let careerFR = career_careergroup_fn(career[1])
data.text = data.text.replace(career[1], careerFR) data.description = data.description.replace(career[1], careerFR)
} }
} }
} }
if (results[0].documentCollection) { if (results?.[0].documentUuid) {
return game.babele.converters.tableResults(results) // Babele 2.8+ handles documentUuid resolution via its own mapping system
return results
} }
return results return results
}, },
@@ -406,6 +433,14 @@ Hooks.once('init', () => {
return beast_traits return beast_traits
} }
//console.log("TRANS:", beast_traits) //console.log("TRANS:", beast_traits)
// Normalize: Foundry v13 requires ActiveEffect.name; migrate legacy v12 data
for (let trait_en of beast_traits) {
if (trait_en.effects) {
for (let eff of trait_en.effects) {
if (eff.name == null) eff.name = eff.label || "";
}
}
}
for (let trait_en of beast_traits) { for (let trait_en of beast_traits) {
let special = ""; let special = "";
let nbt = ""; let nbt = "";
@@ -588,25 +623,7 @@ Hooks.once('init', () => {
} }
}, },
// Search back in careers the translated name of the groupe (as it is the name of the level career itself) // Search back in careers the translated name of the groupe (as it is the name of the level career itself)
"career_careergroup": (value) => { "career_careergroup": career_careergroup_fn,
// Manage exception - Dirty hack
if (value == 'Slayer') {
return "Slayer";
}
if (value == 'Druidic Priest') {
return "Druide";
}
//console.log("Carre groupe : ", value )
// Per default
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("career")
for (let compData of validCompendiums) {
let newName = game.babele.translate(compData.metadata.id, { name: value }).name
if (!newName) newName = value
return newName
}
ui.notifications.error("Das Übersetzen der Karriere " + value + " ist nicht möglich. Sie ist wahrscheinlich nicht übersetzt.", { permanent: true })
return value
},
"mutations_modifier": (value) => { // This is really UGLYYYY i know, but i started like this and discovered afterward that many strings were not easy to automate... Sorry :) "mutations_modifier": (value) => { // This is really UGLYYYY i know, but i started like this and discovered afterward that many strings were not easy to automate... Sorry :)
//console.log("Parsing mutation :", value); //console.log("Parsing mutation :", value);
@@ -646,23 +663,23 @@ Hooks.once('init', () => {
for (let i = 0; i < effects.length; i++) { for (let i = 0; i < effects.length; i++) {
let effect = effects[i]; let effect = effects[i];
//console.log("EFFECT LABEL1:", effect ); //console.log("EFFECT LABEL1:", effect );
effect.label = translations['label' + i]; effect.name = translations['label' + i];
} }
return effects return effects
}, },
"diseases_effects": (effects, translations) => { "diseases_effects": (effects, translations) => {
if (!effects) return; if (!effects) return;
for (let i = 0; i < effects.length; i++) { for (const element of effects) {
let effect = effects[i]; let effect = element;
let label = effect.label; let name = effect.name || effect.label;
let gravity = ""; let gravity = "";
if (label.includes("(") && label.includes(")")) { // Then process specific skills name with (xxxx) inside if (name.includes("(") && name.includes(")")) { // Then process specific skills name with (xxxx) inside
let re = /(.*) +\((.*)\)/i; let re = /(.*) +\((.*)\)/i;
let res = re.exec(label); let res = re.exec(name);
label = res[1].trim(); // Get the gravity name = res[1].trim(); // Get the gravity
gravity = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword gravity = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
} }
effect.label = game.i18n.localize(label) + gravity; effect.name = game.i18n.localize(name) + gravity;
} }
}, },
// Auto-translate duration // Auto-translate duration
+2 -2
View File
@@ -770,10 +770,10 @@ export class WH4FRPatchConfig {
let weaponLength = args.item.reachNum let weaponLength = args.item.reachNum
if (weaponLength > 3) if (weaponLength > 3)
{ {
let improv = duplicate(game.wfrp4e.config.systemItems.improv) let improv = foundry.utils.duplicate(game.wfrp4e.config.systemItems.improv)
improv.system.twohanded.value = args.item.twohanded.value improv.system.twohanded.value = args.item.twohanded.value
improv.system.offhand.value = args.item.offhand.value improv.system.offhand.value = args.item.offhand.value
args.item.update({"system" : improv.system, name : args.item.name + " (Combat au Contact")}) args.item.update({"system" : improv.system, name : args.item.name + " (Combat au Contact)"})
} }
} }
` `