From df852f17d14f7aed64e187e6728462a57c8bfea3 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Fri, 31 Jul 2026 19:13:15 +0200 Subject: [PATCH] fix: aligner le JS avec l'API Foundry v14 - effects.mjs: remove e._getSourceName() (removed in v14, now a getter) - fight.mjs: convert VermineCombatTracker from AppV1 (get template/getData) to AppV2 PARTS + _prepareContext/_prepareTurnContext - fight.mjs: VermineCombat.rollInitiative v14 options-object signature - hooks.mjs: renderPause -> renderGamePause; getSceneControlButtons now uses controls.tokens and tools record (v14 names/structure) - roll.mjs: ChatMessage.create uses rolls array (v14 removed 'roll' key) - item.mjs: getRollData returns system when no actor (v14 expects object) - vermine2047.mjs: correct unregisterSheet API for ActorSheetV2 - base-item-sheet.mjs: call super._onRender --- .../applications/sheets/base-item-sheet.mjs | 1 + module/documents/item.mjs | 2 +- module/system/effects.mjs | 1 - module/system/fight.mjs | 77 +++++++++++++++---- module/system/hooks.mjs | 10 +-- module/system/roll.mjs | 3 +- module/vermine2047.mjs | 2 +- 7 files changed, 72 insertions(+), 24 deletions(-) diff --git a/module/applications/sheets/base-item-sheet.mjs b/module/applications/sheets/base-item-sheet.mjs index 1cc1bd6..dea6170 100644 --- a/module/applications/sheets/base-item-sheet.mjs +++ b/module/applications/sheets/base-item-sheet.mjs @@ -76,6 +76,7 @@ export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.app // ── Rendu ─────────────────────────────────────────────────────────── _onRender(context, options) { + super._onRender(context, options); this.#dragDrop.forEach(d => d.bind(this.element)) } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index eb8d7f5..448b5fe 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -54,7 +54,7 @@ export default class VermineItem extends Item { */ getRollData() { // If present, return the actor's roll data. - if (!this.actor) return null; + if (!this.actor) return this.system; const rollData = this.actor.getRollData(); // Grab the item's system data as well. rollData.item = foundry.utils.deepClone(this.system); diff --git a/module/system/effects.mjs b/module/system/effects.mjs index 8052b39..55e232a 100644 --- a/module/system/effects.mjs +++ b/module/system/effects.mjs @@ -54,7 +54,6 @@ export function prepareActiveEffectCategories(effects) { // Iterate over active effects, classifying them into categories for ( let e of effects ) { - e._getSourceName(); // Trigger a lookup for the source name if ( e.disabled ) categories.inactive.effects.push(e); else if ( e.isTemporary ) categories.temporary.effects.push(e); else categories.passive.effects.push(e); diff --git a/module/system/fight.mjs b/module/system/fight.mjs index a2d11d6..1e9c306 100644 --- a/module/system/fight.mjs +++ b/module/system/fight.mjs @@ -184,10 +184,9 @@ export class VermineCombat extends Combat { // encounter check } - async rollInitiative(ids, formula = undefined, messageOptions = {}) { + async rollInitiative(ids, {formula=null, updateTurn=true, messageMode, messageOptions={}}={}) { // roll initiative - return super.rollInitiative(ids, formula, messageOptions) - + return super.rollInitiative(ids, {formula, updateTurn, messageMode, messageOptions}); } nextRound() { @@ -224,19 +223,69 @@ export class VermineCombat extends Combat { export class VermineCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker { - get template() { - return "systems/vermine2047/templates/combat-tracker.hbs"; + /** @override */ + static PARTS = { + main: { + template: "systems/vermine2047/templates/combat-tracker.hbs", + root: true + } + }; + + /** @override */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.user = game.user; + + const combat = this.viewed; + const hasCombat = combat !== null; + const combats = this.combats; + const currentIdx = combats.indexOf(combat); + const isPlayerTurn = combat?.combatant?.players?.includes(game.user); + const canControl = combat?.turn && combat.turn.between(1, combat.turns.length - 2) + ? combat.canUserModify(game.user, "update", { turn: 0 }) + : combat?.canUserModify(game.user, "update", { round: 0 }); + + Object.assign(context, { + combat, + hasCombat, + combatCount: combats.length, + currentIndex: currentIdx + 1, + previousId: combats[currentIdx - 1]?.id, + nextId: combats[currentIdx + 1]?.id, + round: combat?.round, + control: isPlayerTurn && canControl, + linked: combat?.scene !== null, + cssClass: combats.length > 7 ? "cycle" : combats.length ? "tabbed" : "", + cssId: "combat", + tabName: "combat", + labels: { + scope: game.i18n.localize(`COMBAT.${combat?.scene ? "Linked" : "Unlinked"}`) + }, + turns: [] + }); + + if ( combat ) { + for ( const [i, combatant] of combat.turns.entries() ) { + if ( !combatant.visible ) continue; + context.turns.push(await this._prepareTurnContext(combat, combatant, i)); + } + } + return context; } - async getData(options) { - const context = await super.getData(options); - - if (!context.hasCombat) { - return context; - } - - - return context; + /** @override */ + async _prepareTurnContext(combat, combatant, index) { + const turn = await super._prepareTurnContext(combat, combatant, index); + const actor = combatant.actor; + turn.attitude = combatant.getFlag("world", "attitude") || "active"; + turn.isPlayer = actor?.hasPlayerOwner ?? false; + turn.isNpc = !!actor && !actor.hasPlayerOwner; + turn.owner = combatant.isOwner; + turn.defeated = combatant.isDefeated; + turn.hasRolled = combatant.initiative !== null; + turn.hasResource = combatant.resource !== null && combatant.resource !== undefined; + turn.effects = (turn.effects?.icons ?? []).map(e => e.img); + return turn; } _onRender(context, options) { diff --git a/module/system/hooks.mjs b/module/system/hooks.mjs index ba1ec56..6eaf3a3 100644 --- a/module/system/hooks.mjs +++ b/module/system/hooks.mjs @@ -69,8 +69,8 @@ export const registerHooks = function () { }); // changement de la pause - Hooks.on("renderPause", async function () { - const pauseEl = document.getElementById("pause"); + Hooks.on("renderGamePause", async function (element) { + const pauseEl = element ?? document.getElementById("pause"); if (!pauseEl || pauseEl.className !== "paused") return; pauseEl.querySelectorAll("img").forEach(img => { img.src = 'systems/vermine2047/assets/images/ui/vermine_pause.webp'; @@ -94,9 +94,9 @@ export const registerHooks = function () { }); Hooks.on('getSceneControlButtons', async (controls) => { - const tokenControls = controls.token; + const tokenControls = controls.tokens; if (tokenControls && tokenControls.tools) { - tokenControls.tools.push({ + tokenControls.tools['dice-roller'] = { name: 'Dice Roller', title: game.i18n.localize("VERMINE.RollTool"), icon: 'fas fa-dice-d10', @@ -104,7 +104,7 @@ export const registerHooks = function () { onClick() { RollDialog.create().then(d => d.render(true)); } - }); + }; } }); diff --git a/module/system/roll.mjs b/module/system/roll.mjs index 475f424..1fa7f86 100644 --- a/module/system/roll.mjs +++ b/module/system/roll.mjs @@ -472,10 +472,9 @@ export class VermineUtils { user: game.user?._id, speaker: ChatMessage.getSpeaker(), content: content, - roll: roll + rolls: [roll] }; const msg = await ChatMessage.create(chatData); - await msg.setFlag('world', 'roll', roll); return msg; } diff --git a/module/vermine2047.mjs b/module/vermine2047.mjs index 1f0cb87..2fb261b 100644 --- a/module/vermine2047.mjs +++ b/module/vermine2047.mjs @@ -71,7 +71,7 @@ Hooks.once('init', async function () { // Register sheet application classes (ApplicationV2) // Unregister core sheets - foundry.applications.sheets.ActorSheetV2?.unregisterSheet?.("core", "Actor", { + foundry.documents.collections.Actors.unregisterSheet("core", foundry.applications.sheets.ActorSheetV2, { types: ["character", "npc", "group", "creature"] }) foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1?.sheets?.ItemSheet)