import { M5Item } from "../items/M5Item"; import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType, M5RollTemplate } from "../M5Base"; export class M5ItemSheet extends ItemSheet { static get defaultOptions() { return mergeObject(super.defaultOptions, { width: 640, height: 480, classes: ["midgard5", "sheet", "item"], tabs: [ { navSelector: ".sheet-navigation", contentSelector: ".sheet-content", initial: "base_values", }, ], }); } get template() { //console.log("M5ItemSheet", this.item.data.type) const path = "systems/midgard5/templates/sheets/item"; return `${path}/${this.item.type}.hbs`; } override getData(options?: Partial): ItemSheet.Data | Promise> { const item = this.item as M5Item; return Promise.resolve(super.getData()).then((value) => { item.prepareDerivedData(); const context = value as any; // Use a safe clone of the item data for further operations. const itemData = context.item; // Retrieve the roll data for TinyMCE editors. context.rollData = {}; let actor = this.object?.parent ?? null; if (actor) { context.rollData = actor.getRollData(); } context.data = itemData.system; context.flags = itemData.flags; return context; }); } override activateListeners(html: JQuery) { super.activateListeners(html); html.find(".add-mod").on("click", async (event) => { const context = this.object; const mods = context.system.mods; const modIndex = Object.keys(mods).length; mods[modIndex.toString()] = { type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.ADD, value: 0, } as M5ItemMod; this.object.update({ data: { mods: mods, }, }); }); html.find(".mod-delete").on("click", async (event) => { let target = event.target.closest("[data-mod-id]") as HTMLElement; let modId = target ? target.dataset.modId : null; const context = this.item; delete context.system.mods[modId]; this.render(false); }); html.find(".roll-delete").on("click", async (event) => { let target = event.target.closest("[data-roll]") as HTMLElement; let rollIndex = target ? target.dataset.roll : null; const rolls = this.item.system.rolls.formulas; delete rolls[rollIndex]; this.render(false); }); html.find(".roll-create").on("click", async (event) => { const rolls = this.item.system.rolls.formulas; const indeces = Object.keys(rolls) .map((index) => parseInt(index)) .sort() .reverse(); const index = (indeces.find((index) => !!rolls[index.toString()]) ?? -1) + 1; console.log("roll-create", rolls, indeces, index); rolls[index.toString()] = { formula: "1d6", label: (game as Game).i18n.localize("midgard5.roll"), enabled: true, } as M5RollTemplate; this.item.update({ data: { rolls: { formulas: rolls, }, }, }); this.render(false); }); // Drag & Drop if (["item"].includes(this.object.type)) { const itemToItemAssociation = new DragDrop({ dragSelector: ".item", dropSelector: ".item-list", permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this), }, callbacks: { drop: this._onDropItem.bind(this) }, }); itemToItemAssociation.bind(html[0]); } } _canDragStart(selector) { console.log("M5ItemSheet._canDragStart", selector); return this.options.editable && this.object.isOwner; } _canDragDrop(selector) { console.log("M5ItemSheet._canDragDrop", selector); return true; } async _onDropItem(event) { let data; const obj = this.object; const li = event.currentTarget; try { data = JSON.parse(event.dataTransfer.getData("text/plain")); if (data.type !== "Item") return false; } catch (err) { return false; } // Case 1 - Import from a Compendium pack let itemObject; if (data.pack) { const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id); itemObject = compendiumObject.data; } // Case 2 - Import from World entity else { const originalItem = await (game as Game).items.get(data.id); itemObject = duplicate(originalItem); if (!itemObject) return; } if (itemObject.type === "mod") { let mods = obj?.system?.mods; if (!mods) mods = []; itemObject.id = randomID(); console.log("M5ItemSheet._onDropItem", itemObject); mods.push(itemObject); obj.update({ data: { mods: mods, }, }); } } async _onDragItemStart(event) {} }