From f29ab8bdaab286c635793f901f73819b000d1d34 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 5 Oct 2025 15:25:23 -0600 Subject: [PATCH] Add a prompt for equipping an item on drag and drop --- module/data/Item/Armour.mjs | 39 ++++++++++++------------ module/data/Item/Weapon.mjs | 61 +++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 35 deletions(-) diff --git a/module/data/Item/Armour.mjs b/module/data/Item/Armour.mjs index 726c929..a8ead74 100644 --- a/module/data/Item/Armour.mjs +++ b/module/data/Item/Armour.mjs @@ -4,12 +4,13 @@ import { localizer } from "../../utils/Localizer.mjs"; import { Logger } from "../../utils/Logger.mjs"; import { requiredInteger } from "../helpers.mjs"; +const { diffObject, getProperty, setProperty } = foundry.utils; +const { DialogV2 } = foundry.applications.api; const { fields } = foundry.data; -const { getProperty, diffObject, mergeObject } = foundry.utils; /** Used for Armour and Shields */ export class ArmourData extends CommonItemData { - // MARK: Schema + // #region Schema static defineSchema() { return { ...super.defineSchema(), @@ -39,20 +40,22 @@ export class ArmourData extends CommonItemData { }), }; }; - - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; + // #endregion Schema // #region Lifecycle + async _preCreate(item) { + if (this.parent.isEmbedded && this._canEquip()) { + const shouldEquip = await DialogV2.confirm({ + window: { title: `Equip Item?` }, + content: `Do you want to equip ${item.name}?`, + }); + if (shouldEquip) { + this.updateSource({ "equipped": true }); + }; + }; + }; + async _preUpdate(changes, options, user) { - // return false if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return }; // Ensure changes is a diffed object @@ -69,9 +72,7 @@ export class ArmourData extends CommonItemData { ); // Don't stop the update, but don't allow changing the equipped status - mergeObject(changes, { - "system.equipped": false, - }); + setProperty(changes, `system.equipped`, false); // Set a flag so that we can tell the sheet that it needs to rerender this.forceRerender = true; @@ -79,7 +80,9 @@ export class ArmourData extends CommonItemData { return valid; }; + // #endregion Lifecycle + // #region Helpers /** * Used to tell the preUpdate logic whether or not to prevent the item from * being equipped or not. @@ -106,11 +109,9 @@ export class ArmourData extends CommonItemData { }; return true; }; - // #endregion - // #region Getters get locationString() { return [...this.location].join(`, `); }; - // #endregion + // #endregion Helpers }; diff --git a/module/data/Item/Weapon.mjs b/module/data/Item/Weapon.mjs index a4b77ff..8d50f78 100644 --- a/module/data/Item/Weapon.mjs +++ b/module/data/Item/Weapon.mjs @@ -2,12 +2,14 @@ import { barAttribute, optionalInteger, requiredInteger } from "../helpers.mjs"; import { CommonItemData } from "./Common.mjs"; import { gameTerms } from "../../gameTerms.mjs"; import { localizer } from "../../utils/Localizer.mjs"; +import { Logger } from "../../utils/Logger.mjs"; +const { diffObject, getProperty, setProperty } = foundry.utils; +const { DialogV2 } = foundry.applications.api; const { fields } = foundry.data; -const { hasProperty, mergeObject } = foundry.utils; export class WeaponData extends CommonItemData { - // MARK: Schema + // #region Schema static defineSchema() { return { ...super.defineSchema(), @@ -41,18 +43,28 @@ export class WeaponData extends CommonItemData { }), }; }; - - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; + // #endregion Schema // #region Lifecycle + async _preCreate(item) { + if (this.parent.isEmbedded && this._canEquip()) { + const shouldEquip = await DialogV2.confirm({ + window: { title: `Equip Item?` }, + content: `Do you want to equip ${item.name}?`, + }); + if (shouldEquip) { + this.updateSource({ "equipped": true }); + }; + }; + }; + + /** + * + * @param {*} changes The expanded object that was used for the update + * @param {*} options + * @param {*} user + * @returns + */ async _preUpdate(changes, options, user) { if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return }; let valid = super._preUpdate(changes, options, user); @@ -71,9 +83,26 @@ export class WeaponData extends CommonItemData { }; return valid; }; - // #endregion + // #endregion Lifecycle + + // #region Helpers + /** + * Used to tell the preUpdate logic whether or not to prevent the item from + * being equipped or not. + */ + _canEquip() { + const parent = this.parent; + if (!parent.isEmbedded || !(parent.parent instanceof Actor)) { + Logger.error(`Unable to equip item when it's not embedded`); + return false; + }; + const actor = this.parent.parent.system; + if (actor.equippedWeapons?.length >= actor.limit.weapons) { + return false; + }; + return true; + }; - // #region Getters get traitString() { return [...this.traits].join(`, `); }; @@ -84,7 +113,7 @@ export class WeaponData extends CommonItemData { }; return String(this.range.short ?? this.range.long ?? ``); }; - // #endregion + // #endregion Helpers // #region Sheet Data async getFormFields(_ctx) { @@ -225,5 +254,5 @@ export class WeaponData extends CommonItemData { return fields; }; - // #endregion + // #endregion Sheet Data };