mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 23:49:02 +01:00
Added use of ItemLinkFields
This commit is contained in:
parent
8cdad5172e
commit
569e567dfd
18 changed files with 232 additions and 288 deletions
|
|
@ -340,10 +340,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
})
|
||||
};
|
||||
context.traits.nrTotal = Object.keys(context.traits.values).length;
|
||||
context.traits.nrSelected = Object.values(context.traits.values).reduce(
|
||||
(acc, trait) => acc + (trait.value !== null ? 1 : 0),
|
||||
0
|
||||
);
|
||||
context.traits.nrSelected = this.getNrSelectedTrait();
|
||||
|
||||
context.experience = {
|
||||
values: this.setup.experiences,
|
||||
|
|
@ -397,6 +394,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
choiceA: { suggestions: suggestions.inventory.choiceA, compendium: 'consumables' },
|
||||
choiceB: { suggestions: suggestions.inventory.choiceB, compendium: 'general-items' }
|
||||
};
|
||||
context.noInventoryChoices =
|
||||
suggestions.inventory.take.length === 0 &&
|
||||
suggestions.inventory.choiceA?.length === 0 &&
|
||||
suggestions.inventory.choiceB?.length === 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -427,7 +428,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
case 5:
|
||||
return Object.values(this.setup.experiences).every(x => x.name) ? 6 : 5;
|
||||
case 4:
|
||||
return Object.values(this.setup.traits).every(x => x.value !== null) ? 5 : 4;
|
||||
return this.getNrSelectedTrait() === 6 ? 5 : 4;
|
||||
case 3:
|
||||
return this.setup.class.uuid && this.setup.subclass.uuid ? 4 : 3;
|
||||
case 2:
|
||||
|
|
@ -437,6 +438,18 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
}
|
||||
}
|
||||
|
||||
getNrSelectedTrait() {
|
||||
const traitCompareArray = [
|
||||
...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).traitArray
|
||||
];
|
||||
return Object.values(this.setup.traits).reduce((acc, x) => {
|
||||
const index = traitCompareArray.indexOf(x.value);
|
||||
traitCompareArray.splice(index, 1);
|
||||
acc += index !== -1;
|
||||
return acc;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
async getEquipmentSuggestions(choiceA, choiceB) {
|
||||
if (!this.setup.class.uuid) return { inventory: { take: [] } };
|
||||
|
||||
|
|
@ -448,10 +461,15 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
? { ...characterGuide.suggestedSecondaryWeapon, uuid: characterGuide.suggestedSecondaryWeapon.uuid }
|
||||
: null,
|
||||
inventory: {
|
||||
take: inventory.take ?? [],
|
||||
take: inventory.take?.filter(x => x) ?? [],
|
||||
choiceA:
|
||||
inventory.choiceA?.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceA?.uuid })) ?? [],
|
||||
choiceB: inventory.choiceB?.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceB?.uuid })) ?? []
|
||||
inventory.choiceA
|
||||
?.filter(x => x)
|
||||
.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceA?.uuid })) ?? [],
|
||||
choiceB:
|
||||
inventory.choiceB
|
||||
?.filter(x => x)
|
||||
.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceB?.uuid })) ?? []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -525,7 +543,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
name: this.setup.ancestryName ?? this.setup.primaryAncestry.name,
|
||||
system: {
|
||||
...this.setup.primaryAncestry.system,
|
||||
features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid]
|
||||
features: [
|
||||
{ type: 'primary', item: primaryAncestryFeature.uuid },
|
||||
{ type: 'secondary', item: secondaryAncestryFeature.uuid }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -554,7 +575,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
await this.character.createEmbeddedDocuments('Item', [this.equipment.inventory.choiceA]);
|
||||
if (this.equipment.inventory.choiceB.uuid)
|
||||
await this.character.createEmbeddedDocuments('Item', [this.equipment.inventory.choiceB]);
|
||||
await this.character.createEmbeddedDocuments('Item', this.setup.class.system.inventory.take);
|
||||
await this.character.createEmbeddedDocuments(
|
||||
'Item',
|
||||
this.setup.class.system.inventory.take.filter(x => x)
|
||||
);
|
||||
|
||||
await this.character.update({
|
||||
system: {
|
||||
|
|
|
|||
|
|
@ -341,7 +341,20 @@ export default function DHApplicationMixin(Base) {
|
|||
{
|
||||
name: 'CONTROLS.CommonEdit',
|
||||
icon: 'fa-solid fa-pen-to-square',
|
||||
callback: target => getDocFromElement(target).sheet.render({ force: true })
|
||||
callback: async target => {
|
||||
const doc = getDocFromElement(target);
|
||||
const appId = this.element.id;
|
||||
doc.apps[appId] = this;
|
||||
const app = await doc.sheet.render({ force: true });
|
||||
app.addEventListener(
|
||||
'close',
|
||||
() => {
|
||||
delete doc.apps[appId];
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
@ -496,9 +509,21 @@ export default function DHApplicationMixin(Base) {
|
|||
* Renders an embedded document.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static #editDoc(_event, target) {
|
||||
static async #editDoc(_event, target) {
|
||||
const doc = getDocFromElement(target);
|
||||
if (doc) return doc.sheet.render({ force: true });
|
||||
if (doc) {
|
||||
const appId = this.element.id;
|
||||
doc.apps[appId] = this;
|
||||
const app = await doc.sheet.render({ force: true });
|
||||
app.addEventListener(
|
||||
'close',
|
||||
() => {
|
||||
delete doc.apps[appId];
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: REDO this
|
||||
const { actionId } = target.closest('[data-action-id]').dataset;
|
||||
|
|
|
|||
|
|
@ -178,13 +178,15 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
static async #addFeature(_, target) {
|
||||
const { type } = target.dataset;
|
||||
const cls = foundry.documents.Item.implementation;
|
||||
const feature = await cls.create({
|
||||
'type': 'feature',
|
||||
'name': cls.defaultName({ type: 'feature' }),
|
||||
'system.subType': CONFIG.DH.ITEM.featureSubTypes[type]
|
||||
const item = await cls.create({
|
||||
type: 'feature',
|
||||
name: cls.defaultName({ type: 'feature' })
|
||||
});
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features, feature].map(f => f.uuid)
|
||||
'system.features': [...this.document.system.features, { type, item }].map(x => ({
|
||||
...x,
|
||||
item: x.item?.uuid
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -192,12 +194,14 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
* Remove a feature from the item.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #deleteFeature(_, target) {
|
||||
static async #deleteFeature(_, element) {
|
||||
const target = element.closest('[data-item-uuid]');
|
||||
const feature = getDocFromElement(target);
|
||||
if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||
await feature.update({ 'system.subType': null });
|
||||
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
|
||||
.filter(x => target.dataset.type !== x.type || x.item.uuid !== feature.uuid)
|
||||
.map(x => ({ ...x, item: x.item.uuid }))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -270,10 +274,15 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
if (data.fromInternal) return;
|
||||
|
||||
const target = event.target.closest('fieldset.drop-section');
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (item?.type === 'feature') {
|
||||
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': [...this.document.system.features, { type: target.dataset.type, item }].map(x => ({
|
||||
...x,
|
||||
item: x.item?.uuid
|
||||
}))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ import DHHeritageSheet from '../api/heritage-sheet.mjs';
|
|||
export default class AncestrySheet extends DHHeritageSheet {
|
||||
/**@inheritdoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['ancestry'],
|
||||
actions: {
|
||||
editFeature: AncestrySheet.#editFeature,
|
||||
removeFeature: AncestrySheet.#removeFeature
|
||||
},
|
||||
dragDrop: [{ dragSelector: null, dropSelector: '.tab.features .drop-section' }]
|
||||
classes: ['ancestry']
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
|
|
@ -18,40 +13,6 @@ export default class AncestrySheet extends DHHeritageSheet {
|
|||
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 */
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -61,22 +22,12 @@ export default class AncestrySheet extends DHHeritageSheet {
|
|||
* @param {DragEvent} event - The drag event
|
||||
*/
|
||||
async _onDrop(event) {
|
||||
event.stopPropagation();
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
const target = event.target.closest('fieldset.drop-section');
|
||||
const typeField =
|
||||
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
|
||||
|
||||
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]
|
||||
});
|
||||
if (!typeField) {
|
||||
super._onDrop(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,69 +87,45 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (item.type === 'feature') {
|
||||
if (target.classList.contains('hope-feature')) {
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.hope) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotHope'));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.hope });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('class-feature')) {
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.class) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotClass'));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.class });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
super._onDrop(event);
|
||||
} else if (item.type === 'weapon') {
|
||||
if (target.classList.contains('primary-weapon-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
|
||||
if (!item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedPrimaryWeapon': item.uuid
|
||||
});
|
||||
} else if (target.classList.contains('secondary-weapon-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary)
|
||||
if (item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'armor') {
|
||||
if (target.classList.contains('armor-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedArmor)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedArmor': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (target.classList.contains('choice-a-section')) {
|
||||
if (item.type === 'miscellaneous' || item.type === 'consumable') {
|
||||
if (this.document.system.inventory.choiceA.length < 2)
|
||||
const filteredChoiceA = this.document.system.inventory.choiceA;
|
||||
if (filteredChoiceA.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceA': [
|
||||
...this.document.system.inventory.choiceA.map(x => x.uuid),
|
||||
item.uuid
|
||||
]
|
||||
'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'miscellaneous') {
|
||||
if (target.classList.contains('take-section')) {
|
||||
if (this.document.system.inventory.take.length < 3)
|
||||
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
||||
if (filteredTake.length < 3)
|
||||
await this.document.update({
|
||||
'system.inventory.take': [...this.document.system.inventory.take.map(x => x.uuid), item.uuid]
|
||||
'system.inventory.take': [...filteredTake.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('choice-b-section')) {
|
||||
if (this.document.system.inventory.choiceB.length < 2)
|
||||
const filteredChoiceB = this.document.system.inventory.choiceB.filter(x => x);
|
||||
if (filteredChoiceB.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceB': [
|
||||
...this.document.system.inventory.choiceB.map(x => x.uuid),
|
||||
item.uuid
|
||||
]
|
||||
'system.inventory.choiceB': [...filteredChoiceB.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -167,7 +143,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
static async #removeItemFromCollection(_event, element) {
|
||||
const { uuid, target } = element.dataset;
|
||||
const prop = foundry.utils.getProperty(this.document.system, target);
|
||||
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid) });
|
||||
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid).map(x => x.uuid) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
|||
static DEFAULT_OPTIONS = {
|
||||
classes: ['subclass'],
|
||||
position: { width: 600 },
|
||||
window: { resizable: false },
|
||||
actions: {}
|
||||
window: { resizable: false }
|
||||
};
|
||||
|
||||
/**@override */
|
||||
|
|
@ -36,63 +35,4 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
|||
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
|
||||
}
|
||||
};
|
||||
|
||||
async _onDragStart(event) {
|
||||
const featureItem = event.currentTarget.closest('.drop-section');
|
||||
|
||||
if (featureItem) {
|
||||
const feature = this.document.system[featureItem.dataset.type];
|
||||
if (!feature) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||
return;
|
||||
}
|
||||
|
||||
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
|
||||
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
|
||||
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
|
||||
}
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
event.stopPropagation();
|
||||
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
if (data.fromInternal) return;
|
||||
|
||||
const item = await fromUuid(data.uuid);
|
||||
const target = event.target.closest('fieldset.drop-section');
|
||||
if (item.type === 'feature') {
|
||||
if (target.dataset.type === 'foundation') {
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.foundation) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotFoundation'));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.foundation });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.dataset.type === 'specialization') {
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.specialization) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotSpecialization'));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.specialization });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.dataset.type === 'mastery') {
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.mastery) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotMastery'));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.mastery });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ export default class ForeignDocumentUUIDField extends foundry.data.fields.Docume
|
|||
/**@override */
|
||||
initialize(value, _model, _options = {}) {
|
||||
if (this.idOnly) return value;
|
||||
return () => {
|
||||
return () => ForeignDocumentUUIDField.getInitializedField(value);
|
||||
}
|
||||
|
||||
static getInitializedField(value) {
|
||||
try {
|
||||
const doc = fromUuidSync(value);
|
||||
return doc;
|
||||
|
|
@ -31,7 +34,6 @@ export default class ForeignDocumentUUIDField extends foundry.data.fields.Docume
|
|||
console.error(error);
|
||||
return value ?? null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**@override */
|
||||
|
|
|
|||
19
module/data/fields/itemLinkFields.mjs
Normal file
19
module/data/fields/itemLinkFields.mjs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import ForeignDocumentUUIDField from './foreignDocumentUUIDField.mjs';
|
||||
|
||||
export default class ItemLinkFields extends foundry.data.fields.ArrayField {
|
||||
constructor(options, context) {
|
||||
super(new ItemLinkField(), options, context);
|
||||
}
|
||||
}
|
||||
|
||||
class ItemLinkField extends foundry.data.fields.SchemaField {
|
||||
constructor(context) {
|
||||
super(
|
||||
{
|
||||
type: new foundry.data.fields.StringField({ choices: CONFIG.DH.ITEM.featureSubTypes, nullable: true }),
|
||||
item: new ForeignDocumentUUIDField({ type: 'Item' })
|
||||
},
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
import ItemLinkFields from '../../data/fields/itemLinkFields.mjs';
|
||||
|
||||
export default class DHAncestry extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -15,23 +15,15 @@ export default class DHAncestry extends BaseDataItem {
|
|||
static defineSchema() {
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
features: new ForeignDocumentUUIDArrayField({ type: 'Item' })
|
||||
features: new ItemLinkFields()
|
||||
};
|
||||
}
|
||||
|
||||
get primaryFeature() {
|
||||
return (
|
||||
this.features.find(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.primary) ??
|
||||
(this.features.filter(x => !x).length > 0 ? {} : null)
|
||||
);
|
||||
return this.features.find(x => x.type === CONFIG.DH.ITEM.featureSubTypes.primary)?.item;
|
||||
}
|
||||
|
||||
get secondaryFeature() {
|
||||
return (
|
||||
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)
|
||||
);
|
||||
return this.features.find(x => x.type === CONFIG.DH.ITEM.featureSubTypes.secondary)?.item;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,12 +124,13 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
this.actor.createEmbeddedDocuments(
|
||||
'Item',
|
||||
this.features.map(feature => ({
|
||||
...feature,
|
||||
...(feature.item ?? feature),
|
||||
system: {
|
||||
...feature.system,
|
||||
...(feature.item?.system ?? feature.system),
|
||||
originItemType: this.parent.type,
|
||||
originId: data._id,
|
||||
identifier: feature.identifier
|
||||
identifier: feature.identifier,
|
||||
subType: feature.item ? feature.type : undefined
|
||||
}
|
||||
}))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import BaseDataItem from './base.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import ItemLinkFields from '../fields/itemLinkFields.mjs';
|
||||
|
||||
export default class DHClass extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -27,7 +28,7 @@ export default class DHClass extends BaseDataItem {
|
|||
label: 'DAGGERHEART.GENERAL.HitPoints.plural'
|
||||
}),
|
||||
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }),
|
||||
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||
features: new ItemLinkFields(),
|
||||
subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||
inventory: new fields.SchemaField({
|
||||
take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||
|
|
@ -52,17 +53,11 @@ export default class DHClass extends BaseDataItem {
|
|||
}
|
||||
|
||||
get hopeFeatures() {
|
||||
return (
|
||||
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.hope) ??
|
||||
(this.features.filter(x => !x).length > 0 ? {} : null)
|
||||
);
|
||||
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.hope).map(x => x.item);
|
||||
}
|
||||
|
||||
get classFeatures() {
|
||||
return (
|
||||
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.class) ??
|
||||
(this.features.filter(x => !x).length > 0 ? {} : null)
|
||||
);
|
||||
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.class).map(x => x.item);
|
||||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import ItemLinkFields from '../fields/itemLinkFields.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
|
||||
export default class DHSubclass extends BaseDataItem {
|
||||
|
|
@ -22,22 +22,22 @@ export default class DHSubclass extends BaseDataItem {
|
|||
nullable: true,
|
||||
initial: null
|
||||
}),
|
||||
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||
features: new ItemLinkFields(),
|
||||
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
||||
isMulticlass: new fields.BooleanField({ initial: false })
|
||||
};
|
||||
}
|
||||
|
||||
get foundationFeatures() {
|
||||
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.foundation);
|
||||
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.foundation).map(x => x.item);
|
||||
}
|
||||
|
||||
get specializationFeatures() {
|
||||
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.specialization);
|
||||
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.specialization).map(x => x.item);
|
||||
}
|
||||
|
||||
get masteryFeatures() {
|
||||
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.mastery);
|
||||
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.mastery).map(x => x.item);
|
||||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.selectArmor"}}
|
||||
{{/"systems/daggerheart/templates/components/card-preview.hbs"}}
|
||||
</div>
|
||||
{{#if armor.suggestion}}
|
||||
{{#if armor.suggestion.name}}
|
||||
<fieldset class="suggestion-container">
|
||||
<legend>{{armor.suggestion.name}}</legend>
|
||||
<div class="suggestion-inner-container {{#if armor.suggestion.taken}}taken{{/if}}" data-action="viewItem" data-uuid="{{armor.suggestion.uuid}}">
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.selectPrimaryWeapon"}}
|
||||
{{/"systems/daggerheart/templates/components/card-preview.hbs"}}
|
||||
</div>
|
||||
{{#if primaryWeapon.suggestion}}
|
||||
{{#if primaryWeapon.suggestion.name}}
|
||||
<fieldset class="suggestion-container">
|
||||
<legend>{{primaryWeapon.suggestion.name}}</legend>
|
||||
<div class="suggestion-inner-container {{#if primaryWeapon.suggestion.taken}}taken{{/if}}" data-action="viewItem" data-uuid="{{primaryWeapon.suggestion.uuid}}">
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.selectSecondaryWeapon"}}
|
||||
{{/"systems/daggerheart/templates/components/card-preview.hbs"}}
|
||||
</div>
|
||||
{{#if secondaryWeapon.suggestion}}
|
||||
{{#if secondaryWeapon.suggestion.name}}
|
||||
<fieldset class="suggestion-container">
|
||||
<legend>{{secondaryWeapon.suggestion.name}}</legend>
|
||||
<div
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{#unless noInventoryChoices}}
|
||||
<div class="main-equipment-selection triple">
|
||||
<fieldset class="equipment-selection">
|
||||
<legend>{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.startingItems"}}</legend>
|
||||
|
|
@ -103,5 +104,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<li class='feature-item' data-item-uuid='{{feature.uuid}}'>
|
||||
<li class='feature-item' data-item-uuid='{{feature.uuid}}' data-type="{{type}}">
|
||||
<div class='feature-line'>
|
||||
<img class='image' src='{{feature.img}}' />
|
||||
<h4>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
data-tab='{{tabs.features.id}}'
|
||||
data-group='{{tabs.features.group}}'
|
||||
>
|
||||
<fieldset class="one-column drop-section primary-feature">
|
||||
<fieldset class="one-column drop-section primary-feature" data-type="primary">
|
||||
<legend>
|
||||
{{localize "DAGGERHEART.ITEMS.Ancestry.primaryFeature"}}
|
||||
{{#unless document.system.primaryFeature}}<a><i data-action="addFeature" data-type="primary" class="fa-solid fa-plus icon-button"></i></a>{{/unless}}
|
||||
|
|
@ -11,20 +11,21 @@
|
|||
<div class="features-list">
|
||||
{{#if document.system.primaryFeature}}
|
||||
<div class="feature-item"
|
||||
data-action="editFeature"
|
||||
data-action="editDoc"
|
||||
data-item-uuid="{{document.system.primaryFeature.uuid}}"
|
||||
data-type="primary"
|
||||
>
|
||||
<img class="image" src="{{document.system.primaryFeature.img}}" />
|
||||
<span>{{document.system.primaryFeature.name}}</span>
|
||||
<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>
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column drop-section secondary-feature">
|
||||
<fieldset class="one-column drop-section secondary-feature" data-type="secondary">
|
||||
<legend>
|
||||
{{localize "DAGGERHEART.ITEMS.Ancestry.secondaryFeature"}}
|
||||
{{#unless document.system.secondaryFeature}}<a><i data-action="addFeature" data-type="secondary" class="fa-solid fa-plus icon-button"></i></a>{{/unless}}
|
||||
|
|
@ -32,13 +33,14 @@
|
|||
<div class="features-list">
|
||||
{{#if document.system.secondaryFeature}}
|
||||
<div class="feature-item"
|
||||
data-action="editFeature"
|
||||
data-action="editDoc"
|
||||
data-item-uuid="{{document.system.secondaryFeature.uuid}}"
|
||||
data-type="secondary"
|
||||
>
|
||||
<img class="image" src="{{document.system.secondaryFeature.img}}" />
|
||||
<span>{{document.system.secondaryFeature.name}}</span>
|
||||
<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>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
data-group='{{tabs.features.group}}'
|
||||
>
|
||||
<div class="two-columns even">
|
||||
<fieldset class="drop-section hope-feature">
|
||||
<fieldset class="drop-section hope-feature" data-type='hope'>
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.hopeFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="hope" data-action="addFeature"></i></a></legend>
|
||||
<div class="feature-list">
|
||||
{{#each source.system.hopeFeatures as |feature|}}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="drop-section class-feature">
|
||||
<fieldset class="drop-section class-feature" data-type='class'>
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.classFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="class" data-action="addFeature"></i></a></legend>
|
||||
<div class="feature-list">
|
||||
{{#each source.system.classFeatures as |feature|}}
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<div class='controls'>
|
||||
<a
|
||||
class='effect-control'
|
||||
data-action='viewDoc'
|
||||
data-uuid={{subclass.uuid}}
|
||||
data-action='editDoc'
|
||||
data-item-uuid={{subclass.uuid}}
|
||||
data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}'
|
||||
>
|
||||
<i class="fa-solid fa-globe"></i>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedPrimaryWeapon.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedPrimaryWeapon.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeSuggestedItem" data-target="suggestedPrimaryWeapon" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeSuggestedItem" data-target="suggestedPrimaryWeapon" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedSecondaryWeapon.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedSecondaryWeapon.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeSuggestedItem" data-target="suggestedSecondaryWeapon" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeSuggestedItem" data-target="suggestedSecondaryWeapon" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedArmor.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedArmor.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeSuggestedItem" data-target="suggestedArmor" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeSuggestedItem" data-target="suggestedArmor" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -86,13 +86,15 @@
|
|||
<legend>{{localize "DAGGERHEART.GENERAL.take"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.take}}
|
||||
{{#if this}}
|
||||
<div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
|
||||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeItemFromCollection" data-target="invetory.take" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeItemFromCollection" data-target="inventory.take" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
@ -101,13 +103,15 @@
|
|||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.choiceA}}
|
||||
{{#if this}}
|
||||
<div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
|
||||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeItemFromCollection" data-target="invetory.choiceA" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeItemFromCollection" data-target="inventory.choiceA" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
@ -116,13 +120,15 @@
|
|||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.choiceB}}
|
||||
{{#if this}}
|
||||
<div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
|
||||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<i data-action="removeItemFromCollection" data-target="invetory.choiceB" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i>
|
||||
<a><i data-action="removeItemFromCollection" data-target="inventory.choiceB" data-uuid="{{this.uuid}}" class="fa-solid fa-trash icon-button"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<fieldset class="two-columns">
|
||||
{{#with systemFields.attack.fields.damage.fields.parts.element.fields as | fields | }}
|
||||
{{#with (lookup ../document.system.attack.damage.parts 0) as | source | }}
|
||||
<legend>{{localize "DAGGERHEART.GENERAL.title"}}</legend>
|
||||
<legend>{{localize "DAGGERHEART.GENERAL.damage"}}</legend>
|
||||
<span>{{localize "DAGGERHEART.GENERAL.Dice.single"}}</span>
|
||||
{{formInput fields.value.fields.dice value=source.value.dice name="system.attack.damage.parts.0.value.dice"}}
|
||||
<span>{{localize "DAGGERHEART.GENERAL.bonus"}}</span>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue