mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 16:09:03 +01:00
Initial
This commit is contained in:
parent
42a705a870
commit
f614456e86
10 changed files with 68 additions and 90 deletions
|
|
@ -1661,8 +1661,6 @@
|
||||||
"unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters",
|
"unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters",
|
||||||
"featureNotHope": "This feature is used as something else than a Hope feature and cannot be used here.",
|
"featureNotHope": "This feature is used as something else than a Hope feature and cannot be used here.",
|
||||||
"featureNotClass": "This feature is used as something else than a Class feature and cannot be used here.",
|
"featureNotClass": "This feature is used as something else than a Class feature and cannot be used here.",
|
||||||
"featureNotPrimary": "This feature is used as something else than a Primary feature and cannot be used here.",
|
|
||||||
"featureNotSecondary": "This feature is used as something else than a Secondary feature and cannot be used here.",
|
|
||||||
"featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.",
|
"featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.",
|
||||||
"featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.",
|
"featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.",
|
||||||
"featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here.",
|
"featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here.",
|
||||||
|
|
|
||||||
|
|
@ -179,9 +179,9 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
const { type } = target.dataset;
|
const { type } = target.dataset;
|
||||||
const cls = foundry.documents.Item.implementation;
|
const cls = foundry.documents.Item.implementation;
|
||||||
const feature = await cls.create({
|
const feature = await cls.create({
|
||||||
'type': 'feature',
|
type: 'feature',
|
||||||
'name': cls.defaultName({ type: 'feature' }),
|
name: cls.defaultName({ type: 'feature' }),
|
||||||
'system.subType': CONFIG.DH.ITEM.featureSubTypes[type]
|
[`system.itemLinks.["${this.document.uuid}"]`]: CONFIG.DH.ITEM.featureSubTypes[type]
|
||||||
});
|
});
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.features': [...this.document.system.features, feature].map(f => f.uuid)
|
'system.features': [...this.document.system.features, feature].map(f => f.uuid)
|
||||||
|
|
@ -195,7 +195,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
static async #deleteFeature(_, target) {
|
static async #deleteFeature(_, target) {
|
||||||
const feature = getDocFromElement(target);
|
const feature = getDocFromElement(target);
|
||||||
if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||||
await feature.update({ 'system.subType': null });
|
await feature.update({ [`system.itemLinks.-=${this.document.uuid}`]: null });
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.features': this.document.system.features.map(x => x.uuid).filter(uuid => uuid !== feature.uuid)
|
'system.features': this.document.system.features.map(x => x.uuid).filter(uuid => uuid !== feature.uuid)
|
||||||
});
|
});
|
||||||
|
|
@ -272,6 +272,9 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
|
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (item?.type === 'feature') {
|
if (item?.type === 'feature') {
|
||||||
|
const { type } = target.dataset;
|
||||||
|
await item.update({ [`system.itemLinks.${this.document.uuid}`]: CONFIG.DH.ITEM.featureSubTypes[type] });
|
||||||
|
|
||||||
const current = this.document.system.features.map(x => x.uuid);
|
const current = this.document.system.features.map(x => x.uuid);
|
||||||
await this.document.update({ 'system.features': [...current, item.uuid] });
|
await this.document.update({ 'system.features': [...current, item.uuid] });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,7 @@ import DHHeritageSheet from '../api/heritage-sheet.mjs';
|
||||||
export default class AncestrySheet extends DHHeritageSheet {
|
export default class AncestrySheet extends DHHeritageSheet {
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
classes: ['ancestry'],
|
classes: ['ancestry']
|
||||||
actions: {
|
|
||||||
editFeature: AncestrySheet.#editFeature,
|
|
||||||
removeFeature: AncestrySheet.#removeFeature
|
|
||||||
},
|
|
||||||
dragDrop: [{ dragSelector: null, dropSelector: '.tab.features .drop-section' }]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
|
|
@ -17,66 +12,4 @@ export default class AncestrySheet extends DHHeritageSheet {
|
||||||
...super.PARTS,
|
...super.PARTS,
|
||||||
features: { template: 'systems/daggerheart/templates/sheets/items/ancestry/features.hbs' }
|
features: { template: 'systems/daggerheart/templates/sheets/items/ancestry/features.hbs' }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/* Application Clicks Actions */
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edit an existing feature on the item
|
|
||||||
* @type {ApplicationClickAction}
|
|
||||||
*/
|
|
||||||
static async #editFeature(_event, button) {
|
|
||||||
const target = button.closest('.feature-item');
|
|
||||||
const feature = this.document.system[`${target.dataset.type}Feature`];
|
|
||||||
if (!feature || Object.keys(feature).length === 0) {
|
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
feature.sheet.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a feature from the item.
|
|
||||||
* @type {ApplicationClickAction}
|
|
||||||
*/
|
|
||||||
static async #removeFeature(event, button) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const target = button.closest('.feature-item');
|
|
||||||
const feature = this.document.system[`${target.dataset.type}Feature`];
|
|
||||||
|
|
||||||
if (feature) await feature.update({ 'system.subType': null });
|
|
||||||
await this.document.update({
|
|
||||||
'system.features': this.document.system.features.filter(x => x && x.uuid !== feature.uuid).map(x => x.uuid)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/* Application Drag/Drop */
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On drop on the item.
|
|
||||||
* @param {DragEvent} event - The drag event
|
|
||||||
*/
|
|
||||||
async _onDrop(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
|
||||||
|
|
||||||
const item = await fromUuid(data.uuid);
|
|
||||||
if (item?.type === 'feature') {
|
|
||||||
const subType = event.target.closest('.primary-feature') ? 'primary' : 'secondary';
|
|
||||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes[subType]) {
|
|
||||||
const error = subType === 'primary' ? 'featureNotPrimary' : 'featureNotSecondary';
|
|
||||||
ui.notifications.warn(game.i18n.localize(`DAGGERHEART.UI.Notifications.${error}`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await item.update({ 'system.subType': subType });
|
|
||||||
await this.document.update({
|
|
||||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
export { default as FormulaField } from './formulaField.mjs';
|
export { default as FormulaField } from './formulaField.mjs';
|
||||||
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
||||||
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
||||||
|
export { default as ItemLinksField } from './itemLinksField.mjs';
|
||||||
|
|
|
||||||
32
module/data/fields/itemLinksField.mjs
Normal file
32
module/data/fields/itemLinksField.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
export default class ItemLinksField extends foundry.data.fields.TypedObjectField {
|
||||||
|
/**
|
||||||
|
* @param {DataFieldOptions} [options] Options which configure the behavior of the field.
|
||||||
|
* @param {DataFieldContext} [context] Additional context which describes the field
|
||||||
|
*/
|
||||||
|
constructor(options, context) {
|
||||||
|
super(
|
||||||
|
new foundry.data.fields.StringField({
|
||||||
|
choices: CONFIG.DH.ITEM.featureSubTypes,
|
||||||
|
nullable: true,
|
||||||
|
initial: null
|
||||||
|
}),
|
||||||
|
options,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
static get _defaults() {
|
||||||
|
return mergeObject(super._defaults, { validateKey: this.validateKey });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} [value] The candidate object to be added.
|
||||||
|
*/
|
||||||
|
static validateKey(value) {
|
||||||
|
return true;
|
||||||
|
const parsed = foundry.utils.parseUuid(value);
|
||||||
|
if (!parsed || parsed.type !== CONFIG.Item.documentClass.documentName) return false;
|
||||||
|
if (!foundry.packages.BasePackage.validateId(parsed.documentId)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,18 +20,10 @@ export default class DHAncestry extends BaseDataItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
get primaryFeature() {
|
get primaryFeature() {
|
||||||
return (
|
return this.features.find(x => x.system.itemLinks[this.parent.id] === CONFIG.DH.ITEM.featureSubTypes.primary);
|
||||||
this.features.find(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.primary) ??
|
|
||||||
(this.features.filter(x => !x).length > 0 ? {} : null)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get secondaryFeature() {
|
get secondaryFeature() {
|
||||||
return (
|
return this.features.find(x => x.system.itemLinks[this.parent.id] === CONFIG.DH.ITEM.featureSubTypes.secondary);
|
||||||
this.features.find(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.secondary) ??
|
|
||||||
(this.features.filter(x => !x || x.system.subType === CONFIG.DH.ITEM.featureSubTypes.primary).length > 1
|
|
||||||
? {}
|
|
||||||
: null)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ItemLinksField from '../fields/itemLinksField.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
|
|
@ -21,7 +23,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
hasDescription: false,
|
hasDescription: false,
|
||||||
hasResource: false,
|
hasResource: false,
|
||||||
isQuantifiable: false,
|
isQuantifiable: false,
|
||||||
isInventoryItem: false
|
isInventoryItem: false,
|
||||||
|
isItemLinkable: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,6 +72,10 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
if (this.metadata.isQuantifiable)
|
if (this.metadata.isQuantifiable)
|
||||||
schema.quantity = new fields.NumberField({ integer: true, initial: 1, min: 0, required: true });
|
schema.quantity = new fields.NumberField({ integer: true, initial: 1, min: 0, required: true });
|
||||||
|
|
||||||
|
if (this.metadata.isItemLinkable) {
|
||||||
|
schema.itemLinks = new ItemLinksField();
|
||||||
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ export default class DHFeature extends BaseDataItem {
|
||||||
label: 'TYPES.Item.feature',
|
label: 'TYPES.Item.feature',
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
hasDescription: true,
|
hasDescription: true,
|
||||||
hasResource: true
|
hasResource: true,
|
||||||
|
isItemLinkable: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,17 @@
|
||||||
* @extends {foundry.documents.Item}
|
* @extends {foundry.documents.Item}
|
||||||
*/
|
*/
|
||||||
export default class DHItem extends foundry.documents.Item {
|
export default class DHItem extends foundry.documents.Item {
|
||||||
|
/**@inheritdoc */
|
||||||
|
static async create(data, operation = {}) {
|
||||||
|
if (data.type === 'feature') {
|
||||||
|
const linkUuid = Object.keys(data)
|
||||||
|
.find(x => x.startsWith('system.itemLinks.'))
|
||||||
|
?.slice(17);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.create(data, operation);
|
||||||
|
}
|
||||||
|
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
prepareEmbeddedDocuments() {
|
prepareEmbeddedDocuments() {
|
||||||
super.prepareEmbeddedDocuments();
|
super.prepareEmbeddedDocuments();
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@
|
||||||
{{#if document.system.primaryFeature}}
|
{{#if document.system.primaryFeature}}
|
||||||
<div class="feature-item"
|
<div class="feature-item"
|
||||||
data-action="editFeature"
|
data-action="editFeature"
|
||||||
data-type="primary"
|
data-item-uuid="{{this.uuid}}"
|
||||||
>
|
>
|
||||||
<img class="image" src="{{document.system.primaryFeature.img}}" />
|
<img class="image" src="{{document.system.primaryFeature.img}}" />
|
||||||
<span>{{document.system.primaryFeature.name}}</span>
|
<span>{{document.system.primaryFeature.name}}</span>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a data-action="removeFeature" data-type="primary"><i class="fa-solid fa-trash"></i></a>
|
<a data-action="deleteFeature"><i class="fa-solid fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
@ -33,12 +33,12 @@
|
||||||
{{#if document.system.secondaryFeature}}
|
{{#if document.system.secondaryFeature}}
|
||||||
<div class="feature-item"
|
<div class="feature-item"
|
||||||
data-action="editFeature"
|
data-action="editFeature"
|
||||||
data-type="secondary"
|
data-item-uuid="{{this.uuid}}"
|
||||||
>
|
>
|
||||||
<img class="image" src="{{document.system.secondaryFeature.img}}" />
|
<img class="image" src="{{document.system.secondaryFeature.img}}" />
|
||||||
<span>{{document.system.secondaryFeature.name}}</span>
|
<span>{{document.system.secondaryFeature.name}}</span>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a data-action="removeFeature" data-type="secondary"><i class="fa-solid fa-trash"></i></a>
|
<a data-action="deleteFeature"><i class="fa-solid fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue