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",
"id": "wh4-de-translation",
"compatibility": {
"minimum": "11",
"verified": "13"
"minimum": "13",
"verified": "14"
},
"relationships": {
"systems": [
+2 -2
View File
@@ -1,7 +1,7 @@
/************************************************************************************/
//import WFRP_Tables from "/systems/wfrp4e/modules/system/tables-wfrp4e.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 = () => {
@@ -365,7 +365,7 @@ const __add_actors_translation = () => {
}
}
//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({
"career_skills": (skills_list) => {
// 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)
const career_skills_fn = (skills_list) => {
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("skill")
//DEBUG: console.log( "Thru here ...", compendium, skills_list);
if (skills_list) {
@@ -274,17 +274,43 @@ Hooks.once('init', () => {
}
}
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) => {
let skills_list = skills.split(',');
let skillsFR = game.babele.converters.career_skills(skills_list);
let skillsFR = career_skills_fn(skills_list);
return skillsFR.join(', ')
},
"process_effects": (effectsData, translations, data, tc, tc_translations) => {
//console.log("Effects :", effectsData, translations, data, tc, tc_translations)
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
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) {
for (let script of e.flags.wfrp4e.scriptData) {
if (script?.label) {
@@ -309,31 +335,32 @@ Hooks.once('init', () => {
if (translated) {
for (let data of results) {
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
}
// 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.")) {
results[0].text = "wfrp4e-core.journals"
results[0].description = "wfrp4e-core.journals"
} 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) {
let career = data.text.match(/{(.*)}/)
let career = data.description.match(/{(.*)}/)
//console.log(">>>>>", career)
if (career && career[1]) {
let careerFR = game.babele.converters.career_careergroup(career[1])
data.text = data.text.replace(career[1], careerFR)
let careerFR = career_careergroup_fn(career[1])
data.description = data.description.replace(career[1], careerFR)
}
}
}
if (results[0].documentCollection) {
return game.babele.converters.tableResults(results)
if (results?.[0].documentUuid) {
// Babele 2.8+ handles documentUuid resolution via its own mapping system
return results
}
return results
},
@@ -406,6 +433,14 @@ Hooks.once('init', () => {
return 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) {
let special = "";
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)
"career_careergroup": (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
},
"career_careergroup": career_careergroup_fn,
"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);
@@ -646,23 +663,23 @@ Hooks.once('init', () => {
for (let i = 0; i < effects.length; i++) {
let effect = effects[i];
//console.log("EFFECT LABEL1:", effect );
effect.label = translations['label' + i];
effect.name = translations['label' + i];
}
return effects
},
"diseases_effects": (effects, translations) => {
if (!effects) return;
for (let i = 0; i < effects.length; i++) {
let effect = effects[i];
let label = effect.label;
for (const element of effects) {
let effect = element;
let name = effect.name || effect.label;
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 res = re.exec(label);
label = res[1].trim(); // Get the gravity
let res = re.exec(name);
name = res[1].trim(); // Get the gravity
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
+2 -2
View File
@@ -770,10 +770,10 @@ export class WH4FRPatchConfig {
let weaponLength = args.item.reachNum
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.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)"})
}
}
`