From 16c46e964930acc0a9b556afc43a630601b6be6a Mon Sep 17 00:00:00 2001 From: Oliver-Akins Date: Tue, 28 Jan 2025 22:14:11 -0700 Subject: [PATCH] RC-111 | Prevent Items from being equipped when not embedded --- langs/en-ca.json | 1 + module/data/Item/Protector.mjs | 23 +++++++++++++++++++++++ module/data/Item/Weapon.mjs | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/langs/en-ca.json b/langs/en-ca.json index 89d1be0..09b5bc8 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -116,6 +116,7 @@ }, "notifs": { "error": { + "cannot-equip-not-embedded": "Cannot equip an {itemType} when it isn't within an Actor", "invalid-delta": "The delta for \"{name}\" is not a number, cannot finish processing the action." }, "warn": { diff --git a/module/data/Item/Protector.mjs b/module/data/Item/Protector.mjs index 96e04f3..871c79e 100644 --- a/module/data/Item/Protector.mjs +++ b/module/data/Item/Protector.mjs @@ -1,8 +1,10 @@ import { CommonItemData } from "./Common.mjs"; import { gameTerms } from "../../gameTerms.mjs"; +import { localizer } from "../../utils/Localizer.mjs"; import { requiredInteger } from "../helpers.mjs"; const { fields } = foundry.data; +const { hasProperty, mergeObject } = foundry.utils; /** Used for Armour and Shields */ export class ProtectorData extends CommonItemData { @@ -41,6 +43,27 @@ export class ProtectorData extends CommonItemData { super.prepareDerivedData(); }; + // #region Lifecycle + async _preUpdate(changes, options, user) { + if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return }; + let valid = super._preUpdate(changes, options, user); + + if (hasProperty(changes, `system.equipped`) && !this.parent.isEmbedded) { + ui.notifications.error(localizer( + `RipCrypt.notifs.error.cannot-equip-not-embedded`, + { itemType: `@TYPES.Item.${this.parent.type}` }, + )); + mergeObject( + changes, + { "-=system.equipped": null }, + { inplace: true, performDeletions: true }, + ); + return false; + }; + return valid; + }; + // #endregion + // #region Getters get locationString() { return [...this.location].join(`, `); diff --git a/module/data/Item/Weapon.mjs b/module/data/Item/Weapon.mjs index 3292069..91c28ec 100644 --- a/module/data/Item/Weapon.mjs +++ b/module/data/Item/Weapon.mjs @@ -1,8 +1,10 @@ import { barAttribute, optionalInteger, requiredInteger } from "../helpers.mjs"; import { CommonItemData } from "./Common.mjs"; import { gameTerms } from "../../gameTerms.mjs"; +import { localizer } from "../../utils/Localizer.mjs"; const { fields } = foundry.data; +const { hasProperty, mergeObject } = foundry.utils; export class WeaponData extends CommonItemData { // MARK: Schema @@ -50,6 +52,27 @@ export class WeaponData extends CommonItemData { super.prepareDerivedData(); }; + // #region Lifecycle + async _preUpdate(changes, options, user) { + if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return }; + let valid = super._preUpdate(changes, options, user); + + if (hasProperty(changes, `system.equipped`) && !this.parent.isEmbedded) { + ui.notifications.error(localizer( + `RipCrypt.notifs.error.cannot-equip-not-embedded`, + { itemType: `@TYPES.Item.${this.parent.type}` }, + )); + mergeObject( + changes, + { "-=system.equipped": null }, + { inplace: true, performDeletions: true }, + ); + return false; + }; + return valid; + }; + // #endregion + // #region Getters get traitString() { return [...this.traits].join(`, `);