mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Feature] Item Resource Support (#328)
* Initial * Resource setup finished * Fixed so that costs can be used * Corrected standard resources * Actions can only use item resources from their parent item * Fixed up dice * Fixed resource dice positioning * Fixed parsing of resource.max * Fixed styling on settings tab * Added manual input for Dice Resources * Lightmode fixes * Fixed Feature spellcasting modifier * Bugfix for item input to resourceDiceDialog * Item fix for TokenInput * PR Fixes
This commit is contained in:
parent
eefa116d9a
commit
4be3e6179c
53 changed files with 972 additions and 329 deletions
|
|
@ -10,7 +10,6 @@ export default class DHArmor extends AttachableItem {
|
|||
label: 'TYPES.Item.armor',
|
||||
type: 'armor',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true,
|
||||
isInventoryItem: true
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export default class AttachableItem extends BaseDataItem {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
attached: new fields.ArrayField(new fields.DocumentUUIDField({ type: "Item", nullable: true }))
|
||||
attached: new fields.ArrayField(new fields.DocumentUUIDField({ type: 'Item', nullable: true }))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +90,10 @@ export default class AttachableItem extends BaseDataItem {
|
|||
});
|
||||
|
||||
if (effectsToRemove.length > 0) {
|
||||
await actor.deleteEmbeddedDocuments('ActiveEffect', effectsToRemove.map(e => e.id));
|
||||
await actor.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
effectsToRemove.map(e => e.id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,13 +143,18 @@ export default class AttachableItem extends BaseDataItem {
|
|||
const parentUuidProperty = `${parentType}Uuid`;
|
||||
const effectsToRemove = actor.effects.filter(effect => {
|
||||
const attachmentSource = effect.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.itemAttachmentSource);
|
||||
return attachmentSource &&
|
||||
return (
|
||||
attachmentSource &&
|
||||
attachmentSource[parentUuidProperty] === this.parent.uuid &&
|
||||
attachmentSource.itemUuid === attachedUuid;
|
||||
attachmentSource.itemUuid === attachedUuid
|
||||
);
|
||||
});
|
||||
|
||||
if (effectsToRemove.length > 0) {
|
||||
await actor.deleteEmbeddedDocuments('ActiveEffect', effectsToRemove.map(e => e.id));
|
||||
await actor.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
effectsToRemove.map(e => e.id)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,15 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ITEMS'];
|
||||
|
||||
/** @returns {ItemDataModelMetadata}*/
|
||||
static get metadata() {
|
||||
return {
|
||||
label: 'Base Item',
|
||||
type: 'base',
|
||||
hasDescription: false,
|
||||
hasResource: false,
|
||||
isQuantifiable: false,
|
||||
isInventoryItem: false
|
||||
};
|
||||
|
|
@ -33,6 +36,33 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
|
||||
if (this.metadata.hasDescription) schema.description = new fields.HTMLField({ required: true, nullable: true });
|
||||
|
||||
if (this.metadata.hasResource) {
|
||||
schema.resource = new fields.SchemaField(
|
||||
{
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.ITEM.itemResourceTypes,
|
||||
initial: CONFIG.DH.ITEM.itemResourceTypes.simple
|
||||
}),
|
||||
value: new fields.NumberField({ integer: true, min: 0, initial: 0 }),
|
||||
max: new fields.StringField({ nullable: true, initial: null }),
|
||||
icon: new fields.StringField(),
|
||||
recovery: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.refreshTypes,
|
||||
initial: null,
|
||||
nullable: true
|
||||
}),
|
||||
diceStates: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ integer: true, nullable: true, initial: null }),
|
||||
used: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
),
|
||||
dieFaces: new fields.StringField({ initial: '4' })
|
||||
},
|
||||
{ nullable: true, initial: null }
|
||||
);
|
||||
}
|
||||
|
||||
if (this.metadata.isQuantifiable)
|
||||
schema.quantity = new fields.NumberField({ integer: true, initial: 1, min: 0, required: true });
|
||||
|
||||
|
|
@ -62,28 +92,27 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
return data;
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _preCreate(data, options, user) {
|
||||
// Skip if no initial action is required or actions already exist
|
||||
if (!this.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
|
||||
if (this.metadata.hasInitialAction && foundry.utils.isEmpty(this.actions)) {
|
||||
const metadataType = this.metadata.type;
|
||||
const actionType = { weapon: 'attack' }[metadataType];
|
||||
const ActionClass = game.system.api.models.actions.actionsTypes[actionType];
|
||||
|
||||
const metadataType = this.metadata.type;
|
||||
const actionType = { weapon: 'attack' }[metadataType];
|
||||
const ActionClass = game.system.api.models.actions.actionsTypes[actionType];
|
||||
const action = new ActionClass(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
type: actionType,
|
||||
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||
...ActionClass.getSourceConfig(this.parent)
|
||||
},
|
||||
{
|
||||
parent: this.parent
|
||||
}
|
||||
);
|
||||
|
||||
const action = new ActionClass(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
type: actionType,
|
||||
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||
...ActionClass.getSourceConfig(this.parent)
|
||||
},
|
||||
{
|
||||
parent: this.parent
|
||||
}
|
||||
);
|
||||
|
||||
this.updateSource({ actions: [action] });
|
||||
this.updateSource({ actions: [action] });
|
||||
}
|
||||
}
|
||||
|
||||
_onCreate(data) {
|
||||
|
|
@ -95,7 +124,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
...feature,
|
||||
system: {
|
||||
...feature.system,
|
||||
type: this.parent.type,
|
||||
originItemType: this.parent.type,
|
||||
originId: data._id,
|
||||
identifier: feature.identifier
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ export default class DHDomainCard extends BaseDataItem {
|
|||
return foundry.utils.mergeObject(super.metadata, {
|
||||
label: 'TYPES.Item.domainCard',
|
||||
type: 'domainCard',
|
||||
hasDescription: true
|
||||
hasDescription: true,
|
||||
hasResource: true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ export default class DHFeature extends BaseDataItem {
|
|||
return foundry.utils.mergeObject(super.metadata, {
|
||||
label: 'TYPES.Item.feature',
|
||||
type: 'feature',
|
||||
hasDescription: true
|
||||
hasDescription: true,
|
||||
hasResource: true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -16,10 +17,32 @@ export default class DHFeature extends BaseDataItem {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
type: new fields.StringField({ choices: CONFIG.DH.ITEM.featureTypes, nullable: true, initial: null }),
|
||||
originItemType: new fields.StringField({
|
||||
choices: CONFIG.DH.ITEM.featureTypes,
|
||||
nullable: true,
|
||||
initial: null
|
||||
}),
|
||||
originId: new fields.StringField({ nullable: true, initial: null }),
|
||||
identifier: new fields.StringField(),
|
||||
actions: new fields.ArrayField(new ActionField())
|
||||
};
|
||||
}
|
||||
|
||||
get spellcastingModifier() {
|
||||
let traitValue = 0;
|
||||
if (this.actor && this.originId && ['class', 'subclass'].includes(this.originItemType)) {
|
||||
if (this.originItemType === 'subclass') {
|
||||
traitValue =
|
||||
this.actor.system.traits[this.actor.items.get(this.originId).system.spellcastingTrait]?.value ?? 0;
|
||||
} else {
|
||||
const subclass =
|
||||
this.actor.system.multiclass.value?.id === this.originId
|
||||
? this.actor.system.multiclass.subclass
|
||||
: this.actor.system.class.subclass;
|
||||
traitValue = this.actor.system.traits[subclass.system.spellcastingTrait]?.value ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
return traitValue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ export default class DHWeapon extends AttachableItem {
|
|||
label: 'TYPES.Item.weapon',
|
||||
type: 'weapon',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true,
|
||||
isInventoryItem: true
|
||||
// hasInitialAction: true
|
||||
});
|
||||
|
|
@ -37,7 +36,7 @@ export default class DHWeapon extends AttachableItem {
|
|||
actionIds: new fields.ArrayField(new fields.StringField({ required: true }))
|
||||
})
|
||||
),
|
||||
attack: new ActionField({
|
||||
attack: new ActionField({
|
||||
initial: {
|
||||
name: 'Attack',
|
||||
img: 'icons/skills/melee/blood-slash-foam-red.webp',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue