RC-110 | Prevent Armour/Shield Equipping based on slots
This commit is contained in:
parent
b33d7b59eb
commit
4ccfc03e59
6 changed files with 94 additions and 18 deletions
|
|
@ -135,7 +135,7 @@
|
|||
},
|
||||
"notifs": {
|
||||
"error": {
|
||||
"cannot-equip-not-embedded": "Cannot equip an {itemType} when it isn't within an Actor",
|
||||
"cannot-equip": "Cannot equip the {itemType}, see console for more details.",
|
||||
"invalid-delta": "The delta for \"{name}\" is not a number, cannot finish processing the action."
|
||||
},
|
||||
"warn": {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,27 @@ export class AllItemSheetV1 extends GenericAppMixin(HandlebarsApplicationMixin(I
|
|||
Logger.debug(`Context:`, ctx);
|
||||
return ctx;
|
||||
};
|
||||
|
||||
async _onRender() {
|
||||
// remove the flag if it exists when we render the sheet
|
||||
delete this.document?.system?.forceRerender;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to make it so that items that don't get updated because of the
|
||||
* _preUpdate hook removing/changing the data submitted, can still get
|
||||
* re-rendered when the diff is empty. If the document does get updated,
|
||||
* this rerendering does not happen.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
async _processSubmitData(...args) {
|
||||
await super._processSubmitData(...args);
|
||||
|
||||
if (this.document.system.forceRerender) {
|
||||
await this.render(false);
|
||||
};
|
||||
};
|
||||
// #endregion
|
||||
|
||||
// #region Actions
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import { CommonItemData } from "./Common.mjs";
|
||||
import { gameTerms } from "../../gameTerms.mjs";
|
||||
import { localizer } from "../../utils/Localizer.mjs";
|
||||
import { Logger } from "../../utils/Logger.mjs";
|
||||
import { requiredInteger } from "../helpers.mjs";
|
||||
|
||||
const { fields } = foundry.data;
|
||||
const { hasProperty, mergeObject } = foundry.utils;
|
||||
const { hasProperty, diffObject, mergeObject } = foundry.utils;
|
||||
|
||||
/** Used for Armour and Shields */
|
||||
export class ProtectorData extends CommonItemData {
|
||||
export class ArmourData extends CommonItemData {
|
||||
// MARK: Schema
|
||||
static defineSchema() {
|
||||
return {
|
||||
|
|
@ -45,22 +46,56 @@ export class ProtectorData extends CommonItemData {
|
|||
|
||||
// #region Lifecycle
|
||||
async _preUpdate(changes, options, user) {
|
||||
// return false
|
||||
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`,
|
||||
// Ensure changes is a diffed object
|
||||
const diff = diffObject(this.parent._source, changes);
|
||||
let valid = await super._preUpdate(changes, options, user);
|
||||
|
||||
if (hasProperty(diff, `system.equipped`) && !this._canEquip()) {
|
||||
ui.notifications.error(
|
||||
localizer(
|
||||
`RipCrypt.notifs.error.cannot-equip`,
|
||||
{ itemType: `@TYPES.Item.${this.parent.type}` },
|
||||
));
|
||||
mergeObject(
|
||||
changes,
|
||||
{ "-=system.equipped": null },
|
||||
{ inplace: true, performDeletions: true },
|
||||
),
|
||||
{ console: false },
|
||||
);
|
||||
|
||||
// Don't stop the update, but don't allow changing the equipped status
|
||||
mergeObject(changes, {
|
||||
"system.equipped": false,
|
||||
});
|
||||
|
||||
// Set a flag so that we can tell the sheet that it needs to rerender
|
||||
this.forceRerender = true;
|
||||
};
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
||||
/** Used to tell the preUpdate logic whether or not to prevent the */
|
||||
_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;
|
||||
};
|
||||
return valid;
|
||||
|
||||
if (this.location.size === 0) {
|
||||
Logger.error(`Unable to equip an item without any locations`);
|
||||
return false;
|
||||
};
|
||||
|
||||
const slots = parent.parent.system.equippedArmour ?? {};
|
||||
Logger.debug(`slots`, slots);
|
||||
for (const locationTag of this.location) {
|
||||
if (slots[locationTag.toLowerCase()] != null) {
|
||||
Logger.error(`Unable to equip multiple items in the same slot`);
|
||||
return false;
|
||||
};
|
||||
};
|
||||
return true;
|
||||
};
|
||||
// #endregion
|
||||
|
||||
19
module/data/Item/Shield.mjs
Normal file
19
module/data/Item/Shield.mjs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { ArmourData } from "./Armour.mjs";
|
||||
import { Logger } from "../../utils/Logger.mjs";
|
||||
|
||||
export class ShieldData extends ArmourData {
|
||||
_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 shield = parent.parent.system.equippedShield;
|
||||
if (shield) {
|
||||
Logger.error(`Unable to equip multiple shields`);
|
||||
return false;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@ export class RipCryptItem extends Item {
|
|||
get quantifiedName() {
|
||||
if (this.system.quantity != null && this.system.quantity !== 1) {
|
||||
return `${this.name} (${this.system.quantity})`;
|
||||
}
|
||||
};
|
||||
return this.name;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ import { RipCryptCombatTracker } from "../Apps/sidebar/CombatTracker.mjs";
|
|||
|
||||
// Data Models
|
||||
import { AmmoData } from "../data/Item/Ammo.mjs";
|
||||
import { ArmourData } from "../data/Item/Armour.mjs";
|
||||
import { CraftData } from "../data/Item/Craft.mjs";
|
||||
import { GoodData } from "../data/Item/Good.mjs";
|
||||
import { HeroData } from "../data/Actor/Hero.mjs";
|
||||
import { ProtectorData } from "../data/Item/Protector.mjs";
|
||||
import { ShieldData } from "../data/Item/Shield.mjs";
|
||||
import { SkillData } from "../data/Item/Skill.mjs";
|
||||
import { WeaponData } from "../data/Item/Weapon.mjs";
|
||||
|
||||
|
|
@ -49,10 +50,10 @@ Hooks.once(`init`, () => {
|
|||
// #region Datamodels
|
||||
CONFIG.Actor.dataModels.hero = HeroData;
|
||||
CONFIG.Item.dataModels.ammo = AmmoData,
|
||||
CONFIG.Item.dataModels.armour = ProtectorData;
|
||||
CONFIG.Item.dataModels.armour = ArmourData;
|
||||
CONFIG.Item.dataModels.craft = CraftData;
|
||||
CONFIG.Item.dataModels.good = GoodData;
|
||||
CONFIG.Item.dataModels.shield = ProtectorData;
|
||||
CONFIG.Item.dataModels.shield = ShieldData;
|
||||
CONFIG.Item.dataModels.skill = SkillData;
|
||||
CONFIG.Item.dataModels.weapon = WeaponData;
|
||||
// #endregion
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue