Merge pull request #59 from Eldritch-Oliver/feature/prompt-equip-on-drop
Add a prompt when you drag and drop an item onto an actor that asks you if you want to equip the item automatically
This commit is contained in:
commit
cc917878c3
8 changed files with 114 additions and 53 deletions
14
augments.d.ts
vendored
Normal file
14
augments.d.ts
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
declare global {
|
||||||
|
class Hooks extends foundry.helpers.Hooks {};
|
||||||
|
const fromUuid = foundry.utils.fromUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Actor {
|
||||||
|
/** The system-specific data */
|
||||||
|
system: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
/** The system-specific data */
|
||||||
|
system: any;
|
||||||
|
};
|
||||||
|
|
@ -4,7 +4,7 @@ import stylistic from "@stylistic/eslint-plugin";
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
// Tell eslint to ignore files that I don't mind being formatted slightly differently
|
// Tell eslint to ignore files that I don't mind being formatted slightly differently
|
||||||
{ ignores: [ `scripts/` ] },
|
{ ignores: [ `scripts/`, `foundry/` ] },
|
||||||
{
|
{
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: globals.browser,
|
globals: globals.browser,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "ES2020",
|
"module": "es2022",
|
||||||
"target": "ES2020"
|
"target": "es2022",
|
||||||
|
"types": [
|
||||||
|
"./augments.d.ts"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@client/*": ["./foundry/client/*"],
|
||||||
|
"@common/*": ["./foundry/common/*"],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "**/node_modules/*"],
|
"include": [
|
||||||
"include": ["module/**/*", "foundry.v13.link/client/**/*.js", "foundry.v13.link/**/*.mjs"],
|
"module/**/*",
|
||||||
"typeAcquisition": {
|
"foundry/client/client.mjs",
|
||||||
"include": ["jquery"]
|
"foundry/client/global.d.mts",
|
||||||
}
|
"foundry/common/primitives/global.d.mts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ export class AllItemSheetV1 extends GenericAppMixin(HandlebarsApplicationMixin(I
|
||||||
await super._processSubmitData(...args);
|
await super._processSubmitData(...args);
|
||||||
|
|
||||||
if (this.document.system.forceRerender) {
|
if (this.document.system.forceRerender) {
|
||||||
await this.render(false);
|
await this.render();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export class ArmourSheet extends GenericAppMixin(HandlebarsApplicationMixin(Item
|
||||||
await super._processSubmitData(...args);
|
await super._processSubmitData(...args);
|
||||||
|
|
||||||
if (this.document.system.forceRerender) {
|
if (this.document.system.forceRerender) {
|
||||||
await this.render(false);
|
await this.render();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,11 @@ export class EntityData extends foundry.abstract.TypeDataModel {
|
||||||
};
|
};
|
||||||
|
|
||||||
// #region Getters
|
// #region Getters
|
||||||
|
get equippedWeapons() {
|
||||||
|
const weapons = this.parent.itemTypes.weapon;
|
||||||
|
return weapons.filter(w => w.system.equipped);
|
||||||
|
};
|
||||||
|
|
||||||
get equippedArmour() {
|
get equippedArmour() {
|
||||||
const armours = this.parent.itemTypes.armour;
|
const armours = this.parent.itemTypes.armour;
|
||||||
const slots = Object.fromEntries(
|
const slots = Object.fromEntries(
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,13 @@ import { localizer } from "../../utils/Localizer.mjs";
|
||||||
import { Logger } from "../../utils/Logger.mjs";
|
import { Logger } from "../../utils/Logger.mjs";
|
||||||
import { requiredInteger } from "../helpers.mjs";
|
import { requiredInteger } from "../helpers.mjs";
|
||||||
|
|
||||||
|
const { diffObject, getProperty, setProperty } = foundry.utils;
|
||||||
|
const { DialogV2 } = foundry.applications.api;
|
||||||
const { fields } = foundry.data;
|
const { fields } = foundry.data;
|
||||||
const { getProperty, diffObject, mergeObject } = foundry.utils;
|
|
||||||
|
|
||||||
/** Used for Armour and Shields */
|
/** Used for Armour and Shields */
|
||||||
export class ArmourData extends CommonItemData {
|
export class ArmourData extends CommonItemData {
|
||||||
// MARK: Schema
|
// #region Schema
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
|
|
@ -39,20 +40,23 @@ export class ArmourData extends CommonItemData {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
// #endregion Schema
|
||||||
// MARK: Base Data
|
|
||||||
prepareBaseData() {
|
|
||||||
super.prepareBaseData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// MARK: Derived Data
|
|
||||||
prepareDerivedData() {
|
|
||||||
super.prepareDerivedData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Lifecycle
|
// #region Lifecycle
|
||||||
|
async _preCreate(item, options) {
|
||||||
|
const showEquipPrompt = options.showEquipPrompt ?? true;
|
||||||
|
if (showEquipPrompt && 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) {
|
async _preUpdate(changes, options, user) {
|
||||||
// return false
|
|
||||||
if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return };
|
if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return };
|
||||||
|
|
||||||
// Ensure changes is a diffed object
|
// Ensure changes is a diffed object
|
||||||
|
|
@ -69,9 +73,7 @@ export class ArmourData extends CommonItemData {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Don't stop the update, but don't allow changing the equipped status
|
// Don't stop the update, but don't allow changing the equipped status
|
||||||
mergeObject(changes, {
|
setProperty(changes, `system.equipped`, false);
|
||||||
"system.equipped": false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set a flag so that we can tell the sheet that it needs to rerender
|
// Set a flag so that we can tell the sheet that it needs to rerender
|
||||||
this.forceRerender = true;
|
this.forceRerender = true;
|
||||||
|
|
@ -79,7 +81,9 @@ export class ArmourData extends CommonItemData {
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
};
|
};
|
||||||
|
// #endregion Lifecycle
|
||||||
|
|
||||||
|
// #region Helpers
|
||||||
/**
|
/**
|
||||||
* Used to tell the preUpdate logic whether or not to prevent the item from
|
* Used to tell the preUpdate logic whether or not to prevent the item from
|
||||||
* being equipped or not.
|
* being equipped or not.
|
||||||
|
|
@ -106,11 +110,9 @@ export class ArmourData extends CommonItemData {
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region Getters
|
|
||||||
get locationString() {
|
get locationString() {
|
||||||
return [...this.location].join(`, `);
|
return [...this.location].join(`, `);
|
||||||
};
|
};
|
||||||
// #endregion
|
// #endregion Helpers
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,14 @@ import { barAttribute, optionalInteger, requiredInteger } from "../helpers.mjs";
|
||||||
import { CommonItemData } from "./Common.mjs";
|
import { CommonItemData } from "./Common.mjs";
|
||||||
import { gameTerms } from "../../gameTerms.mjs";
|
import { gameTerms } from "../../gameTerms.mjs";
|
||||||
import { localizer } from "../../utils/Localizer.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 { fields } = foundry.data;
|
||||||
const { hasProperty, mergeObject } = foundry.utils;
|
|
||||||
|
|
||||||
export class WeaponData extends CommonItemData {
|
export class WeaponData extends CommonItemData {
|
||||||
// MARK: Schema
|
// #region Schema
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
|
|
@ -41,39 +43,69 @@ export class WeaponData extends CommonItemData {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
// #endregion Schema
|
||||||
// MARK: Base Data
|
|
||||||
prepareBaseData() {
|
|
||||||
super.prepareBaseData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// MARK: Derived Data
|
|
||||||
prepareDerivedData() {
|
|
||||||
super.prepareDerivedData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Lifecycle
|
// #region Lifecycle
|
||||||
|
async _preCreate(item, options) {
|
||||||
|
const showEquipPrompt = options.showEquipPrompt ?? true;
|
||||||
|
if (showEquipPrompt && 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) {
|
async _preUpdate(changes, options, user) {
|
||||||
if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return };
|
if (options.force && game.settings.get(`ripcrypt`, `devMode`)) { return };
|
||||||
|
|
||||||
|
const diff = diffObject(this.parent._source, changes);
|
||||||
let valid = super._preUpdate(changes, options, user);
|
let valid = super._preUpdate(changes, options, user);
|
||||||
|
|
||||||
if (hasProperty(changes, `system.equipped`) && !this.parent.isEmbedded) {
|
if (getProperty(diff, `system.equipped`) && !this._canEquip()) {
|
||||||
ui.notifications.error(localizer(
|
ui.notifications.error(localizer(
|
||||||
`RipCrypt.notifs.error.cannot-equip-not-embedded`,
|
`RipCrypt.notifs.error.cannot-equip`,
|
||||||
{ itemType: `@TYPES.Item.${this.parent.type}` },
|
{ itemType: `@TYPES.Item.${this.parent.type}` },
|
||||||
));
|
));
|
||||||
mergeObject(
|
|
||||||
changes,
|
// Don't stop the update, but don't allow changing the equipped status
|
||||||
{ "-=system.equipped": null },
|
setProperty(changes, `system.equipped`, false);
|
||||||
{ inplace: true, performDeletions: true },
|
|
||||||
);
|
// Set a flag so that we can tell the sheet that it needs to rerender
|
||||||
return false;
|
this.forceRerender = true;
|
||||||
};
|
};
|
||||||
return valid;
|
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() {
|
get traitString() {
|
||||||
return [...this.traits].join(`, `);
|
return [...this.traits].join(`, `);
|
||||||
};
|
};
|
||||||
|
|
@ -84,7 +116,7 @@ export class WeaponData extends CommonItemData {
|
||||||
};
|
};
|
||||||
return String(this.range.short ?? this.range.long ?? ``);
|
return String(this.range.short ?? this.range.long ?? ``);
|
||||||
};
|
};
|
||||||
// #endregion
|
// #endregion Helpers
|
||||||
|
|
||||||
// #region Sheet Data
|
// #region Sheet Data
|
||||||
async getFormFields(_ctx) {
|
async getFormFields(_ctx) {
|
||||||
|
|
@ -225,5 +257,5 @@ export class WeaponData extends CommonItemData {
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
};
|
};
|
||||||
// #endregion
|
// #endregion Sheet Data
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue