mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Added for Class/Subclass
This commit is contained in:
parent
18d6bd7dcf
commit
261867a4cc
11 changed files with 121 additions and 229 deletions
|
|
@ -26,7 +26,8 @@
|
|||
"adversaryMissing": "The linked adversary doesn't exist in the world.",
|
||||
"beastformInapplicable": "A beastform can only be applied to a Character.",
|
||||
"beastformAlreadyApplied": "The character already has a beastform applied!",
|
||||
"featureIsMissing": "The feature doesn't exist. You should remove it."
|
||||
"featureIsMissing": "The feature doesn't exist. You should remove it.",
|
||||
"featureIsFull": "You can only have 1 entry of this feature"
|
||||
}
|
||||
},
|
||||
"Settings": {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
*/
|
||||
static async #addFeature(_event, _button) {
|
||||
const feature = await game.items.documentClass.create({
|
||||
id: foundry.utils.randomID(),
|
||||
type: 'feature',
|
||||
name: game.i18n.localize('DAGGERHEART.General.newFeature')
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
|
||||
|
|
@ -169,71 +167,45 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
doc.sheet.render({ force: true });
|
||||
}
|
||||
|
||||
//TODO: redo this
|
||||
async selectActionType() {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||
{ types: CONFIG.DH.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
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: redo this
|
||||
getActionPath(type) {
|
||||
return type === 'hope' ? 'hopeFeatures' : 'classFeatures';
|
||||
}
|
||||
|
||||
//TODO: redo this
|
||||
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(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name),
|
||||
...cls.getSourceConfig(this.document)
|
||||
},
|
||||
{
|
||||
parent: this.document
|
||||
}
|
||||
);
|
||||
await this.document.update({ [`system.${actionPath}`]: [...this.document.system[actionPath], action] });
|
||||
}
|
||||
|
||||
//TODO: redo this
|
||||
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);
|
||||
}
|
||||
|
||||
//TODO: redo this
|
||||
static async deleteFeature(_, target) {
|
||||
const actionPath = this.getActionPath(target.dataset.type);
|
||||
const feature = await game.items.documentClass.create({
|
||||
type: 'feature',
|
||||
name: game.i18n.localize('DAGGERHEART.General.newFeature')
|
||||
});
|
||||
await this.document.update({
|
||||
[`system.${actionPath}`]: this.document.system[actionPath].filter(
|
||||
action => action._id !== target.dataset.feature
|
||||
)
|
||||
[`system.${actionPath}`]: [
|
||||
...this.document.system[actionPath].filter(x => x).map(x => x.uuid),
|
||||
feature.uuid
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
static async editFeature(_, button) {
|
||||
const target = button.closest('.feature-item');
|
||||
const actionPath = this.getActionPath(button.dataset.type);
|
||||
const feature = this.document.system[actionPath].find(x => x?.id === target.dataset.featureId);
|
||||
if (!feature) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
|
||||
return;
|
||||
}
|
||||
|
||||
feature.sheet.render(true);
|
||||
}
|
||||
|
||||
static async deleteFeature(event, button) {
|
||||
event.stopPropagation();
|
||||
const target = button.closest('.feature-item');
|
||||
const actionPath = this.getActionPath(button.dataset.type);
|
||||
|
||||
await this.document.update({
|
||||
[`system.${actionPath}`]: this.document.system[actionPath]
|
||||
.filter(feature => feature && feature.id !== target.dataset.featureId)
|
||||
.map(x => x.uuid)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||
|
||||
export default class SubclassSheet extends DHBaseItemSheet {
|
||||
/**@inheritdoc */
|
||||
|
|
@ -39,101 +37,63 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
|||
}
|
||||
};
|
||||
|
||||
//TODO redo everything below this message
|
||||
|
||||
static addFeature(_, target) {
|
||||
if (target.dataset.type === 'action') this.addAction(target.dataset.level);
|
||||
else this.addEffect(target.dataset.level);
|
||||
}
|
||||
|
||||
static async editFeature(_, target) {
|
||||
if (target.dataset.type === 'action') this.editAction(target.dataset.level, target.dataset.feature);
|
||||
else this.editEffect(target.dataset.feature);
|
||||
}
|
||||
|
||||
static async deleteFeature(_, target) {
|
||||
if (target.dataset.type === 'action') this.removeAction(target.dataset.level, target.dataset.feature);
|
||||
else this.removeEffect(target.dataset.level, target.dataset.feature);
|
||||
}
|
||||
|
||||
async #selectActionType() {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||
{ types: CONFIG.DH.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
|
||||
static async addFeature(_, target) {
|
||||
const feature = await game.items.documentClass.create({
|
||||
type: 'feature',
|
||||
name: game.i18n.localize('DAGGERHEART.General.newFeature')
|
||||
});
|
||||
}
|
||||
|
||||
async addAction(level) {
|
||||
const actionType = await this.#selectActionType();
|
||||
const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack,
|
||||
action = new cls(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
systemPath: `${level}.actions`,
|
||||
type: actionType.type,
|
||||
name: game.i18n.localize(CONFIG.DH.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);
|
||||
}
|
||||
|
||||
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
|
||||
]
|
||||
[`system.${target.dataset.type}`]: feature.uuid
|
||||
});
|
||||
}
|
||||
|
||||
async editAction(level, id) {
|
||||
const action = this.document.system[level].actions.find(x => x._id === id);
|
||||
await new DHActionConfig(action).render(true);
|
||||
static async editFeature(_, button) {
|
||||
const feature = this.document.system[button.dataset.type];
|
||||
if (!feature) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
|
||||
return;
|
||||
}
|
||||
|
||||
feature.sheet.render(true);
|
||||
}
|
||||
|
||||
async editEffect(id) {
|
||||
const effect = this.document.effects.get(id);
|
||||
effect.sheet.render(true);
|
||||
}
|
||||
static async deleteFeature(event, button) {
|
||||
event.stopPropagation();
|
||||
|
||||
async removeAction(level, id) {
|
||||
await this.document.update({
|
||||
[`system.${level}.actions`]: this.document.system[level].actions.filter(action => action._id !== id)
|
||||
[`system.${button.dataset.type}`]: null
|
||||
});
|
||||
}
|
||||
|
||||
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)
|
||||
});
|
||||
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) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
if (data.fromInternal) return;
|
||||
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (item?.type === 'feature') {
|
||||
const dropSection = event.target.closest('.drop-section');
|
||||
if (this.document.system[dropSection.dataset.type]) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsFull'));
|
||||
return;
|
||||
}
|
||||
|
||||
await this.document.update({ [`system.${dropSection.dataset.type}`]: item.uuid });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import BaseDataItem from './base.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import ActionField from '../fields/actionField.mjs';
|
||||
|
||||
export default class DHClass extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -28,8 +27,8 @@ export default class DHClass extends BaseDataItem {
|
|||
label: 'DAGGERHEART.Sheets.Class.HitPoints'
|
||||
}),
|
||||
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.Sheets.Class.Evasion' }),
|
||||
hopeFeatures: new foundry.data.fields.ArrayField(new ActionField()),
|
||||
classFeatures: new foundry.data.fields.ArrayField(new ActionField()),
|
||||
hopeFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||
classFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||
subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||
inventory: new fields.SchemaField({
|
||||
take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
import ActionField from '../fields/actionField.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
|
||||
const featureSchema = () => {
|
||||
return new foundry.data.fields.SchemaField({
|
||||
name: new foundry.data.fields.StringField({ required: true }),
|
||||
effects: new ForeignDocumentUUIDArrayField({ type: 'ActiveEffect', required: false }),
|
||||
actions: new foundry.data.fields.ArrayField(new ActionField())
|
||||
});
|
||||
};
|
||||
|
||||
export default class DHSubclass extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
static get metadata() {
|
||||
|
|
@ -31,9 +22,9 @@ export default class DHSubclass extends BaseDataItem {
|
|||
nullable: true,
|
||||
initial: null
|
||||
}),
|
||||
foundationFeature: featureSchema(),
|
||||
specializationFeature: featureSchema(),
|
||||
masteryFeature: featureSchema(),
|
||||
foundationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
||||
specializationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
||||
masteryFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
||||
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
||||
isMulticlass: new fields.BooleanField({ initial: false })
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ export const preloadHandlebarsTemplates = async function () {
|
|||
'systems/daggerheart/templates/sheets/global/partials/action-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.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/levelup/parts/selectable-card-preview.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<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|}}
|
||||
{{#each source.system.hopeFeatures as |feature|}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='hope' feature=feature}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<fieldset>
|
||||
<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">
|
||||
{{#each source.system.classFeatures as |feature index|}}
|
||||
{{#each source.system.classFeatures as |feature|}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='class' feature=feature}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,18 +3,42 @@
|
|||
data-tab='{{tabs.features.id}}'
|
||||
data-group='{{tabs.features.group}}'
|
||||
>
|
||||
<fieldset>
|
||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}}</legend>
|
||||
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='foundationFeature' feature=source.system.foundationFeature}}
|
||||
<fieldset class="drop-section" data-type="foundationFeature">
|
||||
<legend>
|
||||
{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}}
|
||||
<a {{#if source.system.foundationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="foundationFeature" class="fa-solid fa-plus icon-button {{#if source.system.foundationFeature}}disabled{{/if}}"></i></a>
|
||||
</legend>
|
||||
|
||||
<div class="feature-list">
|
||||
{{#if source.system.foundationFeature}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundationFeature' feature=source.system.foundationFeature}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}}</legend>
|
||||
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='specializationFeature' feature=source.system.specializationFeature}}
|
||||
<fieldset class="drop-section" data-type="specializationFeature">
|
||||
<legend>
|
||||
{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}}
|
||||
<a {{#if source.system.specializationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="specializationFeature" class="fa-solid fa-plus icon-button {{#if source.system.specializationFeature}}disabled{{/if}}"></i></a>
|
||||
</legend>
|
||||
|
||||
<div class="feature-list">
|
||||
{{#if source.system.specializationFeature}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specializationFeature' feature=source.system.specializationFeature}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}}</legend>
|
||||
{{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='masteryFeature' feature=source.system.masteryFeature}}
|
||||
<fieldset class="drop-section" data-type="masteryFeature">
|
||||
<legend>
|
||||
{{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}}
|
||||
<a {{#if source.system.masteryFeature}}disabled{{/if}}><i data-action="addFeature" data-type="masteryFeature" class="fa-solid fa-plus icon-button {{#if source.system.masteryFeature}}disabled{{/if}}"></i></a>
|
||||
</legend>
|
||||
|
||||
<div class="feature-list">
|
||||
{{#if source.system.masteryFeature}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='masteryFeature' feature=source.system.masteryFeature}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
</section>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<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