diff --git a/module/data/action.mjs b/module/data/action.mjs index 48adfb21..2c110202 100755 --- a/module/data/action.mjs +++ b/module/data/action.mjs @@ -2,9 +2,8 @@ export default class DaggerheartAction extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { - id: new fields.StringField({}), + id: new fields.DocumentIdField(), name: new fields.StringField({ initial: 'New Action' }), - img: new fields.StringField({ initial: '' }), damage: new fields.SchemaField({ type: new fields.StringField({ choices: SYSTEM.GENERAL.damageTypes, nullable: true, initial: null }), value: new fields.StringField({}) @@ -30,15 +29,6 @@ export default class DaggerheartAction extends foundry.abstract.DataModel { initial: SYSTEM.ACTIONS.targetTypes.other.id }) }) - // uses: new fields.SchemaField({ - // nr: new fields.StringField({}), - // refreshType: new fields.StringField({ choices: SYSTEM.GENERAL.refreshTypes, initial: SYSTEM.GENERAL.refreshTypes.session.id }), - // refreshed: new fields.BooleanField({ initial: true }), - // }), }; } - - use = async () => { - console.log('Test Use'); - }; } diff --git a/module/data/fields/_module.mjs b/module/data/fields/_module.mjs index 42c901fc..41436d4f 100644 --- a/module/data/fields/_module.mjs +++ b/module/data/fields/_module.mjs @@ -1,2 +1,2 @@ export { default as FormulaField } from "./formulaField.mjs"; -export {default as ForeignDocumentUUIDField} from "./foreignDocumentUUIDField.mjs"; \ No newline at end of file +export { default as ForeignDocumentUUIDField } from "./foreignDocumentUUIDField.mjs"; \ No newline at end of file diff --git a/module/data/fields/foreignDocumentUUIDField.mjs b/module/data/fields/foreignDocumentUUIDField.mjs index dc34769e..13bbc80d 100644 --- a/module/data/fields/foreignDocumentUUIDField.mjs +++ b/module/data/fields/foreignDocumentUUIDField.mjs @@ -3,6 +3,15 @@ * that resolves to either the document, the index(for items in compenidums) or the UUID string. */ export default class ForeignDocumentUUIDField extends foundry.data.fields.DocumentUUIDField { + +/** + * @param {foundry.data.types.DocumentUUIDFieldOptions} [options] Options which configure the behavior of the field + * @param {foundry.data.types.DataFieldContext} [context] Additional context which describes the field + */ + constructor(options, context) { + super(options, context); + } + /** @inheritdoc */ static get _defaults() { return foundry.utils.mergeObject(super._defaults, { @@ -25,6 +34,7 @@ export default class ForeignDocumentUUIDField extends foundry.data.fields.Docume } }; } + /**@override */ toObject(value) { return value?.uuid ?? value; diff --git a/module/data/fields/formulaField.mjs b/module/data/fields/formulaField.mjs index ee9a7f2d..82717740 100644 --- a/module/data/fields/formulaField.mjs +++ b/module/data/fields/formulaField.mjs @@ -1,16 +1,30 @@ /** - * @typedef {StringFieldOptions} FormulaFieldOptions - * @property {boolean} [deterministic=false] Is this formula not allowed to have dice values? + * @typedef {foundry.data.types.StringFieldOptions} StringFieldOptions + * @typedef {foundry.data.types.DataFieldContext} DataFieldContext + */ + +/** + * @typedef _FormulaFieldOptions + * @property {boolean} [deterministic] - Is this formula not allowed to have dice values? + */ + +/** + * @typedef {StringFieldOptions & _FormulaFieldOptions} FormulaFieldOptions */ /** * Special case StringField which represents a formula. - * - * @param {FormulaFieldOptions} [options={}] Options which configure the behavior of the field. - * @property {boolean} deterministic=false Is this formula not allowed to have dice values? */ export default class FormulaField extends foundry.data.fields.StringField { + /** + * @param {FormulaFieldOptions} [options] - Options which configure the behavior of the field + * @param {foundry.data.types.DataFieldContext} [context] - Additional context which describes the field + */ + constructor(options, context) { + super(options, context); + } + /** @inheritDoc */ static get _defaults() { return foundry.utils.mergeObject(super._defaults, { @@ -24,7 +38,7 @@ export default class FormulaField extends foundry.data.fields.StringField { _validateType(value) { const roll = new Roll(value.replace(/@([a-z.0-9_-]+)/gi, "1")); roll.evaluateSync({ strict: false }); - if ( this.options.deterministic && !roll.isDeterministic ) throw new Error(`must not contain dice terms: ${value}`); + if (this.options.deterministic && !roll.isDeterministic) throw new Error(`must not contain dice terms: ${value}`); super._validateType(value); } @@ -41,7 +55,7 @@ export default class FormulaField extends foundry.data.fields.StringField { /** @override */ _applyChangeAdd(value, delta, model, change) { - if ( !value ) return delta; + if (!value) return delta; const operator = delta.startsWith("-") ? "-" : "+"; delta = delta.replace(/^[+-]/, "").trim(); return `${value} ${operator} ${delta}`; @@ -51,9 +65,9 @@ export default class FormulaField extends foundry.data.fields.StringField { /** @override */ _applyChangeMultiply(value, delta, model, change) { - if ( !value ) return delta; + if (!value) return delta; const terms = new Roll(value).terms; - if ( terms.length > 1 ) return `(${value}) * ${delta}`; + if (terms.length > 1) return `(${value}) * ${delta}`; return `${value} * ${delta}`; } @@ -61,9 +75,9 @@ export default class FormulaField extends foundry.data.fields.StringField { /** @override */ _applyChangeUpgrade(value, delta, model, change) { - if ( !value ) return delta; + if (!value) return delta; const terms = new Roll(value).terms; - if ( (terms.length === 1) && (terms[0].fn === "max") ) return value.replace(/\)$/, `, ${delta})`); + if ((terms.length === 1) && (terms[0].fn === "max")) return value.replace(/\)$/, `, ${delta})`); return `max(${value}, ${delta})`; } @@ -71,9 +85,9 @@ export default class FormulaField extends foundry.data.fields.StringField { /** @override */ _applyChangeDowngrade(value, delta, model, change) { - if ( !value ) return delta; + if (!value) return delta; const terms = new Roll(value).terms; - if ( (terms.length === 1) && (terms[0].fn === "min") ) return value.replace(/\)$/, `, ${delta})`); + if ((terms.length === 1) && (terms[0].fn === "min")) return value.replace(/\)$/, `, ${delta})`); return `min(${value}, ${delta})`; } -} +} \ No newline at end of file diff --git a/module/data/item/ancestry.mjs b/module/data/item/ancestry.mjs index f9d0b4f1..0359e9fc 100644 --- a/module/data/item/ancestry.mjs +++ b/module/data/item/ancestry.mjs @@ -15,7 +15,7 @@ export default class DHAncestry extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - //use ForeignDocumentUUIDField for Abilities + //TODO: add features field }; } } diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index f23aef2f..e8137340 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -33,28 +33,4 @@ export default class DHArmor extends BaseDataItem { get featureInfo() { return this.feature ? CONFIG.daggerheart.ITEM.armorFeatures[this.feature] : null; } - - /* --------------------------------------------- */ - - /** @inheritDoc */ - prepareDerivedData() { - if (this.parent.parent) { - this.applyLevels(); - } - } - - // Currently bugged as it double triggers. Should get fixed in an updated foundry version. - applyLevels() { - // let armorBonus = 0; - // for(var level in this.parent.parent.system.levelData.levelups){ - // var levelData = this.parent.parent.system.levelData.levelups[level]; - // for(var tier in levelData){ - // var tierData = levelData[tier]; - // if(tierData){ - // armorBonus += Object.keys(tierData.armorOrEvasionSlot).filter(x => tierData.armorOrEvasionSlot[x] === 'armor').length; - // } - // } - // } - // this.marks.max += armorBonus; - } } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index c7815ccd..8605a48e 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -1,7 +1,8 @@ /** * Describes metadata about the item data model type * @typedef {Object} ItemDataModelMetadata - * @property {string} type - The system type that this data model represents (e.g., "weapon", "armor", "consumable") + * @property {string} label - A localizable label used on application. + * @property {string} type - The system type that this data model represents. * @property {boolean} hasDescription - Indicates whether items of this type have description field * @property {boolean} isQuantifiable - Indicates whether items of this type have quantity field */ @@ -33,12 +34,20 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { } /** - * Obtain a data object used to evaluate any dice rolls associated with this Item - * @param {object} [options] + * Convenient access to the item's actor, if it exists. + * @returns {foundry.documents.Actor | null} + */ + get actor() { + return this.parent.actor; + } + + /** + * Obtain a data object used to evaluate any dice rolls associated with this Item Type + * @param {object} [options] - Options which modify the getRollData method. * @returns {object} */ getRollData(options = {}) { - const actorRollData = this.parent.actor?.getRollData() ?? {}; + const actorRollData = this.actor?.getRollData() ?? {}; const data = { ...actorRollData, item: { ...this } }; return data; } diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index 29a22ba3..8d9d62e9 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -19,27 +19,15 @@ export default class DHClass extends BaseDataItem { ...super.defineSchema(), domains: new fields.ArrayField(new fields.StringField(), { max: 2 }), - classItems: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item" }), - ), + classItems: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item" })), evasion: new fields.NumberField({ initial: 0, integer: true }), - features: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item" }), - ), + features: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item" })), - subclasses: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item", required: false, nullable: true, initial: undefined}), - ), + subclasses: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item", required: false, nullable: true, initial: undefined })), inventory: new fields.SchemaField({ - take: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item", required: false, nullable: true, initial: undefined}), - ), - choiceA: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item", required: false, nullable: true, initial: undefined}), - ), - choiceB: new fields.ArrayField( - new ForeignDocumentUUIDField({ type:"Item", required: false, nullable: true, initial: undefined}), - ), + take: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item", required: false, nullable: true, initial: undefined })), + choiceA: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item", required: false, nullable: true, initial: undefined })), + choiceB: new fields.ArrayField(new ForeignDocumentUUIDField({ type: "Item", required: false, nullable: true, initial: undefined })), }), characterGuide: new fields.SchemaField({ suggestedTraits: new fields.SchemaField({ @@ -50,15 +38,15 @@ export default class DHClass extends BaseDataItem { presence: new fields.NumberField({ initial: 0, integer: true }), knowledge: new fields.NumberField({ initial: 0, integer: true }) }), - suggestedPrimaryWeapon: new ForeignDocumentUUIDField({ type:"Item" }), - suggestedSecondaryWeapon: new ForeignDocumentUUIDField({ type:"Item" }), - suggestedArmor: new ForeignDocumentUUIDField({ type:"Item" }), + suggestedPrimaryWeapon: new ForeignDocumentUUIDField({ type: "Item" }), + suggestedSecondaryWeapon: new ForeignDocumentUUIDField({ type: "Item" }), + suggestedArmor: new ForeignDocumentUUIDField({ type: "Item" }), }), multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true }), }; } - get multiclassTier() { + get multiclassTier() { return getTier(this.multiclass, true); } } diff --git a/module/data/item/community.mjs b/module/data/item/community.mjs index 693b73b5..ffa6f921 100644 --- a/module/data/item/community.mjs +++ b/module/data/item/community.mjs @@ -16,7 +16,7 @@ export default class DHCommunity extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - //use ForeignDocumentUUIDField for Abilities + //TODO: add features field }; } } diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index cb22cfec..6986708f 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -16,16 +16,10 @@ export default class DHDomainCard extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - domain: new fields.StringField( - { choices: SYSTEM.DOMAIN.domains}, - { required: true, initial: [] } - ), + domain: new fields.StringField({ choices: SYSTEM.DOMAIN.domains, required: true, blank: true }), level: new fields.NumberField({ initial: 1, integer: true }), recallCost: new fields.NumberField({ initial: 0, integer: true }), - type: new fields.StringField( - { choices: SYSTEM.DOMAIN.cardTypes}, - { required: true, initial: [] } - ), + type: new fields.StringField({ choices: SYSTEM.DOMAIN.cardTypes, required: true, blank: true}), foundation: new fields.BooleanField({ initial: false }), inVault: new fields.BooleanField({ initial: false }), actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction)) diff --git a/module/data/item/feature.mjs b/module/data/item/feature.mjs index ceed1f47..b14c98da 100644 --- a/module/data/item/feature.mjs +++ b/module/data/item/feature.mjs @@ -17,11 +17,16 @@ export default class DHFeature extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), + + //A type of feature seems unnecessary type: new fields.StringField({ choices: SYSTEM.ITEM.featureTypes }), + + //TODO: remove actionType field actionType: new fields.StringField({ choices: SYSTEM.ITEM.actionTypes, initial: SYSTEM.ITEM.actionTypes.passive.id }), + //TODO: remove featureType field featureType: new fields.SchemaField({ type: new fields.StringField({ choices: SYSTEM.ITEM.valueTypes, @@ -46,12 +51,16 @@ export default class DHFeature extends BaseDataItem { { type: new fields.StringField({ choices: SYSTEM.GENERAL.refreshTypes }), uses: new fields.NumberField({ initial: 1, integer: true }), + //TODO: remove refreshed field refreshed: new fields.BooleanField({ initial: true }) }, { nullable: true, initial: null } ), + //TODO: remove refreshed field multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true }), disabled: new fields.BooleanField({ initial: false }), + + //TODO: re do it completely or just remove it effects: new fields.TypedObjectField( new fields.SchemaField({ type: new fields.StringField({ choices: SYSTEM.EFFECTS.effectTypes }), diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 5265aa97..b3c82e52 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -24,7 +24,6 @@ export default class DHWeapon extends BaseDataItem { trait: new fields.StringField({ required: true, choices: SYSTEM.ACTOR.abilities, initial: 'agility' }), range: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.range, initial: 'melee' }), burden: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.burden, initial: 'oneHanded' }), - //DAMAGE damage: new fields.SchemaField({ value: new FormulaField({ initial: 'd6' }), @@ -38,31 +37,4 @@ export default class DHWeapon extends BaseDataItem { feature: new fields.StringField({ choices: SYSTEM.ITEM.weaponFeatures, blank: true }), }; } - - prepareDerivedData() { - if (this.parent.parent) { - this.applyEffects(); - } - } - - applyEffects() { - const effects = this.parent.parent.system.effects; - for (const key in effects) { - console.log - const effectType = effects[key]; - for (const effect of effectType) { - switch (key) { - case SYSTEM.EFFECTS.effectTypes.reach.id: - if ( - SYSTEM.GENERAL.range[this.range].distance < - SYSTEM.GENERAL.range[effect.valueData.value].distance - ) { - this.range = effect.valueData.value; - } - - break; - } - } - } - } } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 837b5564..955c2c27 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -12,6 +12,26 @@ export default class DhpItem extends Item { } } + /** + * @inheritdoc + * @param {object} options - Options which modify the getRollData method. + * @returns + */ + getRollData(options = {}) { + let data; + if (this.system.getRollData) data = this.system.getRollData(options); + else { + const actorRollData = this.actor?.getRollData(options) ?? {}; + data = { ...actorRollData, item: { ...this.system } }; + } + + if (data?.item) { + data.item.flags = { ...this.flags }; + data.item.name = this.name; + } + return data; + } + isInventoryItem() { return ['weapon', 'armor', 'miscellaneous', 'consumable'].includes(this.type); }