Files
fvtt-donjon-et-cie/modules/applications/sheets/base-actor-sheet.mjs

238 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Donjon & Cie - Systeme FoundryVTT
*
* Donjon & Cie est un jeu de role edite par John Doe.
* Ce systeme FoundryVTT est une implementation independante et n'est pas
* affilie a John Doe.
*
* @author LeRatierBretonnien
* @copyright 20252026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
const { HandlebarsApplicationMixin } = foundry.applications.api;
export default class DonjonEtCieActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
static DEFAULT_OPTIONS = {
classes: ["fvtt-donjon-et-cie", "sheet", "actor"],
position: { width: 920, height: 820 },
form: {
submitOnChange: true,
closeOnSubmit: false
},
window: {
resizable: true
},
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: ".item-dropzone" }],
actions: {
editImage: DonjonEtCieActorSheet.#onEditImage,
setTab: DonjonEtCieActorSheet.#onSetTab,
createItem: DonjonEtCieActorSheet.#onCreateItem,
editItem: DonjonEtCieActorSheet.#onEditItem,
deleteItem: DonjonEtCieActorSheet.#onDeleteItem,
rollHitDice: DonjonEtCieActorSheet.#onRollHitDice,
rollInitiative: DonjonEtCieActorSheet.#onRollInitiative,
rollCharacteristic: DonjonEtCieActorSheet.#onRollCharacteristic,
rollWeapon: DonjonEtCieActorSheet.#onRollWeapon,
rollDamage: DonjonEtCieActorSheet.#onRollDamage,
rollSpell: DonjonEtCieActorSheet.#onRollSpell,
rollUsage: DonjonEtCieActorSheet.#onRollUsage,
useFavorService: DonjonEtCieActorSheet.#onUseFavorService,
postItem: DonjonEtCieActorSheet.#onPostItem,
adjustCounter: DonjonEtCieActorSheet.#onAdjustCounter
}
};
async _prepareContext() {
const actor = this.document;
return {
actor,
system: actor.system,
source: actor.toObject(),
config: game.system.donjonEtCie.config,
characteristics: actor.getCharacteristicEntries(),
sections: actor.getSectionData(),
fields: actor.schema.fields,
systemFields: actor.system.schema.fields,
activeTab: this._activeTab ?? "combat"
};
}
_onRender(context, options) {
super._onRender(context, options);
this.#fixWindowShell();
this._applyActiveTab();
}
#fixWindowShell() {
const app = this.element?.matches?.(".application") ? this.element : this.element?.closest(".application");
const content = app?.querySelector(":scope > .window-content") ?? app?.querySelector(".window-content");
const header = app?.querySelector(".window-header");
if (app) {
app.style.display = "flex";
app.style.flexDirection = "column";
app.style.paddingTop = "0";
app.style.overflow = "hidden";
}
if (header) {
header.style.width = "100%";
header.style.flex = "0 0 auto";
header.style.position = "relative";
header.style.zIndex = "3";
}
if (content) {
content.style.width = "100%";
content.style.flex = "1 1 auto";
content.style.minHeight = "0";
content.style.overflowY = "auto";
content.style.overflowX = "hidden";
}
}
_canDragStart() {
return this.isEditable;
}
_canDragDrop() {
return this.isEditable;
}
_onDragStart(event) {
const itemElement = event.currentTarget.closest(".item");
if (!itemElement) return;
const itemId = itemElement.dataset.itemId;
const item = this.document.items.get(itemId);
if (!item) return;
event.dataTransfer.setData("text/plain", JSON.stringify({ type: "Item", uuid: item.uuid }));
}
_onDragOver(event) {
const dropTarget = event.target.closest(".item-section");
this.#setDropTarget(dropTarget);
}
async _onDrop(event) {
this.#setDropTarget(null);
return super._onDrop(event);
}
#setDropTarget(target) {
this.element.querySelectorAll(".item-section.is-dragover").forEach((section) => section.classList.remove("is-dragover"));
if (target instanceof HTMLElement) {
target.classList.add("is-dragover");
}
}
_applyActiveTab() {
const activeTab = this._activeTab ?? "combat";
this.element.querySelectorAll("[data-tab-button]").forEach((button) => {
const isActive = button.dataset.tab === activeTab;
button.classList.toggle("active", isActive);
button.setAttribute("aria-pressed", isActive ? "true" : "false");
});
this.element.querySelectorAll("[data-tab-panel]").forEach((panel) => {
const isActive = panel.dataset.tabPanel === activeTab;
panel.classList.toggle("active", isActive);
panel.toggleAttribute("hidden", !isActive);
});
}
static async #onEditImage(event) {
event.preventDefault();
const picker = new FilePicker({
type: "image",
current: this.document.img,
callback: (path) => this.document.update({ img: path })
});
return picker.browse();
}
static async #onCreateItem(event, target) {
event.preventDefault();
const type = target.dataset.type;
if (!type) return;
return this.document.createEmbeddedDocuments("Item", [{ name: `Nouveau ${type}`, type }], { renderSheet: true });
}
static async #onSetTab(event, target) {
event.preventDefault();
const tab = target.dataset.tab;
if (!tab) return;
this._activeTab = tab;
this._applyActiveTab();
}
static async #onEditItem(event, target) {
event.preventDefault();
const item = this.document.items.get(target.closest("[data-item-id]")?.dataset.itemId);
return item?.sheet.render(true);
}
static async #onDeleteItem(event, target) {
event.preventDefault();
const itemId = target.closest("[data-item-id]")?.dataset.itemId;
if (!itemId) return;
return this.document.deleteEmbeddedDocuments("Item", [itemId]);
}
static async #onRollCharacteristic(event, target) {
event.preventDefault();
return this.document.rollCharacteristic(target.dataset.characteristic);
}
static async #onRollInitiative(event) {
event.preventDefault();
return this.document.rollInitiative();
}
static async #onRollHitDice(event) {
event.preventDefault();
return this.document.rollHitDice();
}
static async #onRollWeapon(event, target) {
event.preventDefault();
return this.document.rollWeapon(target.closest("[data-item-id]")?.dataset.itemId);
}
static async #onRollDamage(event, target) {
event.preventDefault();
return this.document.rollDamage(target.closest("[data-item-id]")?.dataset.itemId);
}
static async #onRollSpell(event, target) {
event.preventDefault();
return this.document.rollSpell(target.closest("[data-item-id]")?.dataset.itemId);
}
static async #onRollUsage(event, target) {
event.preventDefault();
return this.document.rollUsage(target.closest("[data-item-id]")?.dataset.itemId);
}
static async #onUseFavorService(event, target) {
event.preventDefault();
return this.document.useFavorService(target.dataset.department);
}
static async #onPostItem(event, target) {
event.preventDefault();
const item = this.document.items.get(target.closest("[data-item-id]")?.dataset.itemId);
return item?.postToChat();
}
static async #onAdjustCounter(event, target) {
event.preventDefault();
const path = target.dataset.path;
const delta = Number(target.dataset.delta ?? 0);
if (!path || Number.isNaN(delta)) return;
return this.document.adjustNumericField(path, delta);
}
}