Show notification when invalid item types are added to actors (#1807)

This commit is contained in:
Carlos Fernandez 2026-04-16 02:23:25 -04:00 committed by GitHub
parent 7d5cdeb09d
commit aa8771bf0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 41 additions and 25 deletions

View file

@ -213,6 +213,9 @@
"headerTitle": "Adversary Reaction Roll"
}
},
"Base": {
"CannotAddType": "Cannot add {itemType} items to {actorType} actors."
},
"Character": {
"advantageSources": {
"label": "Advantage Sources",

View file

@ -73,7 +73,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
.hideAttribution;
// Prepare inventory data
if (['party', 'character'].includes(this.document.type)) {
if (this.document.system.metadata.hasInventory) {
context.inventory = {
currencies: {},
weapons: this.document.itemTypes.weapon.sort((a, b) => a.sort - b.sort),
@ -283,11 +283,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
async _onDropItem(event, item) {
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
const originActor = item.actor;
if (
item.actor?.uuid === this.document.uuid ||
!originActor ||
!['character', 'party'].includes(this.document.type)
) {
if (!originActor || originActor.uuid === this.document.uuid || !this.document.system.metadata.hasInventory) {
return super._onDropItem(event, item);
}

View file

@ -31,11 +31,12 @@ export default class AncestrySheet extends DHHeritageSheet {
if (data.type === 'ActiveEffect') return super._onDrop(event);
const target = event.target.closest('fieldset.drop-section');
const typeField =
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
if (!typeField) {
super._onDrop(event);
if (target) {
const typeField =
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
if (!typeField) {
super._onDrop(event);
}
}
}
}

View file

@ -133,7 +133,7 @@ export default class DhpAdversary extends DhCreature {
}
isItemValid(source) {
return source.type === 'feature';
return super.isItemValid(source) || source.type === 'feature';
}
async _preUpdate(changes, options, user) {

View file

@ -107,7 +107,8 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
hasResistances: true,
hasAttribution: false,
hasLimitedView: true,
usesSize: false
usesSize: false,
hasInventory: false
};
}
@ -168,6 +169,11 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
/* -------------------------------------------- */
isItemValid(source) {
const inventoryTypes = ['weapon', 'armor', 'consumable', 'loot'];
return this.metadata.hasInventory && inventoryTypes.includes(source.type);
}
/**
* Obtain a data object used to evaluate any dice rolls associated with this Item Type
* @param {object} [options] - Options which modify the getRollData method.

View file

@ -18,7 +18,8 @@ export default class DhCharacter extends DhCreature {
label: 'TYPES.Actor.character',
type: 'character',
settingSheet: DHCharacterSettings,
isNPC: false
isNPC: false,
hasInventory: true
});
}
@ -429,6 +430,11 @@ export default class DhCharacter extends DhCreature {
return attack;
}
/* All items are valid on characters */
isItemValid() {
return true;
}
/** @inheritDoc */
isItemAvailable(item) {
if (!super.isItemAvailable(this)) return false;

View file

@ -118,10 +118,6 @@ export default class DhCompanion extends DhCreature {
return this.levelupChoicesLeft > 0;
}
isItemValid() {
return false;
}
prepareBaseData() {
super.prepareBaseData();
this.attack.roll.bonus = this.partner?.system?.spellcastModifier ?? 0;

View file

@ -56,7 +56,7 @@ export default class DhEnvironment extends BaseDataActor {
}
isItemValid(source) {
return source.type === 'feature';
return super.isItemValid(source) || source.type === 'feature';
}
_onUpdate(changes, options, userId) {

View file

@ -5,6 +5,13 @@ import GroupRollData from '../groupRollData.mjs';
import { GoldField } from '../fields/actorField.mjs';
export default class DhParty extends BaseDataActor {
/** @inheritdoc */
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
hasInventory: true
});
}
/**@inheritdoc */
static defineSchema() {
const fields = foundry.data.fields;
@ -29,10 +36,6 @@ export default class DhParty extends BaseDataActor {
/* -------------------------------------------- */
isItemValid(source) {
return ['weapon', 'armor', 'consumable', 'loot'].includes(source.type);
}
prepareBaseData() {
super.prepareBaseData();

View file

@ -31,8 +31,13 @@ export default class DHItem extends foundry.documents.Item {
static async createDocuments(sources, operation) {
// Ensure that items being created are valid to the actor its being added to
const actor = operation.parent;
sources = actor?.system?.isItemValid ? sources.filter(s => actor.system.isItemValid(s)) : sources;
return super.createDocuments(sources, operation);
const filtered = actor ? sources.filter(s => actor.system.isItemValid(s)) : sources;
if (actor && filtered.length === 0 && sources.length > 0) {
const itemType = _loc(`TYPES.Item.${sources[0].type}`);
const actorType = _loc(`TYPES.Actor.${actor.type}`);
ui.notifications.error('DAGGERHEART.ACTORS.Base.CannotAddType', { format: { itemType, actorType } });
}
return super.createDocuments(filtered, operation);
}
/* -------------------------------------------- */