/** * Feuille de personnage Te Deum - AppV2 */ import { TeDeumUtility } from "../common/tedeum-utility.js"; const { HandlebarsApplicationMixin } = foundry.applications.api /* -------------------------------------------- */ export class TeDeumActorPJSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) { constructor(options = {}) { super(options) this._sheetMode = this.constructor.SHEET_MODES.PLAY } static SHEET_MODES = { EDIT: 0, PLAY: 1 } /** @override */ static DEFAULT_OPTIONS = { classes: ["fvtt-te-deum", "sheet", "actor"], position: { width: 860, height: 680, }, form: { submitOnChange: true, closeOnSubmit: false, }, window: { resizable: true, }, dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }], actions: { editImage: TeDeumActorPJSheet.#onEditImage, toggleSheet: TeDeumActorPJSheet.#onToggleSheet, editItem: TeDeumActorPJSheet.#onEditItem, deleteItem: TeDeumActorPJSheet.#onDeleteItem, createItem: TeDeumActorPJSheet.#onCreateItem, createBlessure: TeDeumActorPJSheet.#onCreateBlessure, createCompetence: TeDeumActorPJSheet.#onCreateCompetence, equipItem: TeDeumActorPJSheet.#onEquipItem, modifyQuantity: TeDeumActorPJSheet.#onModifyQuantity, rollCompetence: TeDeumActorPJSheet.#onRollCompetence, rollArme: TeDeumActorPJSheet.#onRollArme, rollDegats: TeDeumActorPJSheet.#onRollDegats, }, } /** @override */ static PARTS = { sheet: { template: "systems/fvtt-te-deum/templates/actors/actor-sheet.hbs", }, } tabGroups = { primary: "principal" } get isEditMode() { return this._sheetMode === this.constructor.SHEET_MODES.EDIT } get isPlayMode() { return this._sheetMode === this.constructor.SHEET_MODES.PLAY } /* -------------------------------------------- */ /** @override */ async _prepareContext() { const actor = this.document return { title: this.title, id: actor.id, type: actor.type, img: actor.img, name: actor.name, editable: this.isEditable, cssClass: this.isEditable ? "editable" : "locked", system: foundry.utils.duplicate(actor.system), systemFields: actor.system.schema.fields, limited: actor.limited, competences: actor.getCompetences(), config: foundry.utils.duplicate(game.system.tedeum.config), armes: actor.getArmes(), caracList: actor.prepareCaracteristiques(), providence: actor.prepareProvidence(), arbreCompetences: actor.prepareArbreCompetences(), equipements: actor.getEquipements(), simples: actor.getSimples(), armures: actor.getArmures(), graces: actor.getGraces(), blessures: actor.getBlessures(), maladies: actor.getMaladies(), poisons: actor.getPoisons(), combat: actor.prepareCombat(), bonusDegats: actor.getBonusDegats(), nbActions: actor.getNbActions(), initiative: actor.getInitiative(), pointsArmuresLourdes: actor.getNbArmures(), nbArmuresLourdes: actor.getNbArmuresLourdesActuel(), santeModifier: actor.getSanteModifier(), educations: actor.getEducations(), enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.description, { async: true }), enrichedEquipmentFree: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.equipmentfree, { async: true }), enrichedNotes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.notes, { async: true }), enrichedHistoire: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.histoire, { async: true }), owner: actor.isOwner, isEditMode: this.isEditMode, isPlayMode: this.isPlayMode, isGM: game.user.isGM, } } /* -------------------------------------------- */ /** @override */ _onRender(context, options) { super._onRender(context, options) // Tab navigation const nav = this.element.querySelector('nav.tabs[data-group]') if (nav) { const group = nav.dataset.group const activeTab = this.tabGroups[group] || "principal" nav.querySelectorAll('[data-tab]').forEach(link => { const tab = link.dataset.tab link.classList.toggle('active', tab === activeTab) link.addEventListener('click', event => { event.preventDefault() this.tabGroups[group] = tab this.render() }) }) this.element.querySelectorAll(`[data-group="${group}"][data-tab]`).forEach(content => { content.classList.toggle('active', content.dataset.tab === activeTab) }) } // Ignore Enter key in sheet inputs this.element.addEventListener('keydown', e => { if (e.keyCode === 13 && e.target.tagName !== 'TEXTAREA') e.preventDefault() }) } /* -------------------------------------------- */ // #region Static action handlers static async #onEditImage(event) { const fp = new FilePicker({ type: "image", current: this.document.img, callback: path => this.document.update({ img: path }), }) fp.browse() } static async #onToggleSheet(event) { this._sheetMode = this.isEditMode ? this.constructor.SHEET_MODES.PLAY : this.constructor.SHEET_MODES.EDIT this.render() } static async #onEditItem(event, target) { const li = target.closest("[data-item-id]") const item = this.actor.items.get(li?.dataset.itemId) if (item) item.sheet.render(true) } static async #onDeleteItem(event, target) { const li = target.closest("[data-item-id]") await TeDeumUtility.confirmDelete(this, li) } static async #onCreateItem(event, target) { const type = target.dataset.type await this.actor.createEmbeddedDocuments('Item', [{ name: "Nouveau " + type, type }], { renderSheet: true }) } static async #onCreateBlessure(event, target) { const type = target.dataset.type await this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvelle " + type, type, system: { typeBlessure: "estafilade", localisation: "corps", value: 0, appliquee: true, description: "" } }], { renderSheet: true }) } static async #onCreateCompetence(event, target) { const type = target.dataset.type const caracKey = target.dataset.caracKey await this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvelle " + type, type, system: { caracteristique: caracKey } }], { renderSheet: true }) } static async #onEquipItem(event, target) { const li = target.closest("[data-item-id]") if (!li?.dataset.itemId) return await this.actor.equipItem(li.dataset.itemId) } static async #onModifyQuantity(event, target) { const li = target.closest("[data-item-id]") if (!li?.dataset.itemId) return const item = this.actor.items.get(li.dataset.itemId) if (!item) return const delta = parseInt(target.dataset.qty) || 0 await this.actor.incDecQuantity(li.dataset.itemId, delta) } static async #onRollCompetence(event, target) { const li = target.closest("[data-item-id]") if (!li?.dataset.itemId) return await this.actor.rollCompetence(li.dataset.itemId) } static async #onRollArme(event, target) { const li = target.closest("[data-item-id]") if (!li?.dataset.itemId) return await this.actor.rollArme(li.dataset.itemId) } static async #onRollDegats(event, target) { const li = target.closest("[data-item-id]") if (!li?.dataset.itemId) return await this.actor.rollDegatsArme(li.dataset.itemId) } // #endregion }