diff --git a/daggerheart.mjs b/daggerheart.mjs
index cc923ac6..2399ccdf 100644
--- a/daggerheart.mjs
+++ b/daggerheart.mjs
@@ -284,7 +284,6 @@ const preloadHandlebarsTemplates = async function () {
'systems/daggerheart/templates/sheets/pc/parts/heritageCard.hbs',
'systems/daggerheart/templates/sheets/pc/parts/advancementCard.hbs',
'systems/daggerheart/templates/views/parts/level.hbs',
- 'systems/daggerheart/templates/components/slider.hbs',
'systems/daggerheart/templates/components/card-preview.hbs',
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
]);
diff --git a/lang/en.json b/lang/en.json
index 2b5f2724..a18c02dd 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -816,7 +816,8 @@
"AbilityCheckTitle": "{ability} Check"
},
"AttackRoll": {
- "Title": "Attack - {attack}"
+ "Title": "Attack - {attack}",
+ "RollDamage": "Roll Damage"
},
"DamageRoll": {
"Title": "Damage - {damage}",
@@ -996,7 +997,8 @@
"Features": "Features",
"Guide": "Character Guide",
"Items": "Items",
- "Appearance": "Appearance"
+ "Appearance": "Appearance",
+ "settings": "Settings"
},
"Domains": "Domains",
"DamageThresholds": {
@@ -1010,14 +1012,14 @@
"Subclasses": "Subclasses",
"Guide": {
"Suggestions": {
- "Title": "Suggested",
+ "Title": "Suggested Equipments",
"Traits": {
"Title": "Traits"
}
},
- "SuggestedPrimaryWeaponTitle": "Suggested Primary Weapon",
- "SuggestedSecondaryWeaponTitle": "Suggested Secondary Weapon",
- "SuggestedArmorTitle": "Suggested Armor",
+ "SuggestedPrimaryWeaponTitle": "Primary Weapon",
+ "SuggestedSecondaryWeaponTitle": "Secondary Weapon",
+ "SuggestedArmorTitle": "Armor",
"Inventory": {
"Title": "Inventory",
"Take": "Take",
diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs
index 21af5efb..5c031db0 100644
--- a/module/applications/_module.mjs
+++ b/module/applications/_module.mjs
@@ -1,7 +1,7 @@
export { default as DhpPCSheet } from './sheets/pc.mjs';
export { default as DhpAdversarySheet } from './sheets/adversary.mjs';
-export { default as DhpClassSheet } from './sheets/class.mjs';
-export { default as DhpSubclass } from './sheets/subclass.mjs';
+export { default as DhpClassSheet } from './sheets/items/class.mjs';
+export { default as DhpSubclass } from './sheets/items/subclass.mjs';
export { default as DhpFeatureSheet } from './sheets/items/feature.mjs';
export { default as DhpDomainCardSheet } from './sheets/items/domainCard.mjs';
export { default as DhpAncestry } from './sheets/items/ancestry.mjs';
diff --git a/module/applications/chatMessage.mjs b/module/applications/chatMessage.mjs
index fb4cc613..a8cf6f50 100644
--- a/module/applications/chatMessage.mjs
+++ b/module/applications/chatMessage.mjs
@@ -1,19 +1,11 @@
import DhpDualityRoll from '../data/dualityRoll.mjs';
import { DualityRollColor } from '../data/settings/Appearance.mjs';
-export default class DhpChatMesssage extends ChatMessage {
+export default class DhpChatMessage extends ChatMessage {
async renderHTML() {
- if (
- this.type === 'dualityRoll' ||
- this.type === 'adversaryRoll' ||
- this.type === 'damageRoll' ||
- this.type === 'abilityUse'
- ) {
- this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
- }
-
/* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */
const html = await super.renderHTML();
+
if (
this.type === 'dualityRoll' &&
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme ===
diff --git a/module/applications/deathMove.mjs b/module/applications/deathMove.mjs
index af4a0c9c..ea2c86e6 100644
--- a/module/applications/deathMove.mjs
+++ b/module/applications/deathMove.mjs
@@ -47,12 +47,15 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/deathMove.hbs', {
- player: this.actor.name,
- title: game.i18n.localize(this.selectedMove.name),
- img: this.selectedMove.img,
- description: game.i18n.localize(this.selectedMove.description)
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/deathMove.hbs',
+ {
+ player: this.actor.name,
+ title: game.i18n.localize(this.selectedMove.name),
+ img: this.selectedMove.img,
+ description: game.i18n.localize(this.selectedMove.description)
+ }
+ )
});
cls.create(msg.toObject());
diff --git a/module/applications/downtime.mjs b/module/applications/downtime.mjs
index f1da7678..49d8b1ab 100644
--- a/module/applications/downtime.mjs
+++ b/module/applications/downtime.mjs
@@ -70,13 +70,16 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/downtime.hbs', {
- player: this.actor.name,
- title: game.i18n.localize(this.selectedActivity.name),
- img: this.selectedActivity.img,
- description: game.i18n.localize(this.selectedActivity.description),
- refreshedFeatures: refreshedFeatures
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/downtime.hbs',
+ {
+ player: this.actor.name,
+ title: game.i18n.localize(this.selectedActivity.name),
+ img: this.selectedActivity.img,
+ description: game.i18n.localize(this.selectedActivity.description),
+ refreshedFeatures: refreshedFeatures
+ }
+ )
});
cls.create(msg.toObject());
diff --git a/module/applications/sheets/adversary.mjs b/module/applications/sheets/adversary.mjs
index 54827b84..2087ea0a 100644
--- a/module/applications/sheets/adversary.mjs
+++ b/module/applications/sheets/adversary.mjs
@@ -330,15 +330,19 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
);
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ roll: roll._formula,
+ total: roll._total,
+ modifiers: modifiers,
+ diceResults: diceResults
+ };
const msg = new cls({
type: 'adversaryRoll',
- system: {
- roll: roll._formula,
- total: roll._total,
- modifiers: modifiers,
- diceResults: diceResults
- },
- content: 'systems/daggerheart/templates/chat/adversary-roll.hbs',
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/adversary-roll.hbs',
+ systemData
+ ),
rolls: [roll]
});
@@ -362,21 +366,25 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
}));
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ title: button.dataset.name,
+ origin: this.document.id,
+ roll: roll._formula,
+ advantageState,
+ total: roll._total,
+ modifiers: modifiers,
+ dice: dice,
+ targets: targets,
+ damage: { value: button.dataset.damage, type: button.dataset.damageType }
+ };
const msg = new cls({
type: 'adversaryRoll',
sound: CONFIG.sounds.dice,
- system: {
- title: button.dataset.name,
- origin: this.document.id,
- roll: roll._formula,
- advantageState,
- total: roll._total,
- modifiers: modifiers,
- dice: dice,
- targets: targets,
- damage: { value: button.dataset.damage, type: button.dataset.damageType }
- },
- content: 'systems/daggerheart/templates/chat/adversary-attack-roll.hbs',
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/adversary-attack-roll.hbs',
+ systemData
+ ),
rolls: [roll]
});
diff --git a/module/applications/sheets/class.mjs b/module/applications/sheets/class.mjs
deleted file mode 100644
index e9ec1305..00000000
--- a/module/applications/sheets/class.mjs
+++ /dev/null
@@ -1,483 +0,0 @@
-// import DhpApplicationMixin from '../daggerheart-sheet.mjs';
-// import Tagify from '@yaireo/tagify';
-
-// export default class ClassSheet extends DhpApplicationMixin(ItemSheet) {
-// static documentType = "class";
-
-// /** @override */
-// static get defaultOptions() {
-// return foundry.utils.mergeObject(super.defaultOptions, {
-// classes: ["daggerheart", "sheet", "class"],
-// width: 600,
-// height: 'auto',
-// resizable: false,
-// tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }],
-// dragDrop: [
-// { dragSelector: '.suggested-item', dropSelector: null },
-// { dragSelector: null, dropSelector: '.take-section' },
-// { dragSelector: null, dropSelector: '.choice-a-section' },
-// { dragSelector: null, dropSelector: '.choice-b-section' },
-// { dragSelector: null, dropSelector: '.primary-weapon-section' },
-// { dragSelector: null, dropSelector: '.secondary-weapon-section' },
-// { dragSelector: null, dropSelector: '.armor-section' },
-// { dragSelector: null, dropSelector: null },
-// ]
-// });
-// }
-
-// /** @override */
-// async getData() {
-// const context = super.getData();
-// context.domains = this.object.system.domains.map(x => SYSTEM.DOMAIN.domains[x].name)
-
-// return context;
-// }
-
-// activateListeners(html){
-// super.activateListeners(html);
-
-// const domainInput = $(html).find('.domain-input')[0];
-// const domainTagify = new Tagify(domainInput, {
-// tagTextProp: "name",
-// enforceWhitelist: true,
-// whitelist : Object.keys(SYSTEM.DOMAIN.domains).map(key => {
-// const domain = SYSTEM.DOMAIN.domains[key];
-// return { value: key, name: game.i18n.localize(domain.name), src: domain.src, background: domain.background };
-// }),
-// maxTags: 2,
-// callbacks : { invalid: this.onAddTag },
-// dropdown : {
-// mapValueTo: 'name',
-// searchKeys: ['name'],
-// enabled: 0,
-// maxItems: 20,
-// closeOnSelect : true,
-// highlightFirst: false,
-// },
-// templates: {
-// tag(tagData){ //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips?
-// return `
-//
-//
-//
${tagData[this.settings.tagTextProp] || tagData.value}
-//
-//
-// `;
-// }}
-// });
-
-// domainTagify.on('change', this.onDomainSelect.bind(this));
-// }
-
-// onAddTag(e){
-// if( e.detail.index ===2 ){
-// ui.notifications.info(game.i18n.localize("DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains"));
-// }
-// }
-
-// async onDomainSelect(event) {
-// const domains = event.detail?.value ? JSON.parse(event.detail.value) : [];
-// await this.object.update({ "system.domains": domains.map(x => x.value) });
-// this.render(true);
-// }
-
-// async _handleAction(action, event, button) {
-// switch(action){
-// case 'removeSubclass':
-// await this.removeSubclass(button);
-// break;
-// case 'viewSubclass':
-// await this.viewSubclass(button);
-// break;
-// case 'removeFeature':
-// await this.removeFeature(button);
-// break;
-// case 'viewFeature':
-// await this.viewFeature(button);
-// break;
-// case 'removeItem':
-// await this.removeItem(event);
-// break;
-// case 'viewItem':
-// await this.viewItem(button);
-// break;
-// case 'removePrimaryWeapon':
-// await this.removePrimaryWeapon(event);
-// break;
-// case 'removeSecondaryWeapon':
-// await this.removeSecondaryWeapon(event);
-// break;
-// case 'removeArmor':
-// await this.removeArmor(event);
-// break;
-// }
-// }
-
-// async removeSubclass(button){
-// await this.object.update({ "system.subclasses": this.object.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)});
-// }
-
-// async viewSubclass(button){
-// const subclass = await fromUuid(button.dataset.subclass);
-// subclass.sheet.render(true);
-// }
-
-// async removeFeature(button){
-// await this.object.update({ "system.features": this.object.system.features.filter(x => x.uuid !== button.dataset.feature)});
-// }
-
-// async viewFeature(button){
-// const feature = await fromUuid(button.dataset.feature);
-// feature.sheet.render(true);
-// }
-
-// async removeItem(event){
-// event.stopPropagation();
-// const type = event.currentTarget.dataset.type;
-// const path = `system.inventory.${type}`;
-// await this.object.update({ [path]: this.object.system.inventory[type].filter(x => x.uuid !== event.currentTarget.dataset.item)});
-// }
-
-// async viewItem(button){
-// const item = await fromUuid(button.dataset.item);
-// item.sheet.render(true);
-// }
-
-// async removePrimaryWeapon(event){
-// event.stopPropagation();
-// await this.object.update({ "system.characterGuide.suggestedPrimaryWeapon": null }, { diff: false });
-// }
-
-// async removeSecondaryWeapon(event){
-// event.stopPropagation();
-// await this.object.update({ "system.characterGuide.suggestedSecondaryWeapon": null }, { diff: false });
-// }
-
-// async removeArmor(event){
-// event.stopPropagation();
-// await this.object.update({ "system.characterGuide.suggestedArmor": null }, { diff: false });
-// }
-
-// async _onDragStart(event){
-// if(event.currentTarget.classList.contains('suggested-item')){
-// event.dataTransfer.setData("text/plain", JSON.stringify({ type: 'Item', uuid: event.currentTarget.dataset.item }));
-// }
-
-// super._onDragStart(event);
-// }
-
-// async _onDrop(event) {
-// const data = TextEditor.getDragEventData(event);
-// const item = await fromUuid(data.uuid);
-// if(item.type === 'subclass') {
-// await this.object.update({ "system.subclasses": [...this.object.system.subclasses, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// else if(item.type === 'feature') {
-
-// await this.object.update({ "system.features": [...this.object.system.features, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// else if(item.type === 'weapon'){
-// if(event.currentTarget.classList.contains('primary-weapon-section')){
-// if(!this.object.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary) await this.object.update({ "system.characterGuide.suggestedPrimaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } });
-// } else if(event.currentTarget.classList.contains('secondary-weapon-section')){
-// if(!this.object.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary) await this.object.update({ "system.characterGuide.suggestedSecondaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } });
-// }
-// }
-// else if(item.type === 'armor'){
-// if(event.currentTarget.classList.contains('armor-section')){
-// if(!this.object.system.characterGuide.suggestedArmor) await this.object.update({ "system.characterGuide.suggestedArmor": { img: item.img, name: item.name, uuid: item.uuid } });
-// }
-// }
-// else if(event.currentTarget.classList.contains('choice-a-section')){
-// if(item.type === 'miscellaneous' || item.type === 'consumable'){
-// if(this.object.system.inventory.choiceA.length < 2) await this.object.update({ "system.inventory.choiceA": [...this.object.system.inventory.choiceA, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// }
-// else if(item.type === 'miscellaneous'){
-// if(event.currentTarget.classList.contains('take-section')){
-// if(this.object.system.inventory.take.length < 3) await this.object.update({ "system.inventory.take": [...this.object.system.inventory.take, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// else if(event.currentTarget.classList.contains('choice-b-section')){
-// if(this.object.system.inventory.choiceB.length < 2) await this.object.update({ "system.inventory.choiceB": [...this.object.system.inventory.choiceB, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// }
-// }
-// }
-
-import DaggerheartSheet from './daggerheart-sheet.mjs';
-import Tagify from '@yaireo/tagify';
-
-const { ItemSheetV2 } = foundry.applications.sheets;
-const { TextEditor } = foundry.applications.ux;
-export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
- static DEFAULT_OPTIONS = {
- tag: 'form',
- classes: ['daggerheart', 'sheet', 'class'],
- position: { width: 600 },
- actions: {
- removeSubclass: this.removeSubclass,
- viewSubclass: this.viewSubclass,
- removeFeature: this.removeFeature,
- viewFeature: this.viewFeature,
- removeItem: this.removeItem,
- viewItem: this.viewItem,
- removePrimaryWeapon: this.removePrimaryWeapon,
- removeSecondaryWeapon: this.removeSecondaryWeapon,
- removeArmor: this.removeArmor
- },
- form: {
- handler: this.updateForm,
- submitOnChange: true,
- closeOnSubmit: false
- },
- dragDrop: [
- { dragSelector: '.suggested-item', dropSelector: null },
- { dragSelector: null, dropSelector: '.take-section' },
- { dragSelector: null, dropSelector: '.choice-a-section' },
- { dragSelector: null, dropSelector: '.choice-b-section' },
- { dragSelector: null, dropSelector: '.primary-weapon-section' },
- { dragSelector: null, dropSelector: '.secondary-weapon-section' },
- { dragSelector: null, dropSelector: '.armor-section' },
- { dragSelector: null, dropSelector: null }
- ]
- };
-
- static PARTS = {
- form: {
- id: 'feature',
- template: 'systems/daggerheart/templates/sheets/class.hbs'
- }
- };
-
- _getTabs() {
- const tabs = {
- features: {
- active: true,
- cssClass: '',
- group: 'primary',
- id: 'features',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Features')
- },
- guide: {
- active: false,
- cssClass: '',
- group: 'primary',
- id: 'guide',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Guide')
- }
- };
- for (const v of Object.values(tabs)) {
- v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
- v.cssClass = v.active ? 'active' : '';
- }
-
- return tabs;
- }
-
- _attachPartListeners(partId, htmlElement, options) {
- super._attachPartListeners(partId, htmlElement, options);
-
- const domainInput = htmlElement.querySelector('.domain-input');
- const domainTagify = new Tagify(domainInput, {
- tagTextProp: 'name',
- enforceWhitelist: true,
- whitelist: Object.keys(SYSTEM.DOMAIN.domains).map(key => {
- const domain = SYSTEM.DOMAIN.domains[key];
- return {
- value: key,
- name: game.i18n.localize(domain.label),
- src: domain.src,
- background: domain.background
- };
- }),
- maxTags: 2,
- callbacks: { invalid: this.onAddTag },
- dropdown: {
- mapValueTo: 'name',
- searchKeys: ['name'],
- enabled: 0,
- maxItems: 20,
- closeOnSelect: true,
- highlightFirst: false
- },
- templates: {
- tag(tagData) {
- //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips?
- return `
-
-
-
${tagData[this.settings.tagTextProp] || tagData.value}
-
-
- `;
- }
- }
- });
-
- domainTagify.on('change', this.onDomainSelect.bind(this));
- }
-
- async _prepareContext(_options) {
- const context = await super._prepareContext(_options);
- context.document = this.document;
- context.tabs = this._getTabs();
- context.domains = this.document.system.domains.map(x => SYSTEM.DOMAIN.domains[x].label);
-
- return context;
- }
-
- static async updateForm(event, _, formData) {
- await this.document.update(formData.object);
- this.render();
- }
-
- onAddTag(e) {
- if (e.detail.index === 2) {
- ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains'));
- }
- }
-
- async onDomainSelect(event) {
- const domains = event.detail?.value ? JSON.parse(event.detail.value) : [];
- await this.document.update({ 'system.domains': domains.map(x => x.value) });
- this.render(true);
- }
-
- static async removeSubclass(_, button) {
- await this.document.update({
- 'system.subclasses': this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)
- });
- }
-
- static async viewSubclass(_, button) {
- const subclass = await fromUuid(button.dataset.subclass);
- subclass.sheet.render(true);
- }
-
- static async removeFeature(_, button) {
- await this.document.update({
- 'system.features': this.document.system.features.filter(x => x.uuid !== button.dataset.feature)
- });
- }
-
- static async viewFeature(_, button) {
- const feature = await fromUuid(button.dataset.feature);
- feature.sheet.render(true);
- }
-
- static async removeItem(event, button) {
- event.stopPropagation();
- const type = button.dataset.type;
- const path = `system.inventory.${type}`;
- await this.document.update({
- [path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item)
- });
- }
-
- static async viewItem(_, button) {
- const item = await fromUuid(button.dataset.item);
- item.sheet.render(true);
- }
-
- static async removePrimaryWeapon(event) {
- event.stopPropagation();
- await this.document.update({ 'system.characterGuide.suggestedPrimaryWeapon': null }, { diff: false });
- }
-
- static async removeSecondaryWeapon(event) {
- event.stopPropagation();
- await this.document.update({ 'system.characterGuide.suggestedSecondaryWeapon': null }, { diff: false });
- }
-
- static async removeArmor(event) {
- event.stopPropagation();
- await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false });
- }
-
- async _onDrop(event) {
- const data = TextEditor.getDragEventData(event);
- const item = await fromUuid(data.uuid);
- if (item.type === 'subclass') {
- await this.document.update({
- 'system.subclasses': [
- ...this.document.system.subclasses,
- { img: item.img, name: item.name, uuid: item.uuid }
- ]
- });
- } else if (item.type === 'feature') {
- await this.document.update({
- 'system.features': [
- ...this.document.system.features,
- { img: item.img, name: item.name, 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)
- await this.document.update({
- 'system.characterGuide.suggestedPrimaryWeapon': {
- img: item.img,
- name: item.name,
- uuid: item.uuid
- }
- });
- } else if (event.currentTarget.classList.contains('secondary-weapon-section')) {
- if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary)
- await this.document.update({
- 'system.characterGuide.suggestedSecondaryWeapon': {
- img: item.img,
- name: item.name,
- uuid: item.uuid
- }
- });
- }
- } else if (item.type === 'armor') {
- if (event.currentTarget.classList.contains('armor-section')) {
- if (!this.document.system.characterGuide.suggestedArmor)
- await this.document.update({
- 'system.characterGuide.suggestedArmor': { img: item.img, name: item.name, uuid: item.uuid }
- });
- }
- } else if (event.currentTarget.classList.contains('choice-a-section')) {
- if (item.type === 'miscellaneous' || item.type === 'consumable') {
- if (this.document.system.inventory.choiceA.length < 2)
- await this.document.update({
- 'system.inventory.choiceA': [
- ...this.document.system.inventory.choiceA,
- { img: item.img, name: item.name, uuid: item.uuid }
- ]
- });
- }
- } else if (item.type === 'miscellaneous') {
- if (event.currentTarget.classList.contains('take-section')) {
- if (this.document.system.inventory.take.length < 3)
- await this.document.update({
- 'system.inventory.take': [
- ...this.document.system.inventory.take,
- { img: item.img, name: item.name, uuid: item.uuid }
- ]
- });
- } else if (event.currentTarget.classList.contains('choice-b-section')) {
- if (this.document.system.inventory.choiceB.length < 2)
- await this.document.update({
- 'system.inventory.choiceB': [
- ...this.document.system.inventory.choiceB,
- { img: item.img, name: item.name, uuid: item.uuid }
- ]
- });
- }
- }
- }
-}
diff --git a/module/applications/sheets/environment.mjs b/module/applications/sheets/environment.mjs
index 80295b05..8799d41a 100644
--- a/module/applications/sheets/environment.mjs
+++ b/module/applications/sheets/environment.mjs
@@ -123,10 +123,15 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/ability-use.hbs', {
- title: game.i18n.format('DAGGERHEART.Chat.EnvironmentTitle', { actionType: button.dataset.actionType }),
- card: { name: item.name, img: item.img, description: item.system.description }
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ {
+ title: game.i18n.format('DAGGERHEART.Chat.EnvironmentTitle', {
+ actionType: button.dataset.actionType
+ }),
+ card: { name: item.name, img: item.img, description: item.system.description }
+ }
+ )
});
cls.create(msg.toObject());
diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs
new file mode 100644
index 00000000..2241a715
--- /dev/null
+++ b/module/applications/sheets/items/class.mjs
@@ -0,0 +1,270 @@
+import DaggerheartSheet from '../daggerheart-sheet.mjs';
+import Tagify from '@yaireo/tagify';
+
+const { ItemSheetV2 } = foundry.applications.sheets;
+const { TextEditor } = foundry.applications.ux;
+export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
+ static DEFAULT_OPTIONS = {
+ tag: 'form',
+ classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'class'],
+ position: { width: 700 },
+ actions: {
+ removeSubclass: this.removeSubclass,
+ viewSubclass: this.viewSubclass,
+ removeFeature: this.removeFeature,
+ viewFeature: this.viewFeature,
+ removeItem: this.removeItem,
+ viewItem: this.viewItem,
+ removePrimaryWeapon: this.removePrimaryWeapon,
+ removeSecondaryWeapon: this.removeSecondaryWeapon,
+ removeArmor: this.removeArmor
+ },
+ form: {
+ handler: this.updateForm,
+ submitOnChange: true,
+ closeOnSubmit: false
+ },
+ dragDrop: [
+ { dragSelector: '.suggested-item', dropSelector: null },
+ { dragSelector: null, dropSelector: '.take-section' },
+ { dragSelector: null, dropSelector: '.choice-a-section' },
+ { dragSelector: null, dropSelector: '.choice-b-section' },
+ { dragSelector: null, dropSelector: '.primary-weapon-section' },
+ { dragSelector: null, dropSelector: '.secondary-weapon-section' },
+ { dragSelector: null, dropSelector: '.armor-section' },
+ { dragSelector: null, dropSelector: null }
+ ]
+ };
+
+ static PARTS = {
+ header: { template: 'systems/daggerheart/templates/sheets/items/class/header.hbs' },
+ tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
+ features: {
+ template: 'systems/daggerheart/templates/sheets/items/class/features.hbs',
+ scrollable: ['.features']
+ },
+ settings: {
+ template: 'systems/daggerheart/templates/sheets/items/class/settings.hbs',
+ scrollable: ['.settings']
+ }
+ };
+
+ static TABS = {
+ features: {
+ active: true,
+ cssClass: '',
+ group: 'primary',
+ id: 'features',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.Class.Tabs.Features'
+ },
+ settings: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'settings',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.Class.Tabs.settings'
+ }
+ };
+
+ _attachPartListeners(partId, htmlElement, options) {
+ super._attachPartListeners(partId, htmlElement, options);
+
+ const domainInput = htmlElement.querySelector('.domain-input');
+ const domainTagify = new Tagify(domainInput, {
+ tagTextProp: 'name',
+ enforceWhitelist: true,
+ whitelist: Object.keys(SYSTEM.DOMAIN.domains).map(key => {
+ const domain = SYSTEM.DOMAIN.domains[key];
+ return {
+ value: key,
+ name: game.i18n.localize(domain.label),
+ src: domain.src,
+ background: domain.background
+ };
+ }),
+ maxTags: 2,
+ callbacks: { invalid: this.onAddTag },
+ dropdown: {
+ mapValueTo: 'name',
+ searchKeys: ['name'],
+ enabled: 0,
+ maxItems: 20,
+ closeOnSelect: true,
+ highlightFirst: false
+ },
+ templates: {
+ tag(tagData) {
+ //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips?
+ return `
+
+
+
${tagData[this.settings.tagTextProp] || tagData.value}
+
+
+ `;
+ }
+ }
+ });
+
+ domainTagify.on('change', this.onDomainSelect.bind(this));
+ }
+
+ async _prepareContext(_options) {
+ const context = await super._prepareContext(_options);
+ context.document = this.document;
+ context.tabs = super._getTabs(this.constructor.TABS);
+ context.domains = this.document.system.domains.map(x => SYSTEM.DOMAIN.domains[x].label);
+
+ return context;
+ }
+
+ static async updateForm(event, _, formData) {
+ await this.document.update(formData.object);
+ this.render();
+ }
+
+ onAddTag(e) {
+ if (e.detail.index === 2) {
+ ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains'));
+ }
+ }
+
+ async onDomainSelect(event) {
+ const domains = event.detail?.value ? JSON.parse(event.detail.value) : [];
+ await this.document.update({ 'system.domains': domains.map(x => x.value) });
+ this.render(true);
+ }
+
+ static async removeSubclass(_, button) {
+ await this.document.update({
+ 'system.subclasses': this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)
+ });
+ }
+
+ static async viewSubclass(_, button) {
+ const subclass = await fromUuid(button.dataset.subclass);
+ subclass.sheet.render(true);
+ }
+
+ static async removeFeature(_, button) {
+ await this.document.update({
+ 'system.features': this.document.system.features.filter(x => x.uuid !== button.dataset.feature)
+ });
+ }
+
+ static async viewFeature(_, button) {
+ const feature = await fromUuid(button.dataset.feature);
+ feature.sheet.render(true);
+ }
+
+ static async removeItem(event, button) {
+ event.stopPropagation();
+ const type = button.dataset.type;
+ const path = `system.inventory.${type}`;
+ await this.document.update({
+ [path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item)
+ });
+ }
+
+ static async viewItem(_, button) {
+ const item = await fromUuid(button.dataset.item);
+ item.sheet.render(true);
+ }
+
+ static async removePrimaryWeapon(event) {
+ event.stopPropagation();
+ await this.document.update({ 'system.characterGuide.suggestedPrimaryWeapon': null }, { diff: false });
+ }
+
+ static async removeSecondaryWeapon(event) {
+ event.stopPropagation();
+ await this.document.update({ 'system.characterGuide.suggestedSecondaryWeapon': null }, { diff: false });
+ }
+
+ static async removeArmor(event) {
+ event.stopPropagation();
+ await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false });
+ }
+
+ async _onDrop(event) {
+ const data = TextEditor.getDragEventData(event);
+ const item = await fromUuid(data.uuid);
+ if (item.type === 'subclass') {
+ await this.document.update({
+ 'system.subclasses': [
+ ...this.document.system.subclasses,
+ { img: item.img, name: item.name, uuid: item.uuid }
+ ]
+ });
+ } else if (item.type === 'feature') {
+ await this.document.update({
+ 'system.features': [
+ ...this.document.system.features,
+ { img: item.img, name: item.name, 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)
+ await this.document.update({
+ 'system.characterGuide.suggestedPrimaryWeapon': {
+ img: item.img,
+ name: item.name,
+ uuid: item.uuid
+ }
+ });
+ } else if (event.currentTarget.classList.contains('secondary-weapon-section')) {
+ if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary)
+ await this.document.update({
+ 'system.characterGuide.suggestedSecondaryWeapon': {
+ img: item.img,
+ name: item.name,
+ uuid: item.uuid
+ }
+ });
+ }
+ } else if (item.type === 'armor') {
+ if (event.currentTarget.classList.contains('armor-section')) {
+ if (!this.document.system.characterGuide.suggestedArmor)
+ await this.document.update({
+ 'system.characterGuide.suggestedArmor': { img: item.img, name: item.name, uuid: item.uuid }
+ });
+ }
+ } else if (event.currentTarget.classList.contains('choice-a-section')) {
+ if (item.type === 'miscellaneous' || item.type === 'consumable') {
+ if (this.document.system.inventory.choiceA.length < 2)
+ await this.document.update({
+ 'system.inventory.choiceA': [
+ ...this.document.system.inventory.choiceA,
+ { img: item.img, name: item.name, uuid: item.uuid }
+ ]
+ });
+ }
+ } else if (item.type === 'miscellaneous') {
+ if (event.currentTarget.classList.contains('take-section')) {
+ if (this.document.system.inventory.take.length < 3)
+ await this.document.update({
+ 'system.inventory.take': [
+ ...this.document.system.inventory.take,
+ { img: item.img, name: item.name, uuid: item.uuid }
+ ]
+ });
+ } else if (event.currentTarget.classList.contains('choice-b-section')) {
+ if (this.document.system.inventory.choiceB.length < 2)
+ await this.document.update({
+ 'system.inventory.choiceB': [
+ ...this.document.system.inventory.choiceB,
+ { img: item.img, name: item.name, uuid: item.uuid }
+ ]
+ });
+ }
+ }
+ }
+}
diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs
new file mode 100644
index 00000000..d34b8a3f
--- /dev/null
+++ b/module/applications/sheets/items/subclass.mjs
@@ -0,0 +1,121 @@
+import DaggerheartSheet from '../daggerheart-sheet.mjs';
+import DaggerheartFeature from '../../../data/feature.mjs';
+
+const { ItemSheetV2 } = foundry.applications.sheets;
+const { TextEditor } = foundry.applications.ux;
+const { duplicate, getProperty } = foundry.utils;
+export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
+ static DEFAULT_OPTIONS = {
+ tag: 'form',
+ classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'subclass'],
+ position: { width: 600 },
+ window: { resizable: false },
+ actions: {
+ editAbility: this.editAbility,
+ deleteFeatureAbility: this.deleteFeatureAbility
+ },
+ form: {
+ handler: this.updateForm,
+ submitOnChange: true,
+ closeOnSubmit: false
+ },
+ dragDrop: [
+ { dragSelector: null, dropSelector: '.foundation-tab' },
+ { dragSelector: null, dropSelector: '.specialization-tab' },
+ { dragSelector: null, dropSelector: '.mastery-tab' }
+ ]
+ };
+
+ static PARTS = {
+ header: { template: 'systems/daggerheart/templates/sheets/items/subclass/header.hbs' },
+ tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
+ description: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-description.hbs' },
+ features: {
+ template: 'systems/daggerheart/templates/sheets/items/subclass/features.hbs',
+ scrollable: ['.features']
+ },
+ settings: {
+ template: 'systems/daggerheart/templates/sheets/items/subclass/settings.hbs',
+ scrollable: ['.settings']
+ }
+ };
+
+ static TABS = {
+ description: {
+ active: true,
+ cssClass: '',
+ group: 'primary',
+ id: 'description',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.Feature.Tabs.Description'
+ },
+ features: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'features',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.Feature.Tabs.Features'
+ },
+ settings: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'settings',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.Feature.Tabs.Settings'
+ }
+ };
+
+ async _prepareContext(_options) {
+ const context = await super._prepareContext(_options);
+ context.document = this.document;
+ context.config = CONFIG.daggerheart;
+ context.tabs = super._getTabs(this.constructor.TABS);
+
+ return context;
+ }
+
+ static async updateForm(event, _, formData) {
+ await this.document.update(formData.object);
+ this.render();
+ }
+
+ static async editAbility(_, button) {
+ const feature = await fromUuid(button.dataset.ability);
+ feature.sheet.render(true);
+ }
+
+ static async deleteFeatureAbility(event, button) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ 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) {
+ event.preventDefault();
+ const data = TextEditor.getDragEventData(event);
+ const item = await fromUuid(data.uuid);
+ if (!(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id)) return;
+
+ let featureField;
+ if (event.currentTarget.classList.contains('foundation-tab')) featureField = 'foundation';
+ else if (event.currentTarget.classList.contains('specialization-tab')) featureField = 'specialization';
+ else if (event.currentTarget.classList.contains('mastery-tab')) featureField = 'mastery';
+ else return;
+
+ const path = `system.${featureField}Feature.abilities`;
+ const abilities = duplicate(getProperty(this.document, path)) || [];
+ const featureData = { name: item.name, img: item.img, uuid: item.uuid };
+ abilities.push(featureData);
+
+ await this.document.update({ [path]: abilities });
+ }
+}
diff --git a/module/applications/sheets/pc.mjs b/module/applications/sheets/pc.mjs
index 5823a0fe..2d16b470 100644
--- a/module/applications/sheets/pc.mjs
+++ b/module/applications/sheets/pc.mjs
@@ -507,27 +507,33 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
);
const cls = getDocumentClass('ChatMessage');
- const msgData = {
- type: 'dualityRoll',
- sound: CONFIG.sounds.dice,
- system: {
- title: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
- ability: game.i18n.localize(abilities[button.dataset.attribute].label)
- }),
- origin: this.document.id,
- roll: roll._formula,
- modifiers: modifiers,
- hope: hope,
- fear: fear,
- advantage: advantage,
- disadvantage: disadvantage
- },
- user: game.user.id,
- content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
- rolls: [roll]
+
+ const systemContent = {
+ title: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
+ ability: game.i18n.localize(abilities[button.dataset.attribute].label)
+ }),
+ origin: this.document.id,
+ roll: roll._formula,
+ modifiers: modifiers,
+ hope: hope,
+ fear: fear,
+ advantage: advantage,
+ disadvantage: disadvantage
};
- await cls.create(msgData);
+ const msg = new cls({
+ type: 'dualityRoll',
+ sound: CONFIG.sounds.dice,
+ system: systemContent,
+ user: game.user.id,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/duality-roll.hbs',
+ systemContent
+ ),
+ rolls: [roll]
+ });
+
+ await cls.create(msg.toObject());
}
static async toggleMarks(_, button) {
@@ -601,23 +607,28 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
evasion: x.actor.system.evasion
}));
+ const systemData = {
+ title: weapon.name,
+ origin: this.document.id,
+ roll: roll._formula,
+ modifiers: modifiers,
+ hope: hope,
+ fear: fear,
+ advantage: advantage,
+ disadvantage: disadvantage,
+ damage: damage,
+ targets: targets
+ };
+
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
type: 'dualityRoll',
sound: CONFIG.sounds.dice,
- system: {
- title: weapon.name,
- origin: this.document.id,
- roll: roll._formula,
- modifiers: modifiers,
- hope: hope,
- fear: fear,
- advantage: advantage,
- disadvantage: disadvantage,
- damage: damage,
- targets: targets
- },
- content: 'systems/daggerheart/templates/chat/attack-roll.hbs',
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/attack-roll.hbs',
+ systemData
+ ),
rolls: [roll]
});
@@ -655,17 +666,21 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const card = this.document.items.find(x => x.uuid === button.dataset.key);
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ title: `${game.i18n.localize('DAGGERHEART.Chat.DomainCard.Title')} - ${capitalize(button.dataset.domain)}`,
+ img: card.img,
+ name: card.name,
+ description: card.system.effect,
+ actions: card.system.actions
+ };
const msg = new cls({
type: 'abilityUse',
user: game.user.id,
- content: 'systems/daggerheart/templates/chat/ability-use.hbs',
- system: {
- title: `${game.i18n.localize('DAGGERHEART.Chat.DomainCard.Title')} - ${capitalize(button.dataset.domain)}`,
- img: card.img,
- name: card.name,
- description: card.system.effect,
- actions: card.system.actions
- }
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ systemData
+ ),
+ system: systemData
});
cls.create(msg.toObject());
@@ -803,13 +818,16 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/ability-use.hbs', {
- title: game.i18n.localize('DAGGERHEART.Chat.FeatureTitle'),
- card: {
- name: `${feature.name} - Roll Of ${feature.system.featureType.data.numbers[index].value}`,
- img: feature.img
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ {
+ title: game.i18n.localize('DAGGERHEART.Chat.FeatureTitle'),
+ card: {
+ name: `${feature.name} - Roll Of ${feature.system.featureType.data.numbers[index].value}`,
+ img: feature.img
+ }
}
- })
+ )
});
cls.create(msg.toObject());
@@ -870,17 +888,21 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const item = await fromUuid(button.dataset.id);
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ title: game.i18n.localize('DAGGERHEART.Chat.FeatureTitle'),
+ img: item.img,
+ name: item.name,
+ description: item.system.description,
+ actions: item.system.actions
+ };
const msg = new cls({
type: 'abilityUse',
user: game.user.id,
- content: 'systems/daggerheart/templates/chat/ability-use.hbs',
- system: {
- title: game.i18n.localize('DAGGERHEART.Chat.FeatureTitle'),
- img: item.img,
- name: item.name,
- description: item.system.description,
- actions: item.system.actions
- }
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ systemData
+ ),
+ system: systemData
});
cls.create(msg.toObject());
@@ -891,22 +913,26 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const type = button.dataset.type;
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ title:
+ type === 'ancestry'
+ ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.AncestryTitle')
+ : type === 'community'
+ ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle')
+ : game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
+ img: item.img,
+ name: item.name,
+ description: item.system.description,
+ actions: []
+ };
const msg = new cls({
type: 'abilityUse',
user: game.user.id,
- system: {
- title:
- type === 'ancestry'
- ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.AncestryTitle')
- : type === 'community'
- ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle')
- : game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
- img: item.img,
- name: item.name,
- description: item.system.description,
- actions: []
- },
- content: 'systems/daggerheart/templates/chat/ability-use.hbs'
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ systemData
+ )
});
cls.create(msg.toObject());
@@ -923,10 +949,13 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/ability-use.hbs', {
- title: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
- card: { name: title, img: item.img, description: ability.description }
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ {
+ title: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
+ card: { name: title, img: item.img, description: ability.description }
+ }
+ )
});
cls.create(msg.toObject());
@@ -939,10 +968,13 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/ability-use.hbs', {
- title: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
- card: { name: item.name, img: item.img, description: item.system.description }
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ {
+ title: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
+ card: { name: item.name, img: item.img, description: item.system.description }
+ }
+ )
});
cls.create(msg.toObject());
diff --git a/module/applications/sheets/subclass.mjs b/module/applications/sheets/subclass.mjs
deleted file mode 100644
index 40128ab0..00000000
--- a/module/applications/sheets/subclass.mjs
+++ /dev/null
@@ -1,204 +0,0 @@
-// import DhpApplicationMixin from '../daggerheart-sheet.mjs';
-
-// export default class SubclassSheet extends DhpApplicationMixin(ItemSheet) {
-// static documentType = "subclass";
-
-// constructor(options){
-// super(options);
-// }
-
-// static get defaultOptions() {
-// return foundry.utils.mergeObject(super.defaultOptions, {
-// classes: ["daggerheart", "sheet", "subclass"],
-// width: 600,
-// height: 720,
-// tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "general" }],
-// dragDrop: [
-// { dragSelector: null, dropSelector: '.foundation-tab' },
-// { dragSelector: null, dropSelector: '.specialization-tab' },
-// { dragSelector: null, dropSelector: '.mastery-tab' }
-// ],
-// });
-// }
-
-// getData() {
-// const context = super.getData();
-// context.config = CONFIG.daggerheart;
-
-// return context;
-// }
-
-// async _handleAction(action, event, button) {
-// switch(action){
-// case "editAbility":
-// this.editAbility(button);
-// break;
-// case "deleteFeatureAbility":
-// this.deleteFeatureAbility(event);
-// break;
-// }
-// }
-
-// async editAbility(button){
-// const feature = await fromUuid(button.dataset.ability);
-// feature.sheet.render(true);
-// }
-
-// async deleteFeatureAbility(event){
-// event.preventDefault();
-// event.stopPropagation();
-
-// const feature = event.currentTarget.dataset.feature;
-// const newAbilities = this.item.system[`${feature}Feature`].abilities.filter(x => x.uuid !== event.currentTarget.dataset.ability);
-// const path = `system.${feature}Feature.abilities`;
-
-// await this.item.update({ [path]: newAbilities });
-// }
-
-// async _onDrop(event) {
-// const data = TextEditor.getDragEventData(event);
-// const item = await fromUuid(data.uuid);
-// if(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id) {
-// if(event.currentTarget.classList.contains('foundation-tab')){
-// await this.object.update({ "system.foundationFeature.abilities": [...this.item.system.foundationFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// else if(event.currentTarget.classList.contains('specialization-tab')){
-// await this.object.update({ "system.specializationFeature.abilities": [...this.item.system.specializationFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// else if(event.currentTarget.classList.contains('mastery-tab')){
-// await this.object.update({ "system.masteryFeature.abilities": [...this.item.system.masteryFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] });
-// }
-// }
-// }
-// }
-
-import DaggerheartSheet from './daggerheart-sheet.mjs';
-import DaggerheartFeature from '../../data/feature.mjs';
-
-const { ItemSheetV2 } = foundry.applications.sheets;
-const { TextEditor } = foundry.applications.ux;
-const { duplicate, getProperty } = foundry.utils;
-export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
- static DEFAULT_OPTIONS = {
- tag: 'form',
- classes: ['daggerheart', 'sheet', 'subclass'],
- position: { width: 600, height: 600 },
- window: { resizable: true },
- actions: {
- editAbility: this.editAbility,
- deleteFeatureAbility: this.deleteFeatureAbility
- },
- form: {
- handler: this.updateForm,
- submitOnChange: true,
- closeOnSubmit: false
- },
- dragDrop: [
- { dragSelector: null, dropSelector: '.foundation-tab' },
- { dragSelector: null, dropSelector: '.specialization-tab' },
- { dragSelector: null, dropSelector: '.mastery-tab' }
- ]
- };
-
- _getTabs() {
- const tabs = {
- general: {
- active: true,
- cssClass: '',
- group: 'primary',
- id: 'general',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.General')
- },
- foundation: {
- active: false,
- cssClass: '',
- group: 'primary',
- id: 'foundation',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Foundation')
- },
- specialization: {
- active: false,
- cssClass: '',
- group: 'primary',
- id: 'specialization',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Specialization')
- },
- mastery: {
- active: false,
- cssClass: '',
- group: 'primary',
- id: 'mastery',
- icon: null,
- label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Mastery')
- }
- };
- for (const v of Object.values(tabs)) {
- v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
- v.cssClass = v.active ? 'active' : '';
- }
-
- return tabs;
- }
-
- static PARTS = {
- form: {
- id: 'feature',
- template: 'systems/daggerheart/templates/sheets/subclass.hbs'
- }
- };
-
- async _prepareContext(_options) {
- const context = await super._prepareContext(_options);
- context.document = this.document;
- context.config = CONFIG.daggerheart;
- context.tabs = this._getTabs();
-
- return context;
- }
-
- static async updateForm(event, _, formData) {
- await this.document.update(formData.object);
- this.render();
- }
-
- static async editAbility(_, button) {
- const feature = await fromUuid(button.dataset.ability);
- feature.sheet.render(true);
- }
-
- static async deleteFeatureAbility(event, button) {
- event.preventDefault();
- event.stopPropagation();
-
- 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) {
- event.preventDefault();
- const data = TextEditor.getDragEventData(event);
- const item = await fromUuid(data.uuid);
- if (!(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id)) return;
-
- let featureField;
- if (event.currentTarget.classList.contains('foundation-tab')) featureField = 'foundation';
- else if (event.currentTarget.classList.contains('specialization-tab')) featureField = 'specialization';
- else if (event.currentTarget.classList.contains('mastery-tab')) featureField = 'mastery';
- else return;
-
- const path = `system.${featureField}Feature.abilities`;
- const abilities = duplicate(getProperty(this.document, path)) || [];
- const featureData = { name: item.name, img: item.img, uuid: item.uuid };
- abilities.push(featureData);
-
- await this.document.update({ [path]: abilities });
- }
-}
diff --git a/module/data/pc.mjs b/module/data/pc.mjs
index 62adf232..08763123 100644
--- a/module/data/pc.mjs
+++ b/module/data/pc.mjs
@@ -290,7 +290,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
get refreshableFeatures() {
return this.parent.items.reduce(
(acc, x) => {
- if (x.type === 'feature' && x.system.refreshData?.type) {
+ if (x.type === 'feature' && x.system.refreshData?.type === 'feature' && x.system.refreshData?.type) {
acc[x.system.refreshData.type].push(x);
}
diff --git a/module/dialogs/selectDialog.mjs b/module/dialogs/selectDialog.mjs
index e4792238..484979cc 100644
--- a/module/dialogs/selectDialog.mjs
+++ b/module/dialogs/selectDialog.mjs
@@ -5,9 +5,12 @@ export default class SelectDialog extends Dialog {
this.data = {
title: data.title,
buttons: data.buttons,
- content: renderTemplate('systems/daggerheart/templates/dialog/item-select.hbs', {
- items: data.choices
- })
+ content: foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/dialog/item-select.hbs',
+ {
+ items: data.choices
+ }
+ )
};
this.actor = data.actor;
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index bef6da88..ff193d93 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -240,22 +240,26 @@ export default class DhpActor extends Actor {
}
const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: title }),
+ roll: rollString,
+ damage: {
+ total: rollResult.total,
+ type: damage.type
+ },
+ dice: dice,
+ modifiers: modifiers,
+ targets: targets
+ };
const msg = new cls({
type: 'damageRoll',
user: game.user.id,
sound: CONFIG.sounds.dice,
- system: {
- title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: title }),
- roll: rollString,
- damage: {
- total: rollResult.total,
- type: damage.type
- },
- dice: dice,
- modifiers: modifiers,
- targets: targets
- },
- content: 'systems/daggerheart/templates/chat/damage-roll.hbs',
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/damage-roll.hbs',
+ systemData
+ ),
rolls: [roll]
});
@@ -349,11 +353,14 @@ export default class DhpActor extends Actor {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/damage-roll.hbs', {
- roll: roll.formula,
- total: roll.result,
- type: action.damage.type
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/damage-roll.hbs',
+ {
+ roll: roll.formula,
+ total: roll.result,
+ type: action.damage.type
+ }
+ )
});
cls.create(msg.toObject());
@@ -368,11 +375,14 @@ export default class DhpActor extends Actor {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
- content: await renderTemplate('systems/daggerheart/templates/chat/healing-roll.hbs', {
- roll: roll.formula,
- total: roll.result,
- type: action.healing.type
- })
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/healing-roll.hbs',
+ {
+ roll: roll.formula,
+ total: roll.result,
+ type: action.healing.type
+ }
+ )
});
cls.create(msg.toObject());
diff --git a/module/documents/item.mjs b/module/documents/item.mjs
index cbf3ff2b..837b5564 100644
--- a/module/documents/item.mjs
+++ b/module/documents/item.mjs
@@ -38,25 +38,28 @@ export default class DhpItem extends Item {
}, {});
// Render the document creation form
- const html = await renderTemplate('systems/daggerheart/templates/sidebar/documentCreate.hbs', {
- folders,
- name: data.name || game.i18n.format('DOCUMENT.New', { type: label }),
- folder: data.folder,
- hasFolders: folders.length >= 1,
- type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor,
- types: {
- Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous],
- Character: [
- typeObjects.class,
- typeObjects.subclass,
- typeObjects.ancestry,
- typeObjects.community,
- typeObjects.feature,
- typeObjects.domainCard
- ]
- },
- hasTypes: types.length > 1
- });
+ const html = await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/sidebar/documentCreate.hbs',
+ {
+ folders,
+ name: data.name || game.i18n.format('DOCUMENT.New', { type: label }),
+ folder: data.folder,
+ hasFolders: folders.length >= 1,
+ type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor,
+ types: {
+ Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous],
+ Character: [
+ typeObjects.class,
+ typeObjects.subclass,
+ typeObjects.ancestry,
+ typeObjects.community,
+ typeObjects.feature,
+ typeObjects.domainCard
+ ]
+ },
+ hasTypes: types.length > 1
+ }
+ );
// Render the confirmation dialog window
return Dialog.prompt({
diff --git a/styles/components.less b/styles/components.less
deleted file mode 100644
index 34292734..00000000
--- a/styles/components.less
+++ /dev/null
@@ -1,45 +0,0 @@
-.slider-container {
- position: relative;
- background: lightslategray;
-
- .slider-inner-container {
- position: absolute;
- top: 1px;
- left: -60px;
- background-color: inherit;
- color: inherit;
- border-radius: 30px;
- cursor: pointer;
- display: flex;
- align-items: center;
- height: 20px;
- width: 40px;
- padding: 0 4px;
- border: @thinBorder solid black;
-
- &:hover {
- filter: drop-shadow(0 0 3px red);
- }
-
- input:checked {
- opacity: 0;
- width: 0;
- height: 0;
-
- & + .slider-icon {
- transform: translateX(17px);
- transition: 1s;
- }
- }
-
- .slider-icon {
- position: absolute;
- left: 4px;
- height: 15px;
- width: 15px;
- border-radius: 50%;
- transition: 1s;
- transform: translateX(0);
- }
- }
-}
diff --git a/styles/daggerheart.css b/styles/daggerheart.css
index dea99a6f..e6ad610b 100755
--- a/styles/daggerheart.css
+++ b/styles/daggerheart.css
@@ -2268,9 +2268,6 @@ div.daggerheart.views.multiclass {
.daggerheart.sheet.heritage .editor {
height: 200px;
}
-.daggerheart.sheet.class .guide .guide-section {
- gap: 8px;
-}
.daggerheart.sheet.class .guide .drop-section {
width: 100%;
}
@@ -2290,18 +2287,12 @@ div.daggerheart.views.multiclass {
min-width: 24px;
}
.daggerheart.sheet.class .guide .suggested-item {
- padding: 2px 4px;
border-radius: 6px;
- border: 1px solid black;
- background: #778899;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
-.daggerheart.sheet.class .guide .suggested-item:not(:last-child) {
- margin: 4px;
-}
.daggerheart.sheet.class .guide .suggested-item img {
width: 30px;
}
@@ -2322,9 +2313,6 @@ div.daggerheart.views.multiclass {
font-size: 14px;
font-weight: bold;
}
-.daggerheart.sheet.class .guide .extra-section .extra-input {
- margin-bottom: 4px;
-}
.daggerheart.sheet.class .guide-section-title-centered {
font-weight: bold;
font-size: 18px;
@@ -2340,27 +2328,10 @@ div.daggerheart.views.multiclass {
font-size: 14px;
text-align: center;
}
-.daggerheart.sheet.class .tagify {
- background: var(--color-light-1);
- border: 1px solid var(--color-border);
- height: 34px;
- width: 100%;
- border-radius: 3px;
- margin-right: 1px;
-}
-.daggerheart.sheet.class .tagify tag div {
+.daggerheart.sheet.class .domain-section {
display: flex;
- justify-content: space-between;
align-items: center;
- height: 22px;
-}
-.daggerheart.sheet.class .tagify tag div span {
- font-weight: 400;
-}
-.daggerheart.sheet.class .tagify tag div img {
- margin-left: 8px;
- height: 20px;
- width: 20px;
+ gap: 5px;
}
.daggerheart.sheet.adversary .adversary-header-container {
position: relative;
@@ -2733,46 +2704,6 @@ div.daggerheart.views.multiclass {
background: inherit;
border: 0;
}
-.slider-container {
- position: relative;
- background: lightslategray;
-}
-.slider-container .slider-inner-container {
- position: absolute;
- top: 1px;
- left: -60px;
- background-color: inherit;
- color: inherit;
- border-radius: 30px;
- cursor: pointer;
- display: flex;
- align-items: center;
- height: 20px;
- width: 40px;
- padding: 0 4px;
- border: 1px solid black;
-}
-.slider-container .slider-inner-container:hover {
- filter: drop-shadow(0 0 3px red);
-}
-.slider-container .slider-inner-container input:checked {
- opacity: 0;
- width: 0;
- height: 0;
-}
-.slider-container .slider-inner-container input:checked + .slider-icon {
- transform: translateX(17px);
- transition: 1s;
-}
-.slider-container .slider-inner-container .slider-icon {
- position: absolute;
- left: 4px;
- height: 15px;
- width: 15px;
- border-radius: 50%;
- transition: 1s;
- transform: translateX(0);
-}
.item-button.checked {
background: green;
}
@@ -2937,6 +2868,44 @@ div.daggerheart.views.multiclass {
scrollbar-width: thin;
scrollbar-color: light-dark(#18162e, #f3c267) transparent;
}
+.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section {
+ display: grid;
+ gap: 10px;
+ grid-template-columns: 1fr 1.5fr 1.5fr;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items {
+ margin-bottom: 10px;
+ width: 100%;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child {
+ margin-bottom: 0px;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line {
+ display: grid;
+ align-items: center;
+ gap: 10px;
+ grid-template-columns: 1fr 3fr 1fr;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 {
+ font-family: 'Montserrat', sans-serif;
+ font-weight: lighter;
+ color: light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image {
+ height: 40px;
+ width: 40px;
+ object-fit: cover;
+ border-radius: 6px;
+ border: none;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls {
+ display: flex;
+ justify-content: center;
+ gap: 10px;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a {
+ text-shadow: none;
+}
@font-face {
font-family: 'Cinzel';
font-style: normal;
@@ -3149,6 +3118,7 @@ div.daggerheart.views.multiclass {
align-items: start;
gap: 10px;
min-height: 64px;
+ width: 100%;
}
.application.sheet.dh-style fieldset.two-columns {
display: grid;
@@ -3238,6 +3208,48 @@ div.daggerheart.views.multiclass {
.application.setting.dh-style footer button {
flex: 1;
}
+.system-daggerheart .tagify {
+ background: light-dark(transparent, transparent);
+ border: 1px solid light-dark(#222, #efe6d8);
+ height: 34px;
+ border-radius: 3px;
+ margin-right: 1px;
+}
+.system-daggerheart .tagify tag div {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 22px;
+}
+.system-daggerheart .tagify tag div span {
+ font-weight: 400;
+}
+.system-daggerheart .tagify tag div img {
+ margin-left: 8px;
+ height: 20px;
+ width: 20px;
+}
+.system-daggerheart .tagify__dropdown {
+ border: 1px solid light-dark(#222, #efe6d8) !important;
+}
+.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper {
+ background-image: url(../assets/parchments/dh-parchment-dark.png);
+ background-color: transparent;
+ border: 0;
+}
+.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper .tagify__dropdown__item--active {
+ background-color: light-dark(#222, #efe6d8);
+ color: var(--color-dark-3);
+}
+.system-daggerheart.theme-light .tagify__dropdown {
+ color: black;
+}
+.system-daggerheart.theme-light .tagify__dropdown .tagify__dropdown__wrapper {
+ background-image: url(../assets/parchments/dh-parchment-light.png);
+}
+.system-daggerheart.theme-light .tagify__dropdown .tagify__dropdown__item--active {
+ color: #efe6d8;
+}
.theme-light .application .component.dh-style.card.card-preview-container {
background-image: url('../assets/parchments/dh-parchment-light.png');
}
diff --git a/styles/daggerheart.less b/styles/daggerheart.less
index 7fd91e23..6e1a793f 100755
--- a/styles/daggerheart.less
+++ b/styles/daggerheart.less
@@ -6,8 +6,7 @@
@import './chat.less';
@import './item.less';
@import './application.less';
-@import './sheets//sheets.less';
-@import './components.less';
+@import './sheets/sheets.less';
@import './dialog.less';
@import './levelup.less';
@import '../node_modules/@yaireo/tagify/dist/tagify.css';
@@ -15,6 +14,7 @@
// new styles imports
@import './less/items/feature.less';
@import './less/items/domainCard.less';
+@import './less/items/class.less';
@import './less/utils/colors.less';
@import './less/utils/fonts.less';
@@ -96,14 +96,6 @@
cursor: pointer;
}
}
-
- // .window-content {
- // background: crimson;
-
- // > form, >div {
- // background: url(../ui/parchment.jpg) repeat;
- // }
- // }
}
#players {
diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less
index 9001e65e..e82d60d3 100755
--- a/styles/less/global/elements.less
+++ b/styles/less/global/elements.less
@@ -96,6 +96,7 @@
align-items: start;
gap: 10px;
min-height: 64px;
+ width: 100%;
}
&.two-columns {
@@ -212,3 +213,136 @@
}
}
}
+
+.system-daggerheart {
+ .tagify {
+ background: light-dark(transparent, transparent);
+ border: 1px solid light-dark(@dark, @beige);
+ height: 34px;
+
+ border-radius: 3px;
+ margin-right: 1px;
+
+ tag {
+ div {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 22px;
+
+ span {
+ font-weight: 400;
+ }
+
+ img {
+ margin-left: 8px;
+ height: 20px;
+ width: 20px;
+ }
+ }
+ }
+ }
+
+ .tagify__dropdown {
+ border: 1px solid light-dark(@dark, @beige) !important;
+
+ .tagify__dropdown__wrapper {
+ background-image: url(../assets/parchments/dh-parchment-dark.png);
+ background-color: transparent;
+ border: 0;
+
+ .tagify__dropdown__item--active {
+ background-color: light-dark(@dark, @beige);
+ color: var(--color-dark-3);
+ }
+ }
+ }
+
+ &.theme-light {
+ .tagify__dropdown {
+ color: black;
+
+ .tagify__dropdown__wrapper {
+ background-image: url(../assets/parchments/dh-parchment-light.png);
+ }
+
+ .tagify__dropdown__item--active {
+ color: @beige;
+ }
+ }
+ }
+}
+
+.theme-light {
+ .application {
+ .component.dh-style.card {
+ &.card-preview-container {
+ background-image: url('../assets/parchments/dh-parchment-light.png');
+
+ .preview-text-container {
+ background-image: url(../assets/parchments/dh-parchment-dark.png);
+ }
+ }
+ }
+ }
+}
+
+.application {
+ .component.dh-style {
+ &.card-preview-container {
+ border-radius: 6px;
+ border: 2px solid var(--color-tabs-border);
+ display: flex;
+ flex-direction: column;
+ aspect-ratio: 0.75;
+ background-image: url('../assets/parchments/dh-parchment-dark.png');
+
+ &.empty {
+ cursor: pointer;
+ }
+
+ .preview-image-container {
+ flex: 1;
+ border-radius: 4px 4px 0;
+ }
+
+ .preview-text-container {
+ flex: 1;
+ border-radius: 0 0 4px 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ text-align: center;
+ color: var(--color-text-selection-bg);
+ background-image: url(../assets/parchments/dh-parchment-light.png);
+ }
+
+ .preview-empty-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 1;
+
+ .preview-empty-inner-container {
+ position: relative;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+
+ .preview-add-icon {
+ font-size: 48px;
+ }
+
+ .preview-empty-subtext {
+ position: absolute;
+ bottom: -48px;
+ font-size: 18px;
+ font-variant: small-caps;
+ text-align: center;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/styles/less/items/class.css b/styles/less/items/class.css
new file mode 100644
index 00000000..19f17576
--- /dev/null
+++ b/styles/less/items/class.css
@@ -0,0 +1,132 @@
+@font-face {
+ font-family: 'Cinzel';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype');
+}
+@font-face {
+ font-family: 'Cinzel';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype');
+}
+@font-face {
+ font-family: 'Cinzel Decorative';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(https://fonts.gstatic.com/s/cinzeldecorative/v17/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf)
+ format('truetype');
+}
+@font-face {
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype');
+}
+@font-face {
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype');
+}
+.application.sheet.daggerheart.dh-style h1 {
+ font-family: 'Cinzel Decorative', serif;
+ margin: 0;
+ border: none;
+ font-weight: normal;
+}
+.application.sheet.daggerheart.dh-style h2,
+.application.sheet.daggerheart.dh-style h3 {
+ font-family: 'Cinzel', serif;
+ margin: 0;
+ border: none;
+ font-weight: normal;
+}
+.application.sheet.daggerheart.dh-style h4 {
+ font-family: 'Montserrat', sans-serif;
+ font-size: 14px;
+ border: none;
+ font-weight: 700;
+ margin: 0;
+ text-shadow: none;
+ color: #f3c267;
+ font-weight: normal;
+}
+.application.sheet.daggerheart.dh-style h5 {
+ font-size: 14px;
+ color: #f3c267;
+ margin: 0;
+ font-weight: normal;
+}
+.application.sheet.daggerheart.dh-style p,
+.application.sheet.daggerheart.dh-style span {
+ font-family: 'Montserrat', sans-serif;
+}
+.application.sheet.daggerheart.dh-style small {
+ font-family: 'Montserrat', sans-serif;
+ opacity: 0.8;
+}
+.application.sheet.daggerheart.dh-style.class .tagify {
+ background: light-dark(transparent, transparent);
+ border: 1px solid light-dark(#222, #efe6d8);
+ height: 34px;
+ border-radius: 3px;
+ margin-right: 1px;
+}
+.application.sheet.daggerheart.dh-style.class .tagify tag div {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 22px;
+}
+.application.sheet.daggerheart.dh-style.class .tagify tag div span {
+ font-weight: 400;
+}
+.application.sheet.daggerheart.dh-style.class .tagify tag div img {
+ margin-left: 8px;
+ height: 20px;
+ width: 20px;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section {
+ display: grid;
+ gap: 10px;
+ grid-template-columns: 1fr 1.5fr 1.5fr;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items {
+ margin-bottom: 10px;
+ width: 100%;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child {
+ margin-bottom: 0px;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line {
+ display: grid;
+ align-items: center;
+ gap: 10px;
+ grid-template-columns: 1fr 3fr 1fr;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 {
+ font-family: 'Montserrat', sans-serif;
+ font-weight: lighter;
+ color: light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image {
+ height: 40px;
+ width: 40px;
+ object-fit: cover;
+ border-radius: 6px;
+ border: none;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls {
+ display: flex;
+ justify-content: center;
+ gap: 10px;
+}
+.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a {
+ text-shadow: none;
+}
diff --git a/styles/less/items/class.less b/styles/less/items/class.less
new file mode 100644
index 00000000..61974778
--- /dev/null
+++ b/styles/less/items/class.less
@@ -0,0 +1,46 @@
+@import '../utils/colors.less';
+@import '../utils/fonts.less';
+
+.application.sheet.daggerheart.dh-style.class {
+ .tab.settings {
+ .fieldsets-section {
+ display: grid;
+ gap: 10px;
+ grid-template-columns: 1fr 1.5fr 1.5fr;
+ }
+
+ .list-items {
+ margin-bottom: 10px;
+ width: 100%;
+ &:last-child {
+ margin-bottom: 0px;
+ }
+ .item-line {
+ display: grid;
+ align-items: center;
+ gap: 10px;
+ grid-template-columns: 1fr 3fr 1fr;
+ h4 {
+ font-family: @font-body;
+ font-weight: lighter;
+ color: light-dark(@dark, @beige);
+ }
+ .image {
+ height: 40px;
+ width: 40px;
+ object-fit: cover;
+ border-radius: 6px;
+ border: none;
+ }
+ .controls {
+ display: flex;
+ justify-content: center;
+ gap: 10px;
+ a {
+ text-shadow: none;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/styles/sheets/class.less b/styles/sheets/class.less
index 07008699..09dafcff 100644
--- a/styles/sheets/class.less
+++ b/styles/sheets/class.less
@@ -1,119 +1,65 @@
-.daggerheart.sheet.class {
- .guide {
- .guide-section {
- gap: @fullMargin;
- }
-
- .drop-section {
- width: 100%;
-
- legend {
- margin-left: auto;
- margin-right: auto;
- font-size: 12px;
- }
-
- .drop-section-body {
- min-height: 40px;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- }
-
- .trait-input {
- text-align: center;
- min-width: 24px;
- }
-
- .suggested-item {
- padding: @smallPadding @fullPadding;
- border-radius: 6px;
- border: @thinBorder solid black;
- background: @primaryAccent;
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
-
- &:not(:last-child) {
- margin: @halfMargin;
- }
-
- img {
- width: 30px;
- }
-
- div {
- text-align: center;
- }
-
- i {
- border-radius: 50%;
- margin-right: 4px;
- font-size: 11px;
- }
- }
-
- .extra-section {
- display: flex;
- flex-direction: column;
- align-items: center;
-
- .extra-title {
- font-size: 14px;
- font-weight: bold;
- }
-
- .extra-input {
- margin-bottom: @halfMargin;
- }
- }
- }
-
- .guide-section-title-centered {
- font-weight: bold;
- font-size: 18px;
- }
-
- .inventory-section {
- width: 100%;
- border: 2px solid black;
- border-style: dotted;
- min-height: 80px;
-
- .inventory-title {
- font-weight: bold;
- font-size: 14px;
- text-align: center;
- }
- }
-
- .tagify {
- background: var(--color-light-1);
- border: 1px solid var(--color-border);
- height: 34px;
- width: 100%;
- border-radius: 3px;
- margin-right: 1px;
-
- tag {
- div {
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 22px;
-
- span {
- font-weight: 400;
- }
-
- img {
- margin-left: 8px;
- height: 20px;
- width: 20px;
- }
- }
- }
- }
+.daggerheart.sheet.class .guide .drop-section {
+ width: 100%;
+}
+.daggerheart.sheet.class .guide .drop-section legend {
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+}
+.daggerheart.sheet.class .guide .drop-section .drop-section-body {
+ min-height: 40px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.daggerheart.sheet.class .guide .trait-input {
+ text-align: center;
+ min-width: 24px;
+}
+.daggerheart.sheet.class .guide .suggested-item {
+ border-radius: 6px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+}
+.daggerheart.sheet.class .guide .suggested-item img {
+ width: 30px;
+}
+.daggerheart.sheet.class .guide .suggested-item div {
+ text-align: center;
+}
+.daggerheart.sheet.class .guide .suggested-item i {
+ border-radius: 50%;
+ margin-right: 4px;
+ font-size: 11px;
+}
+.daggerheart.sheet.class .guide .extra-section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.daggerheart.sheet.class .guide .extra-section .extra-title {
+ font-size: 14px;
+ font-weight: bold;
+}
+.daggerheart.sheet.class .guide-section-title-centered {
+ font-weight: bold;
+ font-size: 18px;
+}
+.daggerheart.sheet.class .inventory-section {
+ width: 100%;
+ border: 2px solid black;
+ border-style: dotted;
+ min-height: 80px;
+}
+.daggerheart.sheet.class .inventory-section .inventory-title {
+ font-weight: bold;
+ font-size: 14px;
+ text-align: center;
+}
+.daggerheart.sheet.class .domain-section {
+ display: flex;
+ align-items: center;
+ gap: 5px;
}
diff --git a/system.json b/system.json
index 2450788a..dd875adb 100644
--- a/system.json
+++ b/system.json
@@ -435,6 +435,35 @@
"distance": 5,
"units": "feet"
},
+ "documentTypes": {
+ "Actor": {
+ "pc": {},
+ "npc": {},
+ "adversary": {},
+ "environment": {}
+ },
+ "Item": {
+ "ancestry": {},
+ "community": {},
+ "class": {},
+ "subclass": {},
+ "feature": {},
+ "domainCard": {},
+ "miscellaneous": {},
+ "consumable": {},
+ "weapon": {},
+ "armor": {}
+ },
+ "Combat": {
+ "combat": {}
+ },
+ "ChatMessage": {
+ "dualityRoll": {},
+ "adversaryRoll": {},
+ "damageRoll": {},
+ "abilityUse": {}
+ }
+ },
"primaryTokenAttribute": "resources.health",
"secondaryTokenAttribute": "resources.stress",
"url": "https://your/hosted/system/repo/",
diff --git a/template.json b/template.json
deleted file mode 100644
index 7e6c3c67..00000000
--- a/template.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "Actor": {
- "types": ["pc", "npc", "adversary", "environment"],
- "pc": {},
- "npc": {},
- "adversary": {},
- "environment": {}
- },
- "Item": {
- "types": [
- "ancestry",
- "community",
- "class",
- "subclass",
- "feature",
- "domainCard",
- "miscellaneous",
- "consumable",
- "weapon",
- "armor",
- "test"
- ],
- "ancestry": {},
- "community": {},
- "class": {},
- "subclass": {},
- "feature": {},
- "domainCard": {},
- "miscellaneous": {},
- "consumable": {},
- "weapon": {},
- "armor": {},
- "test": {}
- },
- "Combat": {
- "types": ["combat"],
- "combat": {}
- },
- "ChatMessage": {
- "types": ["dualityRoll", "adversaryRoll", "damageRoll", "abilityUse"],
- "dualityRoll": {},
- "adversaryRoll": {},
- "damageRoll": {},
- "abilityUse": {}
- }
-}
diff --git a/templates/chat/attack-roll.hbs b/templates/chat/attack-roll.hbs
index ccc93087..4deaf45b 100644
--- a/templates/chat/attack-roll.hbs
+++ b/templates/chat/attack-roll.hbs
@@ -164,7 +164,7 @@
{{/if}}
- Roll Damage
+ {{localize "DAGGERHEART.Chat.AttackRoll.RollDamage"}}
diff --git a/templates/chat/damage-roll.hbs b/templates/chat/damage-roll.hbs
index 9097331d..7cee09ed 100644
--- a/templates/chat/damage-roll.hbs
+++ b/templates/chat/damage-roll.hbs
@@ -23,7 +23,6 @@
-
{{this.damage.total}}
{{localize "DAGGERHEART.Chat.DamageRoll.DealDamageToTargets"}}
diff --git a/templates/components/slider.hbs b/templates/components/slider.hbs
deleted file mode 100644
index 7cbf08d0..00000000
--- a/templates/components/slider.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/templates/sheets/class.hbs b/templates/sheets/class.hbs
deleted file mode 100644
index 935b1019..00000000
--- a/templates/sheets/class.hbs
+++ /dev/null
@@ -1,289 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{formField systemFields.evasion value=source.system.evasion label=(localize "DAGGERHEART.Sheets.Class.Evasion")}}
- {{!--
--}}
-
-
{{localize "DAGGERHEART.Sheets.Class.ClassFeatures"}}
-
- {{#each source.system.features as |feature index|}}
-
-
-
-
{{feature.name}}
-
-
-
-
-
-
- {{/each}}
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Subclasses"}}
-
- {{#each source.system.subclasses as |subclass index|}}
-
-
-
-
{{subclass.name}}
-
-
-
-
-
-
- {{/each}}
-
-
-
-
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Title"}}
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Traits.Title"}}
-
-
-
-
-
-
-
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedPrimaryWeaponTitle"}}
-
-
-
- {{#if source.system.characterGuide.suggestedPrimaryWeapon}}
-
-
-
{{source.system.characterGuide.suggestedPrimaryWeapon.name}}
-
-
- {{/if}}
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedSecondaryWeaponTitle"}}
-
-
-
- {{#if source.system.characterGuide.suggestedSecondaryWeapon}}
-
-
-
{{source.system.characterGuide.suggestedSecondaryWeapon.name}}
-
-
- {{/if}}
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedArmorTitle"}}
-
-
-
- {{#if source.system.characterGuide.suggestedArmor}}
-
-
-
{{source.system.characterGuide.suggestedArmor.name}}
-
-
- {{/if}}
-
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Title"}}
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Take"}}
-
-
-
- {{#each source.system.inventory.take}}
-
-
-
{{this.name}}
-
-
- {{/each}}
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.ThenChoose"}}
-
-
-
- {{#each source.system.inventory.choiceA}}
-
-
-
{{this.name}}
-
-
- {{/each}}
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.AndEither"}}
-
-
-
- {{#each source.system.inventory.choiceB}}
-
-
-
{{this.name}}
-
-
- {{/each}}
-
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Description.Title"}}
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Description.Explanation"}}
-
-
-
-
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Extra.Title"}}
-
-
-
-
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.BackgroundQuestions.Title"}}
-
-
- {{#times 3}}
-
{{localize "DAGGERHEART.Sheets.Class.Guide.BackgroundQuestions.Question"}} {{add this 1}}
-
- {{/times}}
-
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.Connections.Title"}}
-
-
-
- {{#times 3}}
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Connections.Question"}} {{add this 1}}
-
- {{/times}}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/sheets/items/class/features.hbs b/templates/sheets/items/class/features.hbs
new file mode 100644
index 00000000..dfa386d1
--- /dev/null
+++ b/templates/sheets/items/class/features.hbs
@@ -0,0 +1,49 @@
+
+
+
+ {{localize "DAGGERHEART.Sheets.Feature.Tabs.Features"}}
+
+ {{#each source.system.features as |feature index|}}
+ {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}}
+ {{/each}}
+
+
+
+
+ {{localize "TYPES.Item.subclass"}}
+
+ {{#each source.system.subclasses as |subclass index|}}
+
+
+
+
+ {{subclass.name}}
+
+
+
+
+ {{/each}}
+
+
+
\ No newline at end of file
diff --git a/templates/sheets/items/class/header.hbs b/templates/sheets/items/class/header.hbs
new file mode 100644
index 00000000..6d601987
--- /dev/null
+++ b/templates/sheets/items/class/header.hbs
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs
new file mode 100644
index 00000000..3ae98111
--- /dev/null
+++ b/templates/sheets/items/class/settings.hbs
@@ -0,0 +1,132 @@
+
+
+
+ {{localize tabs.settings.label}}
+ {{localize "DAGGERHEART.Sheets.Class.Evasion"}}
+ {{formField systemFields.evasion value=source.system.evasion}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Traits.Title"}}
+
+ {{localize "DAGGERHEART.Abilities.agility.name"}}
+
+
+ {{localize "DAGGERHEART.Abilities.strength.name"}}
+
+
+ {{localize "DAGGERHEART.Abilities.finesse.name"}}
+
+
+ {{localize "DAGGERHEART.Abilities.instinct.name"}}
+
+
+ {{localize "DAGGERHEART.Abilities.presence.name"}}
+
+
+ {{localize "DAGGERHEART.Abilities.knowledge.name"}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Title"}}
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedPrimaryWeaponTitle"}}
+
+ {{#if source.system.characterGuide.suggestedPrimaryWeapon}}
+
+
+
{{source.system.characterGuide.suggestedPrimaryWeapon.name}}
+
+
+
+
+ {{/if}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedSecondaryWeaponTitle"}}
+
+ {{#if source.system.characterGuide.suggestedSecondaryWeapon}}
+
+
+
{{source.system.characterGuide.suggestedSecondaryWeapon.name}}
+
+
+
+
+ {{/if}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedArmorTitle"}}
+
+ {{#if source.system.characterGuide.suggestedArmor}}
+
+
+
{{source.system.characterGuide.suggestedArmor.name}}
+
+
+
+
+ {{/if}}
+
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Title"}}
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Take"}}
+
+ {{#each source.system.inventory.take}}
+
+
+
{{this.name}}
+
+
+
+
+ {{/each}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.ThenChoose"}}
+
+ {{#each source.system.inventory.choiceA}}
+
+
+
{{this.name}}
+
+
+
+
+ {{/each}}
+
+
+
+
+ {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.AndEither"}}
+
+ {{#each source.system.inventory.choiceB}}
+
+
+
{{this.name}}
+
+
+
+
+ {{/each}}
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/sheets/items/subclass/features.hbs b/templates/sheets/items/subclass/features.hbs
new file mode 100644
index 00000000..eb2010c4
--- /dev/null
+++ b/templates/sheets/items/subclass/features.hbs
@@ -0,0 +1,26 @@
+
+
+ {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}}
+ {{#each source.system.foundationFeature.abilities as |feature key|}}
+ {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}}
+ {{/each}}
+
+
+
+ {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}}
+ {{#each source.system.specializationFeature.abilities as |feature key|}}
+ {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}}
+ {{/each}}
+
+
+
+ {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}}
+ {{#each source.system.masteryFeature.abilities as |feature key|}}
+ {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}}
+ {{/each}}
+
+
\ No newline at end of file
diff --git a/templates/sheets/items/subclass/header.hbs b/templates/sheets/items/subclass/header.hbs
new file mode 100644
index 00000000..4e6d10e9
--- /dev/null
+++ b/templates/sheets/items/subclass/header.hbs
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/templates/sheets/items/subclass/settings.hbs b/templates/sheets/items/subclass/settings.hbs
new file mode 100644
index 00000000..2d8c3381
--- /dev/null
+++ b/templates/sheets/items/subclass/settings.hbs
@@ -0,0 +1,12 @@
+
+
+
+ {{localize tabs.settings.label}}
+ {{localize "DAGGERHEART.Sheets.Subclass.SpellcastingTrait"}}
+ {{formField systemFields.spellcastingTrait value=source.system.spellcastingTrait localize=true}}
+
+
\ No newline at end of file
diff --git a/templates/sheets/subclass.hbs b/templates/sheets/subclass.hbs
deleted file mode 100644
index 6768a719..00000000
--- a/templates/sheets/subclass.hbs
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
- {{formField systemFields.spellcastingTrait value=source.system.spellcastingTrait label=(localize "DAGGERHEART.Sheets.Subclass.SpellcastingTrait") localize=true}}
- {{!--
--}}
-
- {{localize "DAGGERHEART.Sheets.Subclass.Description"}}
- {{formInput systemFields.description value=source.system.description enriched=source.system.description localize=true toggled=true}}
- {{!-- {{editor item.system.description target="system.description" button=true}} --}}
-
-
-
- {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.foundationFeature.fields feature=source.system.foundationFeature featureType="foundation" }}
-
-
- {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.specializationFeature.fields feature=source.system.specializationFeature featureType="specialization" }}
-
-
- {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.masteryFeature.fields feature=source.system.masteryFeature featureType="mastery" }}
-
-
-
\ No newline at end of file