mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-15 13:11:08 +01:00
140/141 - Class/Subclass Actions/Effects (#142)
* Added Actions and effects * Added class hopeFeatures and classFeatures
This commit is contained in:
parent
0fbba51ad7
commit
f80a849b73
15 changed files with 281 additions and 74 deletions
|
|
@ -106,8 +106,13 @@ Hooks.once('init', () => {
|
||||||
|
|
||||||
Hooks.on('ready', () => {
|
Hooks.on('ready', () => {
|
||||||
ui.resources = new CONFIG.ui.resources();
|
ui.resources = new CONFIG.ui.resources();
|
||||||
if(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.DisplayFear) !== 'hide') ui.resources.render({ force: true });
|
if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.DisplayFear) !== 'hide')
|
||||||
document.body.classList.toggle('theme-colorful', game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme === DualityRollColor.colorful.value);
|
ui.resources.render({ force: true });
|
||||||
|
document.body.classList.toggle(
|
||||||
|
'theme-colorful',
|
||||||
|
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme ===
|
||||||
|
DualityRollColor.colorful.value
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.once('dicesoniceready', () => {});
|
Hooks.once('dicesoniceready', () => {});
|
||||||
|
|
@ -269,6 +274,8 @@ const preloadHandlebarsTemplates = async function () {
|
||||||
'systems/daggerheart/templates/sheets/character/sections/loadout.hbs',
|
'systems/daggerheart/templates/sheets/character/sections/loadout.hbs',
|
||||||
'systems/daggerheart/templates/sheets/character/parts/heritageCard.hbs',
|
'systems/daggerheart/templates/sheets/character/parts/heritageCard.hbs',
|
||||||
'systems/daggerheart/templates/sheets/character/parts/advancementCard.hbs',
|
'systems/daggerheart/templates/sheets/character/parts/advancementCard.hbs',
|
||||||
|
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs',
|
||||||
|
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs',
|
||||||
'systems/daggerheart/templates/components/card-preview.hbs',
|
'systems/daggerheart/templates/components/card-preview.hbs',
|
||||||
'systems/daggerheart/templates/views/levelup/parts/selectable-card-preview.hbs',
|
'systems/daggerheart/templates/views/levelup/parts/selectable-card-preview.hbs',
|
||||||
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
|
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
|
||||||
|
|
|
||||||
|
|
@ -825,7 +825,8 @@
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
"Dice": "Dice"
|
"Dice": "Dice"
|
||||||
},
|
},
|
||||||
"Max": "Max"
|
"Max": "Max",
|
||||||
|
"NewEffect": "New Effect"
|
||||||
},
|
},
|
||||||
"FeatureType": {
|
"FeatureType": {
|
||||||
"Normal": "Normal",
|
"Normal": "Normal",
|
||||||
|
|
@ -1145,6 +1146,8 @@
|
||||||
"Appearance": "Appearance",
|
"Appearance": "Appearance",
|
||||||
"settings": "Settings"
|
"settings": "Settings"
|
||||||
},
|
},
|
||||||
|
"HopeFeatures": "Hope Features",
|
||||||
|
"Class Features": "Class Features",
|
||||||
"Domains": "Domains",
|
"Domains": "Domains",
|
||||||
"DamageThresholds": {
|
"DamageThresholds": {
|
||||||
"Title": "Damage Thresholds",
|
"Title": "Damage Thresholds",
|
||||||
|
|
@ -1254,7 +1257,9 @@
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"SubclassFeature": {
|
"SubclassFeature": {
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Abilities": "Abilities"
|
"Abilities": "Abilities",
|
||||||
|
"Actions": "Actions",
|
||||||
|
"Effects": "Effects"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Weapon": {
|
"Weapon": {
|
||||||
|
|
|
||||||
|
|
@ -86,11 +86,11 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
static async updateForm(event, _, formData) {
|
static async updateForm(event, _, formData) {
|
||||||
const submitData = this._prepareSubmitData(event, formData),
|
const submitData = this._prepareSubmitData(event, formData),
|
||||||
data = foundry.utils.expandObject(foundry.utils.mergeObject(this.action.toObject(), submitData)),
|
data = foundry.utils.expandObject(foundry.utils.mergeObject(this.action.toObject(), submitData)),
|
||||||
newActions = this.action.parent.actions.map(x => x.toObject()); // Find better way
|
newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); // Find better way
|
||||||
if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data);
|
if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data);
|
||||||
const updates = await this.action.parent.parent.update({ 'system.actions': newActions });
|
const updates = await this.action.parent.parent.update({ [`system.${this.action.systemPath}`]: newActions });
|
||||||
if (!updates) return;
|
if (!updates) return;
|
||||||
this.action = updates.system.actions[this.action.index];
|
this.action = foundry.utils.getProperty(updates.system, this.action.systemPath)[this.action.index];
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
import { actionsTypes } from '../../../data/_module.mjs';
|
||||||
import { tagifyElement } from '../../../helpers/utils.mjs';
|
import { tagifyElement } from '../../../helpers/utils.mjs';
|
||||||
|
import DHActionConfig from '../../config/Action.mjs';
|
||||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||||
|
|
||||||
const { ItemSheetV2 } = foundry.applications.sheets;
|
const { ItemSheetV2 } = foundry.applications.sheets;
|
||||||
const { TextEditor } = foundry.applications.ux;
|
const { TextEditor } = foundry.applications.ux;
|
||||||
|
|
||||||
export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
|
export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
|
|
@ -11,8 +14,9 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
|
||||||
actions: {
|
actions: {
|
||||||
removeSubclass: this.removeSubclass,
|
removeSubclass: this.removeSubclass,
|
||||||
viewSubclass: this.viewSubclass,
|
viewSubclass: this.viewSubclass,
|
||||||
deleteFeature: this.deleteFeature,
|
addFeature: this.addFeature,
|
||||||
editFeature: this.editFeature,
|
editFeature: this.editFeature,
|
||||||
|
deleteFeature: this.deleteFeature,
|
||||||
removeItem: this.removeItem,
|
removeItem: this.removeItem,
|
||||||
viewItem: this.viewItem,
|
viewItem: this.viewItem,
|
||||||
removePrimaryWeapon: this.removePrimaryWeapon,
|
removePrimaryWeapon: this.removePrimaryWeapon,
|
||||||
|
|
@ -151,6 +155,69 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
|
||||||
await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false });
|
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) {
|
async _onDrop(event) {
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = TextEditor.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
|
|
@ -158,10 +225,6 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
|
'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') {
|
} else if (item.type === 'weapon') {
|
||||||
if (event.currentTarget.classList.contains('primary-weapon-section')) {
|
if (event.currentTarget.classList.contains('primary-weapon-section')) {
|
||||||
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
|
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,24 @@
|
||||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
import { actionsTypes } from '../../../data/_module.mjs';
|
||||||
|
import DHActionConfig from '../../config/Action.mjs';
|
||||||
|
import DhpApplicationMixin from '../daggerheart-sheet.mjs';
|
||||||
|
|
||||||
const { ItemSheetV2 } = foundry.applications.sheets;
|
const { ItemSheetV2 } = foundry.applications.sheets;
|
||||||
const { TextEditor } = foundry.applications.ux;
|
export default class SubclassSheet extends DhpApplicationMixin(ItemSheetV2) {
|
||||||
const { duplicate, getProperty } = foundry.utils;
|
|
||||||
export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'subclass'],
|
classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'subclass'],
|
||||||
position: { width: 600 },
|
position: { width: 600 },
|
||||||
window: { resizable: false },
|
window: { resizable: false },
|
||||||
actions: {
|
actions: {
|
||||||
editAbility: this.editAbility,
|
addFeature: this.addFeature,
|
||||||
deleteFeatureAbility: this.deleteFeatureAbility
|
editFeature: this.editFeature,
|
||||||
|
deleteFeature: this.deleteFeature
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
handler: this.updateForm,
|
handler: this.updateForm,
|
||||||
submitOnChange: true,
|
submitOnChange: true,
|
||||||
closeOnSubmit: false
|
closeOnSubmit: false
|
||||||
},
|
}
|
||||||
dragDrop: [
|
|
||||||
{ dragSelector: null, dropSelector: '.foundation-tab' },
|
|
||||||
{ dragSelector: null, dropSelector: '.specialization-tab' },
|
|
||||||
{ dragSelector: null, dropSelector: '.mastery-tab' }
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
|
|
@ -80,41 +76,99 @@ export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async editAbility(_, button) {
|
static addFeature(_, target) {
|
||||||
const feature = await fromUuid(button.dataset.ability);
|
if (target.dataset.type === 'action') this.addAction(target.dataset.level);
|
||||||
feature.sheet.render(true);
|
else this.addEffect(target.dataset.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async deleteFeatureAbility(event, button) {
|
static async editFeature(_, target) {
|
||||||
event.preventDefault();
|
if (target.dataset.type === 'action') this.editAction(target.dataset.level, target.dataset.feature);
|
||||||
event.stopPropagation();
|
else this.editEffect(target.dataset.feature);
|
||||||
|
|
||||||
const feature = button.dataset.feature;
|
|
||||||
const newAbilities = this.document.system[`${feature}Feature`].abilities.filter(
|
|
||||||
x => x.uuid !== button.dataset.ability
|
|
||||||
);
|
|
||||||
const path = `system.${feature}Feature.abilities`;
|
|
||||||
|
|
||||||
await this.document.update({ [path]: newAbilities });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
static async deleteFeature(_, target) {
|
||||||
event.preventDefault();
|
if (target.dataset.type === 'action') this.removeAction(target.dataset.level, target.dataset.feature);
|
||||||
const data = TextEditor.getDragEventData(event);
|
else this.removeEffect(target.dataset.level, target.dataset.feature);
|
||||||
const item = await fromUuid(data.uuid);
|
}
|
||||||
if (!(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id)) return;
|
|
||||||
|
|
||||||
let featureField;
|
async #selectActionType() {
|
||||||
if (event.currentTarget.classList.contains('foundation-tab')) featureField = 'foundation';
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
else if (event.currentTarget.classList.contains('specialization-tab')) featureField = 'specialization';
|
'systems/daggerheart/templates/views/actionType.hbs',
|
||||||
else if (event.currentTarget.classList.contains('mastery-tab')) featureField = 'mastery';
|
{ types: SYSTEM.ACTIONS.actionTypes }
|
||||||
else return;
|
),
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const path = `system.${featureField}Feature.abilities`;
|
async addAction(level) {
|
||||||
const abilities = duplicate(getProperty(this.document, path)) || [];
|
const actionType = await this.#selectActionType();
|
||||||
const featureData = { name: item.name, img: item.img, uuid: item.uuid };
|
const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack,
|
||||||
abilities.push(featureData);
|
action = new cls(
|
||||||
|
{
|
||||||
|
_id: foundry.utils.randomID(),
|
||||||
|
systemPath: `${level}.actions`,
|
||||||
|
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.${level}.actions`]: [...this.document.system[level].actions, action] });
|
||||||
|
await new DHActionConfig(
|
||||||
|
this.document.system[level].actions[this.document.system[level].actions.length - 1]
|
||||||
|
).render(true);
|
||||||
|
}
|
||||||
|
|
||||||
await this.document.update({ [path]: abilities });
|
async addEffect(level) {
|
||||||
|
const embeddedItems = await this.document.createEmbeddedDocuments('ActiveEffect', [
|
||||||
|
{ name: game.i18n.localize('DAGGERHEART.Feature.NewEffect') }
|
||||||
|
]);
|
||||||
|
await this.document.update({
|
||||||
|
[`system.${level}.effects`]: [
|
||||||
|
...this.document.system[level].effects.map(x => x.uuid),
|
||||||
|
embeddedItems[0].uuid
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async editAction(level, id) {
|
||||||
|
const action = this.document.system[level].actions.find(x => x._id === id);
|
||||||
|
await new DHActionConfig(action).render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async editEffect(id) {
|
||||||
|
const effect = this.document.effects.get(id);
|
||||||
|
effect.sheet.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeAction(level, id) {
|
||||||
|
await this.document.update({
|
||||||
|
[`system.${level}.actions`]: this.document.system[level].actions.filter(action => action._id !== id)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeEffect(level, id) {
|
||||||
|
await this.document.effects.get(id).delete();
|
||||||
|
await this.document.update({
|
||||||
|
[`system.${level}.effects`]: this.document.system[level].effects
|
||||||
|
.filter(x => x && x.id !== id)
|
||||||
|
.map(effect => effect.uuid)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
_id: new fields.DocumentIdField(),
|
_id: new fields.DocumentIdField(),
|
||||||
|
systemPath: new fields.StringField({ required: true, initial: 'actions' }),
|
||||||
type: new fields.StringField({ initial: undefined, readonly: true, required: true }),
|
type: new fields.StringField({ initial: undefined, readonly: true, required: true }),
|
||||||
name: new fields.StringField({ initial: undefined }),
|
name: new fields.StringField({ initial: undefined }),
|
||||||
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
|
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
|
||||||
|
|
@ -93,7 +94,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
prepareData() {}
|
prepareData() {}
|
||||||
|
|
||||||
get index() {
|
get index() {
|
||||||
return this.parent.actions.indexOf(this);
|
return foundry.utils.getProperty(this.parent, this.systemPath).indexOf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get item() {
|
get item() {
|
||||||
|
|
@ -203,7 +204,7 @@ export class DHAttackAction extends DHBaseAction {
|
||||||
static getRollType() {
|
static getRollType() {
|
||||||
return 'weapon';
|
return 'weapon';
|
||||||
}
|
}
|
||||||
|
|
||||||
get chatTitle() {
|
get chatTitle() {
|
||||||
return game.i18n.format('DAGGERHEART.Chat.AttackRoll.Title', {
|
return game.i18n.format('DAGGERHEART.Chat.AttackRoll.Title', {
|
||||||
attack: this.item.name
|
attack: this.item.name
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import BaseDataItem from './base.mjs';
|
import BaseDataItem from './base.mjs';
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||||
|
import ActionField from '../fields/actionField.mjs';
|
||||||
|
|
||||||
export default class DHClass extends BaseDataItem {
|
export default class DHClass extends BaseDataItem {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
|
|
@ -19,7 +20,8 @@ export default class DHClass extends BaseDataItem {
|
||||||
domains: new fields.ArrayField(new fields.StringField(), { max: 2 }),
|
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 }),
|
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(
|
subclasses: new fields.ArrayField(
|
||||||
new ForeignDocumentUUIDField({ type: 'Item', required: false, nullable: true, initial: undefined })
|
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) {
|
async _preCreate(data, options, user) {
|
||||||
const allowed = await super._preCreate(data, options, user);
|
const allowed = await super._preCreate(data, options, user);
|
||||||
if (allowed === false) return;
|
if (allowed === false) return;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
|
import ActionField from '../fields/actionField.mjs';
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||||
import BaseDataItem from './base.mjs';
|
import BaseDataItem from './base.mjs';
|
||||||
|
|
||||||
|
const featureSchema = () => {
|
||||||
|
return new foundry.data.fields.SchemaField({
|
||||||
|
name: new foundry.data.fields.StringField({ required: true }),
|
||||||
|
effects: new foundry.data.fields.ArrayField(new ForeignDocumentUUIDField({ type: 'ActiveEffect' })),
|
||||||
|
actions: new foundry.data.fields.ArrayField(new ActionField())
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export default class DHSubclass extends BaseDataItem {
|
export default class DHSubclass extends BaseDataItem {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
static get metadata() {
|
static get metadata() {
|
||||||
|
|
@ -22,9 +31,9 @@ export default class DHSubclass extends BaseDataItem {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initial: null
|
initial: null
|
||||||
}),
|
}),
|
||||||
foundationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
foundationFeature: featureSchema(),
|
||||||
specializationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
specializationFeature: featureSchema(),
|
||||||
masteryFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
masteryFeature: featureSchema(),
|
||||||
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
||||||
isMulticlass: new fields.BooleanField({ initial: false })
|
isMulticlass: new fields.BooleanField({ initial: false })
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3579,7 +3579,6 @@ div.daggerheart.views.multiclass {
|
||||||
}
|
}
|
||||||
.sheet.daggerheart.dh-style.item .tab.features {
|
.sheet.daggerheart.dh-style.item .tab.features {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
max-height: 265px;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: light-dark(#18162e, #f3c267) transparent;
|
scrollbar-color: light-dark(#18162e, #f3c267) transparent;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
.sheet.daggerheart.dh-style.item {
|
.sheet.daggerheart.dh-style.item {
|
||||||
.tab.features {
|
.tab.features {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
max-height: 265px;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
<a
|
<a
|
||||||
class='effect-control'
|
class='effect-control'
|
||||||
data-action='editFeature'
|
data-action='editFeature'
|
||||||
data-feature='{{feature.uuid}}'
|
data-feature='{{feature._id}}'
|
||||||
|
data-type='{{type}}'
|
||||||
data-tooltip='{{localize "DAGGERHEART.Tooltip.openItemWorld"}}'
|
data-tooltip='{{localize "DAGGERHEART.Tooltip.openItemWorld"}}'
|
||||||
>
|
>
|
||||||
<i class="fa-solid fa-globe"></i>
|
<i class="fa-solid fa-globe"></i>
|
||||||
|
|
@ -17,7 +18,8 @@
|
||||||
<a
|
<a
|
||||||
class='effect-control'
|
class='effect-control'
|
||||||
data-action='deleteFeature'
|
data-action='deleteFeature'
|
||||||
data-feature='{{feature.uuid}}'
|
data-feature='{{feature._id}}'
|
||||||
|
data-type='{{type}}'
|
||||||
data-tooltip='{{localize "DAGGERHEART.Tooltip.delete"}}'
|
data-tooltip='{{localize "DAGGERHEART.Tooltip.delete"}}'
|
||||||
>
|
>
|
||||||
<i class='fas fa-trash'></i>
|
<i class='fas fa-trash'></i>
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,25 @@
|
||||||
data-tab='{{tabs.features.id}}'
|
data-tab='{{tabs.features.id}}'
|
||||||
data-group='{{tabs.features.group}}'
|
data-group='{{tabs.features.group}}'
|
||||||
>
|
>
|
||||||
|
<div class="two-columns even">
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{localize "DAGGERHEART.Sheets.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 index|}}
|
||||||
|
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='hope' feature=feature}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "DAGGERHEART.Sheets.Feature.Tabs.Features"}}</legend>
|
<legend>{{localize "DAGGERHEART.Sheets.Class.ClassFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="class" data-action="addFeature"></i></a></legend>
|
||||||
<div class="feature-list">
|
<div class="feature-list">
|
||||||
{{#each source.system.features as |feature index|}}
|
{{#each source.system.classFeatures as |feature index|}}
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}}
|
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='class' feature=feature}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "TYPES.Item.subclass"}}</legend>
|
<legend>{{localize "TYPES.Item.subclass"}}</legend>
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,16 @@
|
||||||
>
|
>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}}</legend>
|
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}}</legend>
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=source.system.foundationFeature}}
|
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='foundationFeature' feature=source.system.foundationFeature}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}}</legend>
|
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}}</legend>
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=source.system.specializationFeature}}
|
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='specializationFeature' feature=source.system.specializationFeature}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}}</legend>
|
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}}</legend>
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=source.system.masteryFeature}}
|
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='masteryFeature' feature=source.system.masteryFeature}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</section>
|
</section>
|
||||||
30
templates/sheets/items/subclass/parts/subclass-feature.hbs
Normal file
30
templates/sheets/items/subclass/parts/subclass-feature.hbs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<li class='feature-item'>
|
||||||
|
<div class='feature-line'>
|
||||||
|
<img class='image' src='{{feature.img}}' />
|
||||||
|
<h4>{{feature.name}}</h4>
|
||||||
|
{{#unless hideContrals}}
|
||||||
|
<div class='controls'>
|
||||||
|
<a
|
||||||
|
class='effect-control'
|
||||||
|
data-action='editFeature'
|
||||||
|
data-type="{{type}}"
|
||||||
|
data-level="{{level}}"
|
||||||
|
data-feature='{{id}}'
|
||||||
|
data-tooltip='{{localize "DAGGERHEART.Tooltip.openItemWorld"}}'
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-globe"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class='effect-control'
|
||||||
|
data-action='deleteFeature'
|
||||||
|
data-type="{{type}}"
|
||||||
|
data-level="{{level}}"
|
||||||
|
data-feature='{{id}}'
|
||||||
|
data-tooltip='{{localize "DAGGERHEART.Tooltip.delete"}}'
|
||||||
|
>
|
||||||
|
<i class='fas fa-trash'></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
22
templates/sheets/items/subclass/parts/subclass-features.hbs
Normal file
22
templates/sheets/items/subclass/parts/subclass-features.hbs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<div class="two-columns even">
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{localize "DAGGERHEART.Sheets.Subclass.SubclassFeature.Actions"}} <a><i class="fa-solid fa-plus icon-button" data-level="{{level}}" data-type="action" data-action="addFeature"></i></a></legend>
|
||||||
|
|
||||||
|
<div class="feature-list">
|
||||||
|
{{#each feature.actions}}
|
||||||
|
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs' level=../level type="action" id=this._id feature=this}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{localize "DAGGERHEART.Sheets.Subclass.SubclassFeature.Effects"}} <a><i class="fa-solid fa-plus icon-button" data-level="{{level}}" data-type="effect" data-action="addFeature"></i></a></legend>
|
||||||
|
|
||||||
|
<div class="feature-list">
|
||||||
|
{{#each feature.effects}}
|
||||||
|
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs' level=../level type="effect" id=this.id feature=this}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue