import MournbladeCYD2ActorSheetV2 from "./base-actor-sheet.mjs"; import { MournbladeCYD2Utility } from "../../mournblade-cyd2-utility.js"; export default class MournbladeCYD2PersonnageSheet extends MournbladeCYD2ActorSheetV2 { /** @override */ static DEFAULT_OPTIONS = { ...super.DEFAULT_OPTIONS, classes: [...super.DEFAULT_OPTIONS.classes], window: { ...super.DEFAULT_OPTIONS.window, title: "SHEETS.Actor.personnage", }, actions: { ...super.DEFAULT_OPTIONS.actions, removeLinkedActor: MournbladeCYD2PersonnageSheet.#onRemoveLinkedActor, }, }; /** @override */ static PARTS = { sheet: { template: "systems/fvtt-mournblade-cyd-2-0/templates/actor-sheet.hbs", }, }; /** @override */ tabGroups = { primary: "principal" }; /** @override */ async _prepareContext() { const context = await super._prepareContext(); const actor = this.document; context.combativiteList = MournbladeCYD2Utility.getCombativiteList(actor.system.sante.nbcombativite); context.ameList = MournbladeCYD2Utility.getAmeList(actor.system.ame.nbame, actor.getAmeMax?.() ?? 0); context.ameMaxList = MournbladeCYD2Utility.getAmeMaxList(actor.system.ame.nbame); context.skills = actor.getSkills?.() ?? []; context.armes = foundry.utils.duplicate(actor.getWeapons?.() ?? []); context.protections = foundry.utils.duplicate(actor.getArmors?.() ?? []); context.dons = foundry.utils.duplicate(actor.getDons?.() ?? []); context.pactes = foundry.utils.duplicate(actor.getPactes?.() ?? []); context.tendances = foundry.utils.duplicate(actor.getTendances?.() ?? []); context.runes = foundry.utils.duplicate(actor.getRunes?.() ?? []); context.traitsChaotiques = foundry.utils.duplicate(actor.getTraitsChaotiques?.() ?? []); context.traitsEspeces = foundry.utils.duplicate(actor.getTraitsEspeces?.() ?? []); context.profil = actor.getProfil?.() ?? null; context.historiques = foundry.utils.duplicate(actor.getHistoriques?.() ?? []); context.combat = actor.getCombatValues?.() ?? {}; context.equipements = foundry.utils.duplicate(actor.getEquipments?.() ?? []); context.monnaies = foundry.utils.duplicate(actor.getMonnaies?.() ?? []); context.runeEffects = foundry.utils.duplicate(actor.getRuneEffects?.() ?? []); context.ressources = foundry.utils.duplicate(actor.getRessources?.() ?? []); context.talents = foundry.utils.duplicate(actor.getTalents?.() ?? []); context.protectionTotal = actor.getProtectionTotal?.() ?? 0; context.adversiteTotal = (actor.system.adversite?.bleue || 0) + (actor.system.adversite?.rouge || 0) + (actor.system.adversite?.noire || 0); context.richesse = actor.computeRichesse?.() ?? { po: 0, pa: 0, sc: 0, valueSC: 0 }; context.valeurEquipement = actor.computeValeurEquipement?.() ?? { po: 0, pa: 0, sc: 0, valueSC: 0 }; // Prepare sorcellerie linked actors for display context.creaturesInvoqueesActors = await this._getLinkedActors(actor.system.sorcellerie.creaturesinvoquees); context.demonsLiesActors = await this._getLinkedActors(actor.system.sorcellerie.demonslies); context.enchantementsActors = await this._getLinkedActors(actor.system.sorcellerie.enchantements); // Prepare enriched HTML for sorcellerie fields context.enrichedInvocationsEnCours = await foundry.applications.ux.TextEditor.implementation.enrichHTML( actor.system.sorcellerie?.invocationsencours || "", { async: true } ); return context; } /** * Get actor objects from UUID references * @param {string[]} uuids - Array of actor UUIDs * @returns {Promise} Array of actor documents */ async _getLinkedActors(uuids) { if (!uuids || !Array.isArray(uuids) || uuids.length === 0) return []; const actors = []; for (const uuid of uuids) { const actor = await fromUuid(uuid); if (actor) { actors.push(actor); } } return actors; } /** * Handle actor drop on the sheet * @override */ async _onDropActor(event, data) { if (!this.document.isOwner) return; const droppedActor = await Actor.fromDropData(data); if (!droppedActor) return; // Only allow dropping Creature type actors if (droppedActor.type !== 'creature') return; // Determine which list to add to based on creature subtype let fieldPath = ''; const subType = droppedActor.system.soustype || 'creature'; switch (subType) { case 'demon': fieldPath = 'system.sorcellerie.demonslies'; break; case 'automata': fieldPath = 'system.sorcellerie.enchantements'; break; case 'creature': default: fieldPath = 'system.sorcellerie.creaturesinvoquees'; break; } // Add the actor UUID to the appropriate array const currentValue = foundry.utils.getProperty(this.document.system, fieldPath) || []; // Avoid duplicates if (!currentValue.includes(droppedActor.uuid)) { currentValue.push(droppedActor.uuid); await this.document.update({ [fieldPath]: currentValue }); } this.render(); } /** * Handle removal of a linked actor from sorcellerie sections * @param {Event} event - The click event * @param {HTMLElement} target - The clicked element */ static async #onRemoveLinkedActor(event, target) { const li = target.closest(".item"); if (!li) return; const field = target.dataset.field; const uuid = target.dataset.uuid; if (!field || !uuid) return; const fieldPath = `system.sorcellerie.${field}`; const currentValue = foundry.utils.getProperty(this.document.system, fieldPath) || []; // Remove the UUID from the array const newValue = currentValue.filter(u => u !== uuid); await this.document.update({ [fieldPath]: newValue }); this.render(); } /** * Handle click on linked actor name to open its sheet * @param {Event} event - The click event */ static async #onOpenLinkedActor(event) { const target = event.target.closest(".linked-actor-name"); if (!target) return; const uuid = target.dataset.actorUuid; if (!uuid) return; const actor = await fromUuid(uuid); if (actor) { actor.sheet.render(true); } } /** @override */ _onRender(context, options) { super._onRender(context, options); // Add click handler for linked actor names this.element.querySelectorAll('.linked-actor-name').forEach(el => { el.addEventListener('click', (event) => { event.preventDefault(); this.constructor.#onOpenLinkedActor(event); }); }); } }