import { MournbladeUtility } from "./mournblade-utility.js"; /** * Extend the basic ItemSheet with some very simple modifications * @extends {ItemSheet} */ export class MournbladeItemSheet extends ItemSheet { /** @override */ static get defaultOptions() { return mergeObject(super.defaultOptions, { classes: ["fvtt-mournblade", "sheet", "item"], template: "systems/fvtt-mournblade/templates/item-sheet.html", dragDrop: [{ dragSelector: null, dropSelector: null }], width: 620, height: 550 //tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description"}] }); } /* -------------------------------------------- */ _getHeaderButtons() { let buttons = super._getHeaderButtons(); // Add "Post to chat" button // We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry! buttons.unshift( { class: "post", icon: "fas fa-comment", onclick: ev => { } }) return buttons } /* -------------------------------------------- */ /** @override */ setPosition(options = {}) { const position = super.setPosition(options); const sheetBody = this.element.find(".sheet-body"); const bodyHeight = position.height - 192; sheetBody.css("height", bodyHeight); if (this.item.type.includes('weapon')) { position.width = 640; } return position; } /* -------------------------------------------- */ async getData() { const objectData = MournbladeUtility.data(this.object); let itemData = foundry.utils.deepClone(MournbladeUtility.templateData(this.object)); let formData = { title: this.title, id: this.id, type: objectData.type, img: objectData.img, name: objectData.name, editable: this.isEditable, cssClass: this.isEditable ? "editable" : "locked", optionsDiceList: MournbladeUtility.getOptionsDiceList(), optionsStatusList: MournbladeUtility.getOptionsStatusList(), data: itemData, limited: this.object.limited, options: this.options, owner: this.document.isOwner, mr: (this.object.type == 'specialisation'), isGM: game.user.isGM } this.options.editable = !(this.object.data.origin == "embeddedItem"); console.log("ITEM DATA", formData, this); return formData; } /* -------------------------------------------- */ _getHeaderButtons() { let buttons = super._getHeaderButtons(); buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.postItem() }); return buttons } /* -------------------------------------------- */ postItem() { let chatData = duplicate(MournbladeUtility.data(this.item)); if (this.actor) { chatData.actor = { id: this.actor.id }; } // Don't post any image for the item (which would leave a large gap) if the default image is used if (chatData.img.includes("/blank.png")) { chatData.img = null; } // JSON object for easy creation chatData.jsondata = JSON.stringify( { compendium: "postedItem", payload: chatData, }); renderTemplate('systems/fvtt-Mournblade-rpg/templates/post-item.html', chatData).then(html => { let chatOptions = MournbladeUtility.chatDataSetup(html); ChatMessage.create(chatOptions) }); } /* -------------------------------------------- */ async viewSubitem(ev) { let field = $(ev.currentTarget).data('type'); let idx = Number($(ev.currentTarget).data('index')); let itemData = this.object.data.data[field][idx]; if (itemData.name != 'None') { let spec = await Item.create(itemData, { temporary: true }); spec.data.origin = "embeddedItem"; new MournbladeItemSheet(spec).render(true); } } /* -------------------------------------------- */ async deleteSubitem(ev) { let field = $(ev.currentTarget).data('type'); let idx = Number($(ev.currentTarget).data('index')); let oldArray = this.object.data.data[field]; let itemData = this.object.data.data[field][idx]; if (itemData.name != 'None') { let newArray = []; for (var i = 0; i < oldArray.length; i++) { if (i != idx) { newArray.push(oldArray[i]); } } this.object.update({ [`data.${field}`]: newArray }); } } /* -------------------------------------------- */ async manageSpec() { let itemData = this.object.data.data.specialisation[0]; if (itemData.name != 'None') { let spec = await Item.create(itemData, { temporary: true }); spec.data.origin = "embeddedItem"; new MournbladeItemSheet(spec).render(true); } } /* -------------------------------------------- */ /** @override */ activateListeners(html) { super.activateListeners(html); // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; // Update Inventory Item html.find('.item-edit').click(ev => { const li = $(ev.currentTarget).parents(".item"); const item = this.object.options.actor.getOwnedItem(li.data("item-id")); item.sheet.render(true); }); html.find('.delete-spec').click(ev => { this.object.update({ "data.specialisation": [{ name: 'None' }] }); }); html.find('.delete-subitem').click(ev => { this.deleteSubitem(ev); }); html.find('.stat-choice-flag').click(ev => { let idx = $(ev.currentTarget).data("stat-idx"); let array = duplicate(this.object.data.data.statincreasechoice); array[Number(idx)].flag = !array[Number(idx)].flag; this.object.update({ "data.statincreasechoice": array }); }); // Update Inventory Item html.find('.item-delete').click(ev => { const li = $(ev.currentTarget).parents(".item"); let itemId = li.data("item-id"); let itemType = li.data("item-type"); }); html.find('.view-subitem').click(ev => { this.viewSubitem(ev); }); html.find('.view-spec').click(ev => { this.manageSpec(); }); } /* -------------------------------------------- */ async addAbility(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); console.log("ABB", event, item, dataItem) if (event.toElement.className == 'drop-abilities') { let abilityArray = duplicate(this.object.data.data.abilities); abilityArray.push(newItem); await this.object.update({ 'data.abilities': abilityArray }); } if (event.toElement.className == 'drop-optionnal-abilities') { let abilityArray = duplicate(this.object.data.data.optionnalabilities); abilityArray.push(newItem); await this.object.update({ 'data.optionnalabilities': abilityArray }); } } /* -------------------------------------------- */ async addRacePerk(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-race-perk') { let perkArray = duplicate(this.object.data.data.perks); perkArray.push(newItem); await this.object.update({ 'data.perks': perkArray }); } } /* -------------------------------------------- */ async addSpecialisation(item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); let specArray = [newItem]; await this.object.update({ 'data.specialisation': specArray }); } /* -------------------------------------------- */ async addRoleSpecialisation(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); console.log("Add spec", event, newItem); if (event.toElement.className == 'drop-spec1') { let specArray = duplicate(this.object.data.data.specialisationsplus1); specArray.push(newItem); await this.object.update({ 'data.specialisationsplus1': specArray }); } if (event.toElement.className == 'drop-spec2') { let specArray = duplicate(this.object.data.data.specincrease); specArray.push(newItem); await this.object.update({ 'data.specincrease': specArray }); } } /* -------------------------------------------- */ async addRolePerk(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); console.log("Add spec", event, newItem); if (event.toElement.className == 'drop-perk2') { let perkArray = duplicate(this.object.data.data.perks); perkArray.push(newItem); await this.object.update({ 'data.perks': perkArray }); } if (event.toElement.className == 'drop-specialperk1') { let perkArray = duplicate(this.object.data.data.specialperk); perkArray.push(newItem); await this.object.update({ 'data.specialperk': perkArray }); } } /* -------------------------------------------- */ async addPower(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-spec-power') { let powArray = duplicate(this.object.data.data.powers); powArray.push(newItem); await this.object.update({ 'data.powers': powArray }); } } /* -------------------------------------------- */ async addAbilityPower(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-ability-power') { let powArray = duplicate(this.object.data.data.powersgained); powArray.push(newItem); await this.object.update({ 'data.powersgained': powArray }); } } /* -------------------------------------------- */ async addAbilityEffect(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-ability-effect') { let powArray = duplicate(this.object.data.data.effectsgained); powArray.push(newItem); await this.object.update({ 'data.effectsgained': powArray }); } } /* -------------------------------------------- */ async addAbilitySpec(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-ability-spec') { let powArray = duplicate(this.object.data.data.specialisations); powArray.push(newItem); await this.object.update({ 'data.specialisations': powArray }); } } /* -------------------------------------------- */ async addAbilityWeaponArmor(event, item, dataItem) { let newItem = duplicate(item.data); newItem._id = randomID(dataItem.id.length); if (event.toElement.className == 'drop-ability-weapon') { let weaponArray = duplicate(this.object.data.data.attackgained); weaponArray.push(newItem); await this.object.update({ 'data.attackgained': weaponArray }); } if (event.toElement.className == 'drop-ability-armor') { let armorArray = duplicate(this.object.data.data.armorgained); armorArray.push(newItem); await this.object.update({ 'data.armorgained': armorArray }); } } /* -------------------------------------------- */ async addPerkSpecialisation(event, item, dataItem) { let newItem = duplicate(item.data); if (event.toElement.className == 'drop-spec-perk') { //console.log("PER SPEC", event) let key = event.toElement.dataset["key"]; if (key == 'affectedspec') { await this.object.update({ 'data.features.affectedspec.value': newItem.name }); } else { await this.object.update({ 'data.features.gainspecdice.value': newItem.name }); } } } /* -------------------------------------------- */ async addPerkEffect(event, item, dataItem) { let newItem = duplicate(item.data) if (event.toElement.className == 'drop-perk-effect') { let effectArray = duplicate(this.object.data.data.effectsgained) effectArray.push(newItem) await this.object.update({ 'data.effectsgained': effectArray }) } } /* -------------------------------------------- */ async addEffectPower(event, item, dataItem) { let newItem = duplicate(item.data) if (event.toElement.className == 'drop-power-effect') { let effectArray = duplicate(this.object.data.data.effectsgained) effectArray.push(newItem); await this.object.update({ 'data.effectsgained': effectArray }) } } /* -------------------------------------------- */ async addEffectSpec(event, item, dataItem) { let newItem = duplicate(item.data); if (event.toElement.className == 'drop-effect-spec') { let specArray = duplicate(this.object.data.data.recoveryrollspec); specArray.push(newItem); await this.object.update({ 'data.recoveryrollspec': specArray }); } if (event.toElement.className == 'drop-effect-specaffected') { let specArray = duplicate(this.object.data.data.specaffected); specArray.push(newItem); await this.object.update({ 'data.specaffected': specArray }); } } /* -------------------------------------------- */ async addEffectItem(event, item, dataItem) { let newItem = duplicate(item.data); if (event.toElement.className == 'drop-equipment-effect') { let effectArray = duplicate(this.object.data.data.effects); effectArray.push(newItem); await this.object.update({ 'data.effects': effectArray }); } } /* -------------------------------------------- */ async _onDrop(event) { if (this.object.type == 'weapon' || this.object.type == 'shield' || this.object.type == 'armor' || this.object.type == 'shield') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'effect') { return this.addEffectItem(event, item, dataItem); } } } if (this.object.type == 'power') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'effect') { return this.addEffectPower(event, item, dataItem); } } } if (this.object.type == 'effect') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'specialisation') { return this.addEffectSpec(event, item, dataItem); } } } if (this.object.type == 'race') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'ability') { return this.addAbility(event, item, dataItem); } if (item.data.type == 'perk') { return this.addRacePerk(event, item, dataItem); } } } if (this.object.type == 'perk') { let data = event.dataTransfer.getData('text/plain') if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem) if (item.data.type == 'specialisation') { return this.addPerkSpecialisation(event, item, dataItem) } if (item.data.type == 'effect') { return this.addPerkEffect(event, item, dataItem); } } } if (this.object.type == 'specialisation') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'power') { return this.addPower(event, item, dataItem); } } } if (this.object.type == 'ability') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'effect') { return this.addAbilityEffect(event, item, dataItem); } if (item.data.type == 'power') { return this.addAbilityPower(event, item, dataItem); } if (item.data.type == 'specialisation') { return this.addAbilitySpec(event, item, dataItem); } if (item.data.type == 'weapon' || item.data.type == 'armor') { return this.addAbilityWeaponArmor(event, item, dataItem); } } } if (this.object.type == 'role') { let data = event.dataTransfer.getData('text/plain'); if (data) { let dataItem = JSON.parse(data); let item = await MournbladeUtility.searchItem(dataItem); if (item.data.type == 'specialisation') { return this.addRoleSpecialisation(event, item, dataItem); } if (item.data.type == 'perk') { return this.addRolePerk(event, item, dataItem); } } } ui.notifications.warn("This item can not be dropped over another item"); } /* -------------------------------------------- */ get template() { let type = this.item.type; return `systems/fvtt-Mournblade-rpg/templates/item-${type}-sheet.html`; } /* -------------------------------------------- */ /** @override */ _updateObject(event, formData) { return this.object.update(formData); } }