From c23ac61ee53994b268a48db1c9172bf821684e75 Mon Sep 17 00:00:00 2001
From: WBHarry <89362246+WBHarry@users.noreply.github.com>
Date: Sun, 31 May 2026 03:05:13 +0200
Subject: [PATCH 1/2] Corrected the data path for showing the difficulty marker
in roll chat messages (#1950)
---
templates/ui/chat/parts/roll-part.hbs | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/templates/ui/chat/parts/roll-part.hbs b/templates/ui/chat/parts/roll-part.hbs
index 14e3eaa6..cfee735f 100644
--- a/templates/ui/chat/parts/roll-part.hbs
+++ b/templates/ui/chat/parts/roll-part.hbs
@@ -12,13 +12,9 @@
{{/if}}
- {{#if roll.difficulty}}
-
- {{!-- {{#if canViewSecret}} --}}
- difficulty {{roll.difficulty}}
- {{!-- {{else}}
- {{localize (ifThen roll.success "DAGGERHEART.GENERAL.success" "DAGGERHEART.GENERAL.failure")}}
- {{/if}} --}}
+ {{#if roll.options.roll.difficulty}}
+
+ {{localize "DAGGERHEART.GENERAL.difficulty"}} {{roll.options.roll.difficulty}}
{{/if}}
From 53f15a7fdec1edb6de4a54c29029c33e0890e100 Mon Sep 17 00:00:00 2001
From: WBHarry <89362246+WBHarry@users.noreply.github.com>
Date: Sun, 31 May 2026 03:11:43 +0200
Subject: [PATCH 2/2] [Feature] NPC Actors (#1949)
---
assets/icons/documents/actors/drama-masks.svg | 1 +
daggerheart.mjs | 5 +
lang/en.json | 6 +
.../applications/sheets-configs/_module.mjs | 1 +
.../sheets-configs/npc-settings.mjs | 85 +++++++++++
module/applications/sheets/actors/_module.mjs | 1 +
module/applications/sheets/actors/npc.mjs | 136 ++++++++++++++++++
module/data/actor/_module.mjs | 4 +-
module/data/actor/npc.mjs | 43 ++++++
module/documents/actor.mjs | 8 ++
styles/less/global/tab-navigation.less | 7 +-
.../less/sheets/actors/adversary/header.less | 8 +-
.../less/sheets/actors/companion/header.less | 4 +-
.../sheets/actors/environment/header.less | 4 +-
styles/less/sheets/actors/npc/features.less | 18 +++
styles/less/sheets/actors/npc/header.less | 83 +++++++++++
styles/less/sheets/actors/npc/index.less | 3 +
styles/less/sheets/actors/npc/sheet.less | 10 ++
styles/less/sheets/index.less | 1 +
system.json | 5 +-
.../sheets-settings/npc-settings/details.hbs | 13 ++
.../sheets-settings/npc-settings/features.hbs | 29 ++++
.../sheets-settings/npc-settings/header.hbs | 3 +
templates/sheets/actors/adversary/header.hbs | 5 +-
templates/sheets/actors/companion/header.hbs | 9 +-
.../sheets/actors/environment/header.hbs | 9 +-
templates/sheets/actors/npc/features.hbs | 14 ++
templates/sheets/actors/npc/header.hbs | 40 ++++++
templates/sheets/actors/npc/navigation.hbs | 7 +
templates/sheets/actors/npc/notes.hbs | 11 ++
.../sheets/global/tabs/tab-navigation.hbs | 2 +-
.../ui/sidebar/actor-document-partial.hbs | 2 +
32 files changed, 548 insertions(+), 29 deletions(-)
create mode 100644 assets/icons/documents/actors/drama-masks.svg
create mode 100644 module/applications/sheets-configs/npc-settings.mjs
create mode 100644 module/applications/sheets/actors/npc.mjs
create mode 100644 module/data/actor/npc.mjs
create mode 100644 styles/less/sheets/actors/npc/features.less
create mode 100644 styles/less/sheets/actors/npc/header.less
create mode 100644 styles/less/sheets/actors/npc/index.less
create mode 100644 styles/less/sheets/actors/npc/sheet.less
create mode 100644 templates/sheets-settings/npc-settings/details.hbs
create mode 100644 templates/sheets-settings/npc-settings/features.hbs
create mode 100644 templates/sheets-settings/npc-settings/header.hbs
create mode 100644 templates/sheets/actors/npc/features.hbs
create mode 100644 templates/sheets/actors/npc/header.hbs
create mode 100644 templates/sheets/actors/npc/navigation.hbs
create mode 100644 templates/sheets/actors/npc/notes.hbs
diff --git a/assets/icons/documents/actors/drama-masks.svg b/assets/icons/documents/actors/drama-masks.svg
new file mode 100644
index 00000000..84307da0
--- /dev/null
+++ b/assets/icons/documents/actors/drama-masks.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/daggerheart.mjs b/daggerheart.mjs
index 363430be..23977628 100644
--- a/daggerheart.mjs
+++ b/daggerheart.mjs
@@ -196,6 +196,11 @@ Hooks.once('init', () => {
makeDefault: true,
label: sheetLabel('TYPES.Actor.environment')
});
+ Actors.registerSheet(SYSTEM.id, applications.sheets.actors.NPC, {
+ types: ['npc'],
+ makeDefault: true,
+ label: sheetLabel('TYPES.Actor.npc')
+ });
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Party, {
types: ['party'],
makeDefault: true,
diff --git a/lang/en.json b/lang/en.json
index f1841e09..9ce515d9 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -23,6 +23,7 @@
"companion": "Companion",
"adversary": "Adversary",
"environment": "Environment",
+ "npc": "NPC",
"party": "Party"
}
},
@@ -333,6 +334,11 @@
},
"newAdversary": "New Adversary"
},
+ "NPC": {
+ "FIELDS": {
+ "motives": { "label": "Motives" }
+ }
+ },
"Party": {
"Subtitle": {
"character": "{community} {ancestry} | {subclass} {class}",
diff --git a/module/applications/sheets-configs/_module.mjs b/module/applications/sheets-configs/_module.mjs
index 4b83a042..9528a424 100644
--- a/module/applications/sheets-configs/_module.mjs
+++ b/module/applications/sheets-configs/_module.mjs
@@ -2,6 +2,7 @@ export { default as ActionConfig } from './action-config.mjs';
export { default as ActionSettingsConfig } from './action-settings-config.mjs';
export { default as CharacterSettings } from './character-settings.mjs';
export { default as AdversarySettings } from './adversary-settings.mjs';
+export { default as NPCSettings } from './npc-settings.mjs';
export { default as CompanionSettings } from './companion-settings.mjs';
export { default as SettingFeatureConfig } from './setting-feature-config.mjs';
export { default as EnvironmentSettings } from './environment-settings.mjs';
diff --git a/module/applications/sheets-configs/npc-settings.mjs b/module/applications/sheets-configs/npc-settings.mjs
new file mode 100644
index 00000000..c187877c
--- /dev/null
+++ b/module/applications/sheets-configs/npc-settings.mjs
@@ -0,0 +1,85 @@
+import DHBaseActorSettings from '../sheets/api/actor-setting.mjs';
+
+/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
+
+export default class DHNPCSettings extends DHBaseActorSettings {
+ /**@inheritdoc */
+ static DEFAULT_OPTIONS = {
+ classes: ['npc-settings'],
+ position: { width: 455, height: 'auto' },
+ actions: {},
+ dragDrop: [
+ { dragSelector: null, dropSelector: '.tab.features' },
+ { dragSelector: '.feature-item', dropSelector: null }
+ ]
+ };
+
+ /**@override */
+ static PARTS = {
+ header: {
+ id: 'header',
+ template: 'systems/daggerheart/templates/sheets-settings/npc-settings/header.hbs'
+ },
+ tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
+ details: {
+ id: 'details',
+ template: 'systems/daggerheart/templates/sheets-settings/npc-settings/details.hbs'
+ },
+ features: {
+ id: 'features',
+ template: 'systems/daggerheart/templates/sheets-settings/npc-settings/features.hbs'
+ }
+ };
+
+ /** @override */
+ static TABS = {
+ primary: {
+ tabs: [{ id: 'details' }, { id: 'features' }],
+ initial: 'details',
+ labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
+ }
+ };
+
+ async _prepareContext(options) {
+ const context = await super._prepareContext(options);
+
+ const featureForms = ['passive', 'action', 'reaction'];
+ context.features = context.document.system.features.sort((a, b) =>
+ a.system.featureForm !== b.system.featureForm
+ ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
+ : a.sort - b.sort
+ );
+
+ return context;
+ }
+
+ /* -------------------------------------------- */
+
+ async _onDragStart(event) {
+ const featureItem = event.currentTarget.closest('.feature-item');
+
+ if (featureItem) {
+ const feature = this.actor.items.get(featureItem.id);
+ const featureData = { type: 'Item', uuid: feature.uuid, fromInternal: true };
+ event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
+ event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
+ }
+ }
+
+ async _onDrop(event) {
+ event.stopPropagation();
+ const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
+
+ const item = await fromUuid(data.uuid);
+ if (item?.type === 'feature') {
+ if (data.fromInternal && item.parent?.uuid === this.actor.uuid) {
+ return;
+ }
+
+ const itemData = item.toObject();
+ delete itemData._id;
+
+ await this.actor.createEmbeddedDocuments('Item', [itemData]);
+ }
+ }
+}
diff --git a/module/applications/sheets/actors/_module.mjs b/module/applications/sheets/actors/_module.mjs
index c4ea2d94..1a2bebfb 100644
--- a/module/applications/sheets/actors/_module.mjs
+++ b/module/applications/sheets/actors/_module.mjs
@@ -2,4 +2,5 @@ export { default as Adversary } from './adversary.mjs';
export { default as Character } from './character.mjs';
export { default as Companion } from './companion.mjs';
export { default as Environment } from './environment.mjs';
+export { default as NPC } from './npc.mjs';
export { default as Party } from './party.mjs';
diff --git a/module/applications/sheets/actors/npc.mjs b/module/applications/sheets/actors/npc.mjs
new file mode 100644
index 00000000..8c9048c2
--- /dev/null
+++ b/module/applications/sheets/actors/npc.mjs
@@ -0,0 +1,136 @@
+import DHBaseActorSheet from '../api/base-actor.mjs';
+
+export default class NPCSheet extends DHBaseActorSheet {
+ /** @inheritDoc */
+ static DEFAULT_OPTIONS = {
+ classes: ['npc'],
+ position: { width: 660, height: 600 },
+ window: { resizable: true },
+ actions: {},
+ window: {
+ resizable: true,
+ controls: [
+ {
+ icon: 'fa-solid fa-signature',
+ label: 'DAGGERHEART.UI.Tooltip.configureAttribution',
+ action: 'editAttribution'
+ }
+ ]
+ },
+ dragDrop: [
+ {
+ dragSelector: '[data-item-id][draggable="true"], [data-item-id] [draggable="true"]',
+ dropSelector: null
+ }
+ ]
+ };
+
+ static PARTS = {
+ header: { template: 'systems/daggerheart/templates/sheets/actors/npc/header.hbs' },
+ tabs: { template: 'systems/daggerheart/templates/sheets/actors/npc/navigation.hbs' },
+ features: {
+ template: 'systems/daggerheart/templates/sheets/actors/npc/features.hbs',
+ scrollable: ['.feature-section']
+ },
+ notes: {
+ template: 'systems/daggerheart/templates/sheets/actors/npc/notes.hbs'
+ }
+ };
+
+ /** @inheritdoc */
+ static TABS = {
+ primary: {
+ tabs: [{ id: 'notes' }, { id: 'features' }],
+ initial: 'notes',
+ labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
+ }
+ };
+
+ /** @inheritdoc */
+ _prepareTabs(group) {
+ const result = super._prepareTabs(group);
+ if (group === 'primary') {
+ result.features.empty = this.document.system.features.length === 0;
+ }
+ return result;
+ }
+
+ /** @inheritdoc */
+ async _preparePartContext(partId, context, options) {
+ context = await super._preparePartContext(partId, context, options);
+ switch (partId) {
+ case 'header':
+ await this._prepareHeaderContext(context, options);
+ break;
+ case 'features':
+ await this._prepareFeaturesContext(context, options);
+ break;
+ case 'notes':
+ await this._prepareNotesContext(context, options);
+ break;
+ }
+
+ return context;
+ }
+
+ /**
+ * Prepare render context for the Header part.
+ * @param {ApplicationRenderContext} context
+ * @param {ApplicationRenderOptions} options
+ * @returns {Promise}
+ * @protected
+ */
+ async _prepareHeaderContext(context, _options) {
+ const { system } = this.document;
+ const { TextEditor } = foundry.applications.ux;
+
+ context.description = await TextEditor.implementation.enrichHTML(system.description, {
+ secrets: this.document.isOwner,
+ relativeTo: this.document
+ });
+ }
+
+ /**
+ * Prepare render context for the Features part.
+ * @param {ApplicationRenderContext} context
+ * @param {ApplicationRenderOptions} options
+ * @returns {Promise}
+ * @protected
+ */
+ async _prepareFeaturesContext(context, _options) {
+ const featureForms = ['passive', 'action', 'reaction'];
+ context.features = this.document.system.features.sort((a, b) =>
+ a.system.featureForm !== b.system.featureForm
+ ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
+ : a.sort - b.sort
+ );
+ }
+
+ /**
+ * Prepare render context for the Biography part.
+ * @param {ApplicationRenderContext} context
+ * @param {ApplicationRenderOptions} options
+ * @returns {Promise}
+ * @protected
+ */
+ async _prepareNotesContext(context, _options) {
+ const { system } = this.document;
+ const { TextEditor } = foundry.applications.ux;
+
+ const paths = {
+ notes: 'notes'
+ };
+
+ for (const [key, path] of Object.entries(paths)) {
+ const value = foundry.utils.getProperty(system, path);
+ context[key] = {
+ field: system.schema.getField(path),
+ value,
+ enriched: await TextEditor.implementation.enrichHTML(value, {
+ secrets: this.document.isOwner,
+ relativeTo: this.document
+ })
+ };
+ }
+ }
+}
diff --git a/module/data/actor/_module.mjs b/module/data/actor/_module.mjs
index 99577620..1fe1ef3f 100644
--- a/module/data/actor/_module.mjs
+++ b/module/data/actor/_module.mjs
@@ -1,15 +1,17 @@
import DhCharacter from './character.mjs';
import DhCompanion from './companion.mjs';
import DhAdversary from './adversary.mjs';
+import DhNPC from './npc.mjs';
import DhEnvironment from './environment.mjs';
import DhParty from './party.mjs';
-export { DhCharacter, DhCompanion, DhAdversary, DhEnvironment, DhParty };
+export { DhCharacter, DhCompanion, DhAdversary, DhNPC, DhEnvironment, DhParty };
export const config = {
character: DhCharacter,
companion: DhCompanion,
adversary: DhAdversary,
+ npc: DhNPC,
environment: DhEnvironment,
party: DhParty
};
diff --git a/module/data/actor/npc.mjs b/module/data/actor/npc.mjs
new file mode 100644
index 00000000..2ccaf926
--- /dev/null
+++ b/module/data/actor/npc.mjs
@@ -0,0 +1,43 @@
+import DHNPCSettings from '../../applications/sheets-configs/npc-settings.mjs';
+import BaseDataActor from './base.mjs';
+
+export default class DhpNPC extends BaseDataActor {
+ static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.NPC'];
+
+ static get metadata() {
+ return foundry.utils.mergeObject(super.metadata, {
+ label: 'TYPES.Actor.npc',
+ type: 'npc',
+ settingSheet: DHNPCSettings,
+ hasResistances: false,
+ hasAttribution: true
+ });
+ }
+
+ static defineSchema() {
+ const fields = foundry.data.fields;
+ return {
+ ...super.defineSchema(),
+ difficulty: new fields.NumberField({
+ nullable: true,
+ initial: null,
+ integer: true,
+ label: 'DAGGERHEART.GENERAL.difficulty'
+ }),
+ description: new fields.HTMLField({ label: 'DAGGERHEART.GENERAL.description' }),
+ motives: new fields.StringField(),
+ notes: new fields.HTMLField()
+ };
+ }
+
+ /**@inheritdoc */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/actors/drama-masks.svg';
+
+ get features() {
+ return this.parent.items.filter(x => x.type === 'feature');
+ }
+
+ isItemValid(source) {
+ return super.isItemValid(source) || source.type === 'feature';
+ }
+}
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index e4c11a5c..6c462d98 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -109,6 +109,14 @@ export default class DhpActor extends Actor {
});
}
+ if (this.type === 'npc') {
+ Object.assign(update, {
+ prototypeToken: {
+ disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
+ }
+ });
+ }
+
this.updateSource(update);
}
diff --git a/styles/less/global/tab-navigation.less b/styles/less/global/tab-navigation.less
index 038a9749..3d143b4c 100755
--- a/styles/less/global/tab-navigation.less
+++ b/styles/less/global/tab-navigation.less
@@ -3,8 +3,7 @@
.daggerheart.dh-style {
.tab-navigation {
- margin: 5px 0;
- height: 40px;
+ margin: 5px 0 10px 0;
width: 100%;
.navigation-container {
@@ -21,6 +20,10 @@
a {
color: @color-text-emphatic;
+
+ &.empty:not(.active) {
+ opacity: 0.4;
+ }
}
}
}
diff --git a/styles/less/sheets/actors/adversary/header.less b/styles/less/sheets/actors/adversary/header.less
index 8bd3fcee..1e5e4fa5 100644
--- a/styles/less/sheets/actors/adversary/header.less
+++ b/styles/less/sheets/actors/adversary/header.less
@@ -35,7 +35,7 @@
.tags {
display: flex;
gap: 10px;
- padding-bottom: 16px;
+ padding-bottom: 8px;
.tag {
display: flex;
@@ -67,11 +67,5 @@
gap: 12px;
padding: 16px 0;
}
-
- .adversary-navigation {
- display: flex;
- gap: 8px;
- align-items: center;
- }
}
}
diff --git a/styles/less/sheets/actors/companion/header.less b/styles/less/sheets/actors/companion/header.less
index b4df96bf..aca789a6 100644
--- a/styles/less/sheets/actors/companion/header.less
+++ b/styles/less/sheets/actors/companion/header.less
@@ -148,10 +148,8 @@
}
.companion-navigation {
- display: flex;
- gap: 8px;
- align-items: baseline;
width: 100%;
+ padding: 0 10px;
}
}
}
diff --git a/styles/less/sheets/actors/environment/header.less b/styles/less/sheets/actors/environment/header.less
index 85471af4..da6954e0 100644
--- a/styles/less/sheets/actors/environment/header.less
+++ b/styles/less/sheets/actors/environment/header.less
@@ -138,10 +138,8 @@
}
.environment-navigation {
- display: flex;
- gap: 20px;
- align-items: baseline;
padding: 0 20px;
+
.tab-navigation {
margin-top: 0;
}
diff --git a/styles/less/sheets/actors/npc/features.less b/styles/less/sheets/actors/npc/features.less
new file mode 100644
index 00000000..107b5a06
--- /dev/null
+++ b/styles/less/sheets/actors/npc/features.less
@@ -0,0 +1,18 @@
+.application.sheet.daggerheart.actor.dh-style.npc {
+ .tab.features {
+ &.active {
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .feature-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 5%);
+ padding-bottom: 20px;
+ }
+ }
+}
diff --git a/styles/less/sheets/actors/npc/header.less b/styles/less/sheets/actors/npc/header.less
new file mode 100644
index 00000000..d49d763c
--- /dev/null
+++ b/styles/less/sheets/actors/npc/header.less
@@ -0,0 +1,83 @@
+.application.sheet.daggerheart.actor.dh-style.npc {
+ .npc-header-sheet {
+ width: 100%;
+ display: flex;
+
+ .portrait {
+ cursor: pointer;
+ width: 275px;
+
+ img {
+ height: 275px;
+ }
+ }
+
+ .tags {
+ display: flex;
+ gap: 10px;
+ padding-bottom: 8px;
+
+ .tag {
+ display: flex;
+ flex-direction: row;
+ gap: 4px;
+ justify-content: center;
+ align-items: center;
+ padding: 3px 5px;
+ font-size: var(--font-size-12);
+ font: @font-body;
+
+ background: light-dark(@dark-15, @beige-15);
+ border: 1px solid light-dark(@dark, @beige);
+ border-radius: 3px;
+ }
+
+ .label {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ font-size: var(--font-size-12);
+ }
+ }
+
+ .info-section {
+ flex: 1;
+ padding: 0 15px;
+ padding-top: var(--header-height);
+ display: flex;
+ flex-direction: column;
+
+ .name-row {
+ display: flex;
+ gap: 5px;
+ align-items: center;
+ justify-content: space-between;
+ padding: 8px 0;
+
+ h1 {
+ display: flex;
+ flex: 1;
+ padding: 6px 0 0 0;
+ font-size: var(--font-size-32);
+ text-align: start;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+ word-break: break-word;
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @golden);
+ }
+ }
+ }
+
+ .npc-info {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ padding: 16px 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/styles/less/sheets/actors/npc/index.less b/styles/less/sheets/actors/npc/index.less
new file mode 100644
index 00000000..2d7d54e3
--- /dev/null
+++ b/styles/less/sheets/actors/npc/index.less
@@ -0,0 +1,3 @@
+@import './sheet.less';
+@import './header.less';
+@import './features.less';
\ No newline at end of file
diff --git a/styles/less/sheets/actors/npc/sheet.less b/styles/less/sheets/actors/npc/sheet.less
new file mode 100644
index 00000000..8ba3b7a9
--- /dev/null
+++ b/styles/less/sheets/actors/npc/sheet.less
@@ -0,0 +1,10 @@
+.application.sheet.daggerheart.actor.dh-style.npc {
+ .window-content {
+ display: grid;
+ grid-template-rows: auto auto 1fr;
+ }
+
+ .npc-navigation {
+ padding: 0 15px;
+ }
+}
\ No newline at end of file
diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less
index ca1bc840..4312f755 100644
--- a/styles/less/sheets/index.less
+++ b/styles/less/sheets/index.less
@@ -6,6 +6,7 @@
@import './actors/character/index.less';
@import './actors/companion/index.less';
@import './actors/environment/index.less';
+@import './actors/npc/index.less';
@import './actors/party/index.less';
@import './items/beastform.less';
diff --git a/system.json b/system.json
index 2acd7570..89320768 100644
--- a/system.json
+++ b/system.json
@@ -244,11 +244,14 @@
"adversary": {
"htmlFields": ["notes", "description"]
},
+ "npc": {
+ "htmlFields": ["notes"]
+ },
"environment": {
"htmlFields": ["notes", "description"]
},
"party": {
- "htmlFields": ["notes"]
+ "htmlFields": ["notes", "description"]
}
},
"Item": {
diff --git a/templates/sheets-settings/npc-settings/details.hbs b/templates/sheets-settings/npc-settings/details.hbs
new file mode 100644
index 00000000..0e18b488
--- /dev/null
+++ b/templates/sheets-settings/npc-settings/details.hbs
@@ -0,0 +1,13 @@
+
+
+ {{localize "DAGGERHEART.GENERAL.description"}}
+ {{formInput systemFields.description value=document._source.system.description}}
+
+
+ {{formGroup systemFields.motives value=document._source.system.motives}}
+ {{formGroup systemFields.difficulty value=document._source.system.difficulty localize=true}}
+
diff --git a/templates/sheets-settings/npc-settings/features.hbs b/templates/sheets-settings/npc-settings/features.hbs
new file mode 100644
index 00000000..2f2f5f47
--- /dev/null
+++ b/templates/sheets-settings/npc-settings/features.hbs
@@ -0,0 +1,29 @@
+
+
+ {{localize "DOCUMENT.New" type=(localize "TYPES.Item.feature")}}
+
+
+ {{localize tabs.features.label}}
+
+ {{#each @root.features as |feature|}}
+
+
+
+ {{feature.name}}
+
+
+
+ {{/each}}
+
+
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}}
+
+
+
\ No newline at end of file
diff --git a/templates/sheets-settings/npc-settings/header.hbs b/templates/sheets-settings/npc-settings/header.hbs
new file mode 100644
index 00000000..c9cb60fe
--- /dev/null
+++ b/templates/sheets-settings/npc-settings/header.hbs
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs
index fba96980..5adc235a 100644
--- a/templates/sheets/actors/adversary/header.hbs
+++ b/templates/sheets/actors/adversary/header.hbs
@@ -44,10 +44,9 @@
-
- {{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
+ {{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
-
+ {{/ 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
\ No newline at end of file
diff --git a/templates/sheets/actors/companion/header.hbs b/templates/sheets/actors/companion/header.hbs
index d10c0640..9c324709 100644
--- a/templates/sheets/actors/companion/header.hbs
+++ b/templates/sheets/actors/companion/header.hbs
@@ -50,9 +50,10 @@
- {{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
-
-
-
+ {{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
+
+
+
+ {{/ 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
\ No newline at end of file
diff --git a/templates/sheets/actors/environment/header.hbs b/templates/sheets/actors/environment/header.hbs
index 2c6bbb5a..1b4073c7 100644
--- a/templates/sheets/actors/environment/header.hbs
+++ b/templates/sheets/actors/environment/header.hbs
@@ -44,9 +44,10 @@
- {{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
-
-
-
+ {{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
+
+
+
+ {{/ 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
\ No newline at end of file
diff --git a/templates/sheets/actors/npc/features.hbs b/templates/sheets/actors/npc/features.hbs
new file mode 100644
index 00000000..3b495e74
--- /dev/null
+++ b/templates/sheets/actors/npc/features.hbs
@@ -0,0 +1,14 @@
+
+
+ {{> 'daggerheart.inventory-items'
+ title=tabs.features.label
+ type='feature'
+ collection=@root.features
+ hideContextMenu=true
+ hideModifyControls=true
+ canCreate=@root.editable
+ showActions=@root.editable
+ }}
+
+
\ No newline at end of file
diff --git a/templates/sheets/actors/npc/header.hbs b/templates/sheets/actors/npc/header.hbs
new file mode 100644
index 00000000..8dc345dc
--- /dev/null
+++ b/templates/sheets/actors/npc/header.hbs
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/templates/sheets/actors/npc/navigation.hbs b/templates/sheets/actors/npc/navigation.hbs
new file mode 100644
index 00000000..ae684f0d
--- /dev/null
+++ b/templates/sheets/actors/npc/navigation.hbs
@@ -0,0 +1,7 @@
+
+ {{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
+
+
+
+ {{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
+
\ No newline at end of file
diff --git a/templates/sheets/actors/npc/notes.hbs b/templates/sheets/actors/npc/notes.hbs
new file mode 100644
index 00000000..bc9ac3cf
--- /dev/null
+++ b/templates/sheets/actors/npc/notes.hbs
@@ -0,0 +1,11 @@
+
+ {{formInput notes.field value=notes.value enriched=notes.enriched toggled=true}}
+
+ {{#if (and showAttribution document.system.attribution.artist)}}
+ {{localize "DAGGERHEART.GENERAL.artistAttribution" artist=document.system.attribution.artist}}
+ {{/if}}
+
\ No newline at end of file
diff --git a/templates/sheets/global/tabs/tab-navigation.hbs b/templates/sheets/global/tabs/tab-navigation.hbs
index f9a31d3e..8af1f140 100755
--- a/templates/sheets/global/tabs/tab-navigation.hbs
+++ b/templates/sheets/global/tabs/tab-navigation.hbs
@@ -4,7 +4,7 @@
{{#each tabs as |tab|}}
-
+
{{localize tab.label}}
{{/each}}
diff --git a/templates/ui/sidebar/actor-document-partial.hbs b/templates/ui/sidebar/actor-document-partial.hbs
index 2a9f47fa..1bd3ff9a 100644
--- a/templates/ui/sidebar/actor-document-partial.hbs
+++ b/templates/ui/sidebar/actor-document-partial.hbs
@@ -6,6 +6,8 @@
{{name}}
{{#if (or (eq type "adversary") (eq type "environment"))}}
{{localize "DAGGERHEART.UI.Sidebar.actorDirectory.tier" tier=system.tier type=(@root.getTypeLabel this)}}
+ {{else if (eq type "npc")}}
+ {{localize "TYPES.Actor.npc"}}
{{else if (eq type "character")}}
{{localize "DAGGERHEART.UI.Sidebar.actorDirectory.character" level=system.levelData.level.current}}
{{else if (eq type "companion")}}