diff --git a/lang/en.json b/lang/en.json
index 17d2c9d5..9a4024ae 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -1137,6 +1137,8 @@
"Appearance": "Appearance",
"settings": "Settings"
},
+ "HopeFeatures": "Hope Features",
+ "Class Features": "Class Features",
"Domains": "Domains",
"DamageThresholds": {
"Title": "Damage Thresholds",
diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs
index c8f5c1e1..54f29361 100644
--- a/module/applications/sheets/items/class.mjs
+++ b/module/applications/sheets/items/class.mjs
@@ -1,8 +1,11 @@
+import { actionsTypes } from '../../../data/_module.mjs';
import { tagifyElement } from '../../../helpers/utils.mjs';
+import DHActionConfig from '../../config/Action.mjs';
import DaggerheartSheet from '../daggerheart-sheet.mjs';
const { ItemSheetV2 } = foundry.applications.sheets;
const { TextEditor } = foundry.applications.ux;
+
export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
@@ -11,8 +14,9 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
actions: {
removeSubclass: this.removeSubclass,
viewSubclass: this.viewSubclass,
- deleteFeature: this.deleteFeature,
+ addFeature: this.addFeature,
editFeature: this.editFeature,
+ deleteFeature: this.deleteFeature,
removeItem: this.removeItem,
viewItem: this.viewItem,
removePrimaryWeapon: this.removePrimaryWeapon,
@@ -151,6 +155,69 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false });
}
+ async selectActionType() {
+ const content = await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/views/actionType.hbs',
+ { types: SYSTEM.ACTIONS.actionTypes }
+ ),
+ title = 'Select Action Type',
+ type = 'form',
+ data = {};
+ return Dialog.prompt({
+ title,
+ label: title,
+ content,
+ type,
+ callback: html => {
+ const form = html[0].querySelector('form'),
+ fd = new foundry.applications.ux.FormDataExtended(form);
+ foundry.utils.mergeObject(data, fd.object, { inplace: true });
+
+ return data;
+ },
+ rejectClose: false
+ });
+ }
+
+ getActionPath(type) {
+ return type === 'hope' ? 'hopeFeatures' : 'classFeatures';
+ }
+
+ static async addFeature(_, target) {
+ const actionPath = this.getActionPath(target.dataset.type);
+ const actionType = await this.selectActionType();
+ const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack,
+ action = new cls(
+ {
+ _id: foundry.utils.randomID(),
+ systemPath: actionPath,
+ type: actionType.type,
+ name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name),
+ ...cls.getSourceConfig(this.document)
+ },
+ {
+ parent: this.document
+ }
+ );
+ await this.document.update({ [`system.${actionPath}`]: [...this.document.system[actionPath], action] });
+ }
+
+ static async editFeature(_, target) {
+ const action = this.document.system[this.getActionPath(target.dataset.type)].find(
+ x => x._id === target.dataset.feature
+ );
+ await new DHActionConfig(action).render(true);
+ }
+
+ static async deleteFeature(_, target) {
+ const actionPath = this.getActionPath(target.dataset.type);
+ await this.document.update({
+ [`system.${actionPath}`]: this.document.system[actionPath].filter(
+ action => action._id !== target.dataset.feature
+ )
+ });
+ }
+
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const item = await fromUuid(data.uuid);
@@ -158,10 +225,6 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
await this.document.update({
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
});
- } else if (item.type === 'feature') {
- await this.document.update({
- 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
- });
} else if (item.type === 'weapon') {
if (event.currentTarget.classList.contains('primary-weapon-section')) {
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs
index 335014b9..47acb712 100644
--- a/module/data/item/class.mjs
+++ b/module/data/item/class.mjs
@@ -1,5 +1,6 @@
import BaseDataItem from './base.mjs';
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
+import ActionField from '../fields/actionField.mjs';
export default class DHClass extends BaseDataItem {
/** @inheritDoc */
@@ -19,7 +20,8 @@ export default class DHClass extends BaseDataItem {
domains: new fields.ArrayField(new fields.StringField(), { max: 2 }),
classItems: new fields.ArrayField(new ForeignDocumentUUIDField({ type: 'Item' })),
evasion: new fields.NumberField({ initial: 0, integer: true }),
- features: new fields.ArrayField(new ForeignDocumentUUIDField({ type: 'Item' })),
+ hopeFeatures: new foundry.data.fields.ArrayField(new ActionField()),
+ classFeatures: new foundry.data.fields.ArrayField(new ActionField()),
subclasses: new fields.ArrayField(
new ForeignDocumentUUIDField({ type: 'Item', required: false, nullable: true, initial: undefined })
),
@@ -51,6 +53,10 @@ export default class DHClass extends BaseDataItem {
};
}
+ get hopeFeature() {
+ return this.hopeFeatures.length > 0 ? this.hopeFeatures[0] : null;
+ }
+
async _preCreate(data, options, user) {
const allowed = await super._preCreate(data, options, user);
if (allowed === false) return;
diff --git a/templates/sheets/global/partials/feature-section-item.hbs b/templates/sheets/global/partials/feature-section-item.hbs
index ebaabefe..7bcf7736 100644
--- a/templates/sheets/global/partials/feature-section-item.hbs
+++ b/templates/sheets/global/partials/feature-section-item.hbs
@@ -9,7 +9,8 @@
@@ -17,7 +18,8 @@
diff --git a/templates/sheets/items/class/features.hbs b/templates/sheets/items/class/features.hbs
index dfa386d1..8b615121 100644
--- a/templates/sheets/items/class/features.hbs
+++ b/templates/sheets/items/class/features.hbs
@@ -3,15 +3,25 @@
data-tab='{{tabs.features.id}}'
data-group='{{tabs.features.group}}'
>
+