Compare commits

...

11 commits

Author SHA1 Message Date
Carlos Fernandez
624e81ae36 Styling pass for scrollbars, fieldsets, and scroll shadows 2026-06-24 17:53:30 -04:00
Carlos Fernandez
1ebbad4797
[Fix] quirks involving expanding items and hovering over them (#2033)
Some checks failed
Project CI / build (24.x) (push) Has been cancelled
2026-06-24 17:37:00 -04:00
WBHarry
2c1f52413d Raised verison
Some checks are pending
Project CI / build (24.x) (push) Waiting to run
2026-06-23 23:33:29 +02:00
WBHarry
ca82cbcf66
. (#2041) 2026-06-23 23:28:04 +02:00
Carlos Fernandez
07b7c82094
Fetch origin fetch when in compendium (#2042) 2026-06-23 23:26:53 +02:00
Carlos Fernandez
958eaa310c
Simplify ActiveEffect sheet tags (#2037)
Some checks are pending
Project CI / build (24.x) (push) Waiting to run
* Simplify ActiveEffect sheet tags

* Show origin actor and exclude tag if it is a top level actor tag without origin
2026-06-23 12:22:03 +02:00
Carlos Fernandez
f5fa59b3bd
Make prosemirror editor look a bit nicer (#2034) 2026-06-23 09:40:12 +02:00
Carlos Fernandez
9f29229c94
Fix resolving formulas in weapon change effects (#2035) 2026-06-23 08:57:22 +02:00
WBHarry
329d820aab Raised version
Some checks failed
Project CI / build (24.x) (push) Has been cancelled
2026-06-22 00:26:24 +02:00
WBHarry
8e93025947
[Fix] Weapon Spellcasting Active Effects (#2032)
* .

* .

* Apply suggestion from @CarlosFdez

---------

Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
2026-06-22 00:24:33 +02:00
WBHarry
1492491998
[Fix] Reroll Countdown Automation (#2031)
* Fixed so that automated countdowns reverse progress from Fear when rerolling dice if the duality result changes

* .

* Removed overprep

* Apply suggestion from @CarlosFdez

---------

Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
2026-06-22 00:14:40 +02:00
48 changed files with 411 additions and 299 deletions

View file

@ -2010,7 +2010,8 @@
"Attachments": { "Attachments": {
"attachHint": "Drop items here to attach them", "attachHint": "Drop items here to attach them",
"transferHint": "If checked, this effect will be applied to any actor that owns this Effect's parent Item. The effect is always applied if this Item is attached to another one." "transferHint": "If checked, this effect will be applied to any actor that owns this Effect's parent Item. The effect is always applied if this Item is attached to another one."
} },
"OriginTag": "Origin: {name}"
}, },
"GENERAL": { "GENERAL": {
"Ability": { "Ability": {

View file

@ -518,7 +518,7 @@ export default function DHApplicationMixin(Base) {
const doc = await getDocFromElement(target), const doc = await getDocFromElement(target),
action = doc?.system?.attack ?? doc; action = doc?.system?.attack ?? doc;
const config = action.prepareConfig(event); const config = action.prepareConfig(event);
config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects( config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(
this.document, this.document,
doc doc
); );
@ -603,7 +603,7 @@ export default function DHApplicationMixin(Base) {
const doc = await fromUuid(itemUuid); const doc = await fromUuid(itemUuid);
//get inventory-item description element //get inventory-item description element
const descriptionElement = el.querySelector('.invetory-description'); const descriptionElement = el.querySelector('.inventory-description');
if (!doc || !descriptionElement) continue; if (!doc || !descriptionElement) continue;
// localize the description (idk if it's still necessary) // localize the description (idk if it's still necessary)

View file

@ -212,7 +212,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
const doc = await getDocFromElement(target), const doc = await getDocFromElement(target),
action = doc?.system?.attack ?? doc; action = doc?.system?.attack ?? doc;
const config = action.prepareConfig(event); const config = action.prepareConfig(event);
config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects( config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(
this.document, this.document,
doc doc
); );

View file

@ -342,29 +342,31 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
* Sends updates of the countdowns to the GM player. Since this is asynchronous, be sure to * Sends updates of the countdowns to the GM player. Since this is asynchronous, be sure to
* update all the countdowns at the same time. * update all the countdowns at the same time.
* *
* @param {...any} progressTypes Countdowns to be updated * @param {...(string | { type: string; undo?: boolean })} progressTypes Countdowns to be updated
*/ */
static async updateCountdowns(...progressTypes) { static async updateCountdowns(...progressTypes) {
progressTypes = progressTypes.map(p => typeof p === 'string' ? { type: p } : p);
const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
if (!countdownAutomation) return; if (!countdownAutomation) return;
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => { const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => {
const countdown = countdownSetting.countdowns[key]; const countdown = countdownSetting.countdowns[key];
if (progressTypes.indexOf(countdown.progress.type) !== -1 && countdown.progress.current > 0) { const progressData = progressTypes.find(x => x.type === countdown.progress.type);
acc.push(key); if (progressData && countdown.progress.current > 0) {
acc[key] = { value: progressData.undo ? 1 : -1 };
} }
return acc; return acc;
}, []); }, {});
const countdownData = countdownSetting.toObject(); const countdownData = countdownSetting.toObject();
const settings = { const settings = {
...countdownData, ...countdownData,
countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => { countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => {
const countdown = foundry.utils.deepClone(countdownData.countdowns[key]); const countdown = foundry.utils.deepClone(countdownData.countdowns[key]);
if (updatedCountdowns.includes(key)) { if (updatedCountdowns[key]) {
countdown.progress.current -= 1; countdown.progress.current += updatedCountdowns[key].value;
} }
acc[key] = countdown; acc[key] = countdown;

View file

@ -54,6 +54,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
return {}; return {};
} }
get hasDescription() {
return Boolean(this.description);
}
/** /**
* Create a Map containing each Action step based on fields define in schema. Ordered by Fields order property. * Create a Map containing each Action step based on fields define in schema. Ordered by Fields order property.
* *
@ -228,7 +232,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
let config = this.prepareConfig(event, configOptions); let config = this.prepareConfig(event, configOptions);
if (!config) return; if (!config) return;
config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects(this.actor, this.item); config.effects =
await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(this.actor, this.item);
if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return;
@ -333,27 +338,45 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
} }
/** /**
* Get the all potentially applicable effects on the actor * Get the all potentially applicable effects on the actor for the action's RollDialog
* @param {DHActor} actor The actor performing the action * @param {DHActor} actor The actor performing the action
* @param {DHItem|DhActor} effectParent The parent of the effect * @param {DHItem|DhActor} effectParent The parent of the effect
* @returns {DhActiveEffect[]} * @returns {DhActiveEffect[]}
*/ */
static async getEffects(actor, effectParent) { static async getActionRelevantEffects(actor, effectParent) {
if (!actor) return []; if (!actor) return [];
return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).filter( // Changes on weapon effects are not typically only applicable to show in the roll dialog for the weapon itself
effect => { // The exemptions to this rule are listed below
/* Effects on weapons only ever apply for the weapon itself */ const weaponTransferredEffectKeys = [
'system.bonuses.roll.spellcast.bonus'
];
const results = [];
const applicableEffects = await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true });
for (const effect of [...applicableEffects].filter(e => !e.isSuppressed)) {
if (effect.parent.type === 'weapon') { if (effect.parent.type === 'weapon') {
/* Unless they're secondary - then they apply only to other primary weapons */ // Effects on weapons only ever apply for the weapon itself (with a few exceptions)
if (effect.parent.system.secondary) { const restricted =
if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false; effect.parent.system.secondary
} else if (effectParent?.id !== effect.parent.id) return false; // Secondary applies only to other primary weapons
? effectParent?.type !== 'weapon' || effectParent?.system.secondary
// Primary only applies to itself
: effectParent?.id !== effect.parent.id;
if (restricted) {
const sourceChanges = effect._source.system.changes;
const changes = sourceChanges.filter(x => weaponTransferredEffectKeys.includes(x.key));
if (changes.length) {
results.push(effect.clone({ 'system.changes': changes }));
}
continue;
}
} }
return !effect.isSuppressed; results.push(effect);
} }
);
return results;
} }
/** /**

View file

@ -52,6 +52,10 @@ export default class DHArmor extends AttachableItem {
); );
} }
get itemFeatures() {
return this.armorFeatures;
}
/**@inheritdoc */ /**@inheritdoc */
async getDescriptionData() { async getDescriptionData() {
const baseDescription = this.description; const baseDescription = this.description;
@ -169,8 +173,4 @@ export default class DHArmor extends AttachableItem {
const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armor.max}`]; const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armor.max}`];
return labels; return labels;
} }
get itemFeatures() {
return this.armorFeatures;
}
} }

View file

@ -113,6 +113,10 @@ export default class DHWeapon extends AttachableItem {
); );
} }
get itemFeatures() {
return this.weaponFeatures;
}
/**@inheritdoc */ /**@inheritdoc */
async getDescriptionData() { async getDescriptionData() {
const baseDescription = this.description; const baseDescription = this.description;
@ -269,8 +273,4 @@ export default class DHWeapon extends AttachableItem {
return labels; return labels;
} }
get itemFeatures() {
return this.weaponFeatures;
}
} }

View file

@ -1,19 +1,28 @@
import { ResourceUpdateMap } from '../data/action/baseAction.mjs'; import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) { export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) {
const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
if (game.user.isGM ? !hopeFear.gm : !hopeFear.players) return;
const updates = [];
const hope = (newDuality >= 0 ? 1 : 0) - (oldDuality >= 0 ? 1 : 0); const hope = (newDuality >= 0 ? 1 : 0) - (oldDuality >= 0 ? 1 : 0);
const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0); const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0);
const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0); const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0);
const { hopeFear, countdownAutomation } =
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
if (game.user.isGM ? hopeFear.gm : hopeFear.players) {
const updates = [];
if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true }); if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true });
if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true }); if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true });
if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true }); if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true })
const resourceUpdates = new ResourceUpdateMap(actor); const resourceUpdates = new ResourceUpdateMap(actor);
resourceUpdates.addResources(updates); resourceUpdates.addResources(updates);
resourceUpdates.updateResources(); resourceUpdates.updateResources();
} }
if (countdownAutomation && fear !== 0) {
game.system.api.applications.ui.DhCountdowns.updateCountdowns({
type: CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id,
undo: fear === 1 ? false : true
});
}
}

View file

@ -65,6 +65,10 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
); );
} }
get hasDescription() {
return Boolean(this.description);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Event Handlers */ /* Event Handlers */
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -224,12 +228,13 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
* @returns {string[]} An array of localized tag strings. * @returns {string[]} An array of localized tag strings.
*/ */
_getTags() { _getTags() {
const tags = [ const tags = [];
`${game.i18n.localize(this.parent.system.metadata.label)}: ${this.parent.name}`, const originActor = DhActiveEffect.#resolveParentDocument(fromUuidSync(this.origin, { strict: false }), Actor);
game.i18n.localize( if (originActor && originActor !== this.actor) {
this.isTemporary ? 'DAGGERHEART.EFFECTS.Duration.temporary' : 'DAGGERHEART.EFFECTS.Duration.passive' tags.push(_loc('DAGGERHEART.EFFECTS.OriginTag', { name: originActor.name }));
) } else if (!(this.parent instanceof Actor)) {
]; tags.push(`${_loc(this.parent.system.metadata.label)}: ${this.parent.name}`);
}
for (const statusId of this.statuses) { for (const statusId of this.statuses) {
const status = CONFIG.statusEffects.find(s => s.id === statusId); const status = CONFIG.statusEffects.find(s => s.id === statusId);

View file

@ -549,7 +549,7 @@ export default class DhpActor extends Actor {
headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
ability: abilityLabel ability: abilityLabel
}), }),
effects: await game.system.api.data.actions.actionsTypes.base.getEffects(this), effects: await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(this),
roll: { roll: {
trait: trait, trait: trait,
type: 'trait' type: 'trait'

View file

@ -167,7 +167,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
if (this.system.action) { if (this.system.action) {
const actor = await foundry.utils.fromUuid(config.source.actor); const actor = await foundry.utils.fromUuid(config.source.actor);
const item = actor?.items.get(config.source.item) ?? null; const item = actor?.items.get(config.source.item) ?? null;
config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects(actor, item); config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(actor, item);
await this.system.action.workflow.get('damage')?.execute(config, this._id, true); await this.system.action.workflow.get('damage')?.execute(config, this._id, true);
} }
} }

View file

@ -46,7 +46,9 @@ export default class DhpCombat extends Combat {
for (let actor of actors) { for (let actor of actors) {
await actor.createEmbeddedDocuments( await actor.createEmbeddedDocuments(
'ActiveEffect', 'ActiveEffect',
effects.filter(x => x.effectTargetTypes.includes(actor.type)) effects
.filter(x => x.effectTargetTypes.includes(actor.type))
.map(x => foundry.utils.deepClone(x))
); );
} }
} else { } else {

View file

@ -89,6 +89,10 @@ export default class DHItem extends foundry.documents.Item {
return !pack?.locked && this.isOwner && isValidType && hasActions; return !pack?.locked && this.isOwner && isValidType && hasActions;
} }
get hasDescription() {
return Boolean(this.system.description) || Boolean(this.system.itemFeatures?.length);
}
/** @inheritdoc */ /** @inheritdoc */
static async createDialog(data = {}, createOptions = {}, options = {}) { static async createDialog(data = {}, createOptions = {}, options = {}) {
const { folders, types, template, context = {}, ...dialogOptions } = options; const { folders, types, template, context = {}, ...dialogOptions } = options;

View file

@ -261,10 +261,14 @@
fieldset { fieldset {
align-items: center; align-items: center;
margin-top: 5px;
border-radius: 6px; border-radius: 6px;
border-color: @color-fieldset-border; border-color: @color-fieldset-border;
/* Left and right side spacing is set up so that content starts at 15px left indent */
margin-top: 5px;
padding-inline: 7px;
margin-inline: 6px;
&.glassy { &.glassy {
background-color: light-dark(@dark-blue-10, @golden-10); background-color: light-dark(@dark-blue-10, @golden-10);
border-color: transparent; border-color: transparent;
@ -501,7 +505,7 @@
height: 1px; height: 1px;
width: 100%; width: 100%;
border-bottom: 1px solid @color-border; border-bottom: 1px solid @color-border;
mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%); mask-image: linear-gradient(270deg, transparent 0%, black 35%,black 50%, black 65%, transparent 100%);
} }
side-line-div { side-line-div {

View file

@ -43,36 +43,26 @@
} }
} }
.item-main {
border-radius: 5px;
padding: 2px;
margin: -2px;
}
&:hover { &:hover {
.inventory-item-header .item-label .item-name .expanded-icon { .inventory-item-header .item-label .item-name .expanded-icon {
margin-left: 10px; margin-left: 10px;
display: inline-block; display: inline-block;
} }
&:has(.inventory-item-content.extensible) { .item-main {
.inventory-item-header,
.inventory-item-content {
background: light-dark(@dark-blue-40, @golden-40); background: light-dark(@dark-blue-40, @golden-40);
} }
}
&:has(.inventory-item-content.extended) { &:has(.inventory-item-content.extended) {
.inventory-item-header .item-label .item-name .expanded-icon { .inventory-item-header .item-label .item-name .expanded-icon {
display: none; display: none;
} }
} }
} }
&:has(.inventory-item-content.extensible) {
.inventory-item-header {
border-radius: 5px 5px 0 0;
}
.inventory-item-content {
border-radius: 0 0 5px 5px;
}
}
&:not(:has(.inventory-item-content.extensible)) .inventory-item-header {
border-radius: 5px;
}
} }
.inventory-item-header, .inventory-item-header,
@ -171,7 +161,7 @@
grid-template-rows: 1fr; grid-template-rows: 1fr;
padding-top: 4px; padding-top: 4px;
} }
.invetory-description { .inventory-description {
overflow: hidden; overflow: hidden;
h1 { h1 {

View file

@ -3,6 +3,8 @@
.application.daggerheart { .application.daggerheart {
prose-mirror { prose-mirror {
--menu-padding: 4px 0px;
--menu-height: calc(var(--menu-button-height) + 8px);
height: 100% !important; height: 100% !important;
width: 100%; width: 100%;

View file

@ -54,7 +54,7 @@ body.game:is(.performance-low, .noblur) {
position: relative; position: relative;
min-height: -webkit-fill-available; min-height: -webkit-fill-available;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
padding-bottom: 20px; padding-bottom: 16px;
.tab { .tab {
padding: 0 10px; padding: 0 10px;

View file

@ -39,6 +39,7 @@
.window-header > .attribution-header-label { .window-header > .attribution-header-label {
margin-right: var(--spacer-4); margin-right: var(--spacer-4);
pointer-events: none;
} }
.tab.inventory { .tab.inventory {
@ -46,7 +47,7 @@
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 10px; gap: 10px;
padding: 10px 10px 0; padding: 12px 12px 0 10px;
.input { .input {
color: light-dark(@dark, @beige); color: light-dark(@dark, @beige);

View file

@ -3,13 +3,20 @@
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
.tab.effects { .tab.effects {
margin-top: var(--spacer-12);
overflow-y: auto;
scrollbar-gutter: stable;
.with-scroll-shadows();
.effects-sections { .effects-sections {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; }
padding-bottom: 20px; fieldset {
.with-scroll-shadows(); margin-right: 0; // scroll gutter compensation
&:first-child {
margin-top: 0;
}
} }
} }
} }

View file

@ -3,14 +3,17 @@
@import '../../../utils/mixin.less'; @import '../../../utils/mixin.less';
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
.tab.features { .tab.features.active {
position: relative;
margin-top: var(--spacer-8);
padding: var(--spacer-8) 2px 0 var(--left-indent);
overflow-y: auto;
scrollbar-gutter: stable;
.with-scroll-shadows();
.feature-section { .feature-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto;
padding-bottom: 20px;
.with-scroll-shadows();
} }
} }
} }

View file

@ -7,7 +7,7 @@
width: 100%; width: 100%;
> *:not(line-div, .tab-navigation) { > *:not(line-div, .tab-navigation) {
padding-left: 15px; padding-left: var(--left-indent);
padding-right: 15px; padding-right: 15px;
} }
@ -75,6 +75,7 @@
.tab-navigation { .tab-navigation {
margin-top: 0; margin-top: 0;
margin-bottom: 0;
button[data-action="openSettings"] { button[data-action="openSettings"] {
margin-right: 12px; margin-right: 12px;
} }

View file

@ -1,7 +1,6 @@
@import './features.less';
@import './header.less';
@import './sheet.less'; @import './sheet.less';
@import './header.less';
@import './features.less';
@import './sidebar.less'; @import './sidebar.less';
@import './effects.less'; @import './effects.less';
@import './notes.less'; @import './notes.less';

View file

@ -1,3 +1,8 @@
.application.sheet.daggerheart.actor.dh-style.adversary .tab.notes.active { .application.sheet.daggerheart.actor.dh-style.adversary .tab.notes.active {
padding-bottom: 20px; padding-top: var(--spacer-16);
padding-left: var(--left-indent);
.editor-content {
scrollbar-gutter: stable;
.with-scroll-shadows();
}
} }

View file

@ -2,6 +2,8 @@
@import '../../../utils/fonts.less'; @import '../../../utils/fonts.less';
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
--left-indent: 15px;
.window-content { .window-content {
display: grid; display: grid;
grid-template-columns: 275px 1fr; grid-template-columns: 275px 1fr;
@ -9,6 +11,7 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
padding-bottom: 0; padding-bottom: 0;
}
.adversary-sidebar-sheet { .adversary-sidebar-sheet {
grid-row: 1 / span 2; grid-row: 1 / span 2;
@ -30,7 +33,9 @@
overflow: hidden; overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} padding: 0;
margin-right: 1px;
margin-bottom: 12px;
} }
} }
} }

View file

@ -11,8 +11,9 @@
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
padding-top: 8px; padding-top: 8px;
padding-bottom: 20px; padding-bottom: 4px;
height: 100%; height: 100%;
scrollbar-gutter: stable;
.with-scroll-shadows(); .with-scroll-shadows();
} }

View file

@ -10,6 +10,7 @@
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
padding-bottom: 20px; padding-bottom: 20px;
scrollbar-gutter: stable;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -1,8 +1,8 @@
@import './sheet.less';
@import './biography.less'; @import './biography.less';
@import './effects.less'; @import './effects.less';
@import './features.less'; @import './features.less';
@import './header.less'; @import './header.less';
@import './inventory.less'; @import './inventory.less';
@import './loadout.less'; @import './loadout.less';
@import './sheet.less';
@import './sidebar.less'; @import './sidebar.less';

View file

@ -4,13 +4,18 @@
.application.sheet.daggerheart.actor.dh-style.character { .application.sheet.daggerheart.actor.dh-style.character {
.tab.inventory { .tab.inventory {
padding-right: 0;
.search-section {
padding-right: 14px;
}
.items-section { .items-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
scrollbar-gutter: stable;
margin-top: 20px; margin-top: 20px;
padding-bottom: 20px; padding-bottom: 4px;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -5,6 +5,7 @@
.application.sheet.daggerheart.actor.dh-style.character { .application.sheet.daggerheart.actor.dh-style.character {
.tab.loadout { .tab.loadout {
.search-section { .search-section {
padding-right: 14px;
.btn-toggle-view { .btn-toggle-view {
background: light-dark(@dark-blue-10, @dark-blue); background: light-dark(@dark-blue-10, @dark-blue);
border: 1px solid @color-border; border: 1px solid @color-border;
@ -52,8 +53,9 @@
gap: 10px; gap: 10px;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
scrollbar-gutter: stable;
margin-top: 20px; margin-top: 20px;
padding-bottom: 20px; padding-bottom: 4px;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -10,6 +10,7 @@
width: 100%; width: 100%;
padding-bottom: 0; padding-bottom: 0;
overflow-x: auto; overflow-x: auto;
}
.character-sidebar-sheet { .character-sidebar-sheet {
grid-row: 1 / span 2; grid-row: 1 / span 2;
@ -27,6 +28,9 @@
.tab { .tab {
grid-row: 2; grid-row: 2;
grid-column: 2; grid-column: 2;
padding-right: 0;
margin-right: 2px;
margin-bottom: 12px;
&.active { &.active {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -34,4 +38,3 @@
} }
} }
} }
}

View file

@ -1,13 +1,17 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/mixin.less';
.application.sheet.daggerheart.actor.dh-style.companion { .application.sheet.daggerheart.actor.dh-style.companion {
.tab.effects { .tab.effects {
margin-right: 2px;
padding-right: 0;
.effects-sections { .effects-sections {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
padding-bottom: 20px; padding-bottom: 4px;
scrollbar-gutter: stable;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -4,12 +4,14 @@
.application.sheet.daggerheart.actor.dh-style.environment { .application.sheet.daggerheart.actor.dh-style.environment {
.tab.features { .tab.features {
position: relative;
.feature-section { .feature-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
padding-bottom: 4px; padding: 4px 8px;
scrollbar-gutter: stable;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -1,4 +1,5 @@
@import './sheet.less';
@import './features.less'; @import './features.less';
@import './header.less'; @import './header.less';
@import './potentialAdversaries.less'; @import './potentialAdversaries.less';
@import './sheet.less'; @import './notes.less';

View file

@ -0,0 +1,11 @@
@import '../../../utils/mixin.less';
.application.sheet.daggerheart.actor.dh-style.environment {
.tab.notes {
padding: 6px 0 4px 15px;
.editor-content {
scrollbar-gutter: stable;
.with-scroll-shadows();
}
}
}

View file

@ -1,4 +1,5 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/mixin.less';
.application.sheet.daggerheart.actor.dh-style.environment { .application.sheet.daggerheart.actor.dh-style.environment {
.tab.potentialAdversaries { .tab.potentialAdversaries {
@ -7,7 +8,8 @@
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
padding-bottom: 4px; padding: 0 4px 4px 4px;
scrollbar-gutter: stable;
.with-scroll-shadows(); .with-scroll-shadows();
} }
} }

View file

@ -16,6 +16,8 @@
.tab { .tab {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
padding-right: 0;
margin-right: 2px;
&.active { &.active {
overflow: hidden; overflow: hidden;

View file

@ -1,4 +1,5 @@
@import './sheet.less';
@import './header.less'; @import './header.less';
@import './party-members.less'; @import './party-members.less';
@import './sheet.less';
@import './inventory.less'; @import './inventory.less';
@import './notes.less';

View file

@ -4,11 +4,17 @@
.application.sheet.daggerheart.actor.dh-style.party { .application.sheet.daggerheart.actor.dh-style.party {
.tab.inventory { .tab.inventory {
padding-right: 0;
.search-section {
padding-right: 14px;
}
.items-section { .items-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow-y: auto; overflow-y: auto;
scrollbar-gutter: stable;
margin-top: 20px; margin-top: 20px;
padding-bottom: 4px; padding-bottom: 4px;
.with-scroll-shadows(); .with-scroll-shadows();

View file

@ -0,0 +1,12 @@
@import '../../../utils/mixin.less';
.application.sheet.daggerheart.actor.dh-style.party {
.tab.notes {
padding: 16px 0 4px 15px;
.editor-content {
scrollbar-gutter: stable;
padding-left: 8px;
.with-scroll-shadows();
}
}
}

View file

@ -4,6 +4,7 @@
.application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers { .application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers {
overflow: auto; overflow: auto;
.with-scroll-shadows();
.actors-list { .actors-list {
display: flex; display: flex;

View file

@ -21,6 +21,8 @@
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
scrollbar-gutter: stable; scrollbar-gutter: stable;
margin-right: 2px;
padding-right: 8px;
&.active { &.active {
overflow: auto; overflow: auto;

View file

@ -2,7 +2,7 @@
"id": "daggerheart", "id": "daggerheart",
"title": "Daggerheart", "title": "Daggerheart",
"description": "An unofficial implementation of the Daggerheart system", "description": "An unofficial implementation of the Daggerheart system",
"version": "2.3.4", "version": "2.4.1",
"compatibility": { "compatibility": {
"minimum": "14.364", "minimum": "14.364",
"verified": "14.364", "verified": "14.364",
@ -10,7 +10,7 @@
}, },
"url": "https://github.com/Foundryborne/daggerheart", "url": "https://github.com/Foundryborne/daggerheart",
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json", "manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.3.4/system.zip", "download": "https://github.com/Foundryborne/daggerheart/releases/download/2.4.1/system.zip",
"authors": [ "authors": [
{ {
"name": "WBHarry" "name": "WBHarry"

View file

@ -1,14 +1,15 @@
<section class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-tab='{{tabs.features.id}}' <section class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-tab='{{tabs.features.id}}'
data-group='{{tabs.features.group}}'> data-group='{{tabs.features.group}}'>
<div class="feature-section"> <div class="feature-section">
{{> 'daggerheart.inventory-items' {{#each @root.features as |item|}}
title=tabs.features.label {{> 'daggerheart.inventory-item'
item=item
type='feature' type='feature'
collection=@root.features actorType=@root.document.type
hideContextMenu=true hideContextMenu=true
hideModifyControls=true hideModifyControls=true
canCreate=@root.editable
showActions=@root.editable showActions=@root.editable
}} }}
{{/each}}
</div> </div>
</section> </section>

View file

@ -3,10 +3,7 @@
data-tab='{{tabs.notes.id}}' data-tab='{{tabs.notes.id}}'
data-group='{{tabs.notes.group}}' data-group='{{tabs.notes.group}}'
> >
<fieldset class="fit-height"> {{formInput notes.field value=notes.value enriched=notes.enriched class="aaa" toggled=true}}
<legend>{{localize tabs.notes.label}}</legend>
{{formInput notes.field value=notes.value enriched=notes.enriched toggled=true}}
</fieldset>
{{#if (and showAttribution document.system.attribution.artist)}} {{#if (and showAttribution document.system.attribution.artist)}}
<label class="artist-attribution">{{localize "DAGGERHEART.GENERAL.artistAttribution" artist=document.system.attribution.artist}}</label> <label class="artist-attribution">{{localize "DAGGERHEART.GENERAL.artistAttribution" artist=document.system.attribution.artist}}</label>

View file

@ -4,14 +4,15 @@
data-group='{{tabs.features.group}}' data-group='{{tabs.features.group}}'
> >
<div class="feature-section"> <div class="feature-section">
{{> 'daggerheart.inventory-items' {{#each @root.features as |item|}}
title=tabs.features.label {{> 'daggerheart.inventory-item'
item=item
type='feature' type='feature'
collection=@root.features actorType=@root.document.type
hideContextMenu=true hideContextMenu=true
hideModifyControls=true hideModifyControls=true
canCreate=@root.editable
showActions=@root.editable showActions=@root.editable
}} }}
{{/each}}
</div> </div>
</section> </section>

View file

@ -3,10 +3,7 @@
data-tab='{{tabs.notes.id}}' data-tab='{{tabs.notes.id}}'
data-group='{{tabs.notes.group}}' data-group='{{tabs.notes.group}}'
> >
<fieldset class="fit-height">
<legend>{{localize tabs.notes.label}}</legend>
{{formInput notes.field value=notes.value enriched=notes.value toggled=true}} {{formInput notes.field value=notes.value enriched=notes.value toggled=true}}
</fieldset>
{{#if (and showAttribution document.system.attribution.artist)}} {{#if (and showAttribution document.system.attribution.artist)}}
<label class="artist-attribution">{{localize "DAGGERHEART.GENERAL.artistAttribution" artist=document.system.attribution.artist}}</label> <label class="artist-attribution">{{localize "DAGGERHEART.GENERAL.artistAttribution" artist=document.system.attribution.artist}}</label>

View file

@ -3,8 +3,5 @@
data-tab='{{tabs.notes.id}}' data-tab='{{tabs.notes.id}}'
data-group='{{tabs.notes.group}}' data-group='{{tabs.notes.group}}'
> >
<fieldset class="fit-height">
<legend>{{localize tabs.notes.label}}</legend>
{{formInput notes.field value=notes.value enriched=notes.value toggled=true}} {{formInput notes.field value=notes.value enriched=notes.value toggled=true}}
</fieldset>
</section> </section>

View file

@ -25,7 +25,8 @@ Parameters:
data-type="{{type}}" data-item-type="{{item.type}}" data-type="{{type}}" data-item-type="{{item.type}}"
data-item-uuid="{{item.uuid}}" data-no-compendium-edit="{{noCompendiumEdit}}" data-item-uuid="{{item.uuid}}" data-no-compendium-edit="{{noCompendiumEdit}}"
> >
<div class="inventory-item-header {{#if hideContextMenu}}padded{{/if}}" {{#unless noExtensible}}data-action="toggleExtended" {{/unless}}> <div class="item-main">
<div class="inventory-item-header{{#if hideContextMenu}} padded{{/if}}" {{#unless (or noExtensible (not item.hasDescription))}}data-action="toggleExtended" {{/unless}}>
{{!-- Image --}} {{!-- Image --}}
<div class="img-portait" draggable="true" <div class="img-portait" draggable="true"
{{#unless (eq showActions false)}}data-action='{{ifThen item.usable "useItem" (ifThen (hasProperty item "toChat" ) "toChat" "editDoc" ) }}'{{/unless}} {{#unless (eq showActions false)}}data-action='{{ifThen item.usable "useItem" (ifThen (hasProperty item "toChat" ) "toChat" "editDoc" ) }}'{{/unless}}
@ -43,18 +44,16 @@ Parameters:
{{!-- Name & Tags --}} {{!-- Name & Tags --}}
<div class="item-label" draggable="true"> <div class="item-label" draggable="true">
{{!-- Item Name --}} {{!-- Item Name --}}
<span class="item-name">{{localize item.name}} {{#unless (or noExtensible (not item.system.description))}}<span class="expanded-icon"><i class="fa-solid fa-expand"></i></span>{{/unless}}</span> <span class="item-name">{{localize item.name}} {{#unless (or noExtensible (not item.hasDescription))}}<span class="expanded-icon"><i class="fa-solid fa-expand"></i></span>{{/unless}}</span>
{{!-- Tags Start --}} {{!-- Tags Start --}}
{{#if (not hideTags)}} {{#if (not hideTags)}}
{{#> "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs" item}} {{#> "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs" item}}
{{#if (eq ../type 'feature')}} {{#if (and (eq ../type 'feature') system.featureForm (ne @root.document.type "character"))}}
{{#if (and system.featureForm (ne @root.document.type "character"))}}
<div class="tag feature-form"> <div class="tag feature-form">
<span class="recall-value">{{localize (concat "DAGGERHEART.CONFIG.FeatureForm." system.featureForm)}}</span> <span class="recall-value">{{localize (concat "DAGGERHEART.CONFIG.FeatureForm." system.featureForm)}}</span>
</div> </div>
{{/if}} {{/if}}
{{/if}}
{{/ "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs"}} {{/ "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs"}}
{{/if}} {{/if}}
@ -131,10 +130,11 @@ Parameters:
</div> </div>
{{/unless}} {{/unless}}
</div> </div>
<div class="inventory-item-content{{#unless noExtensible}} extensible{{/unless}}">
{{!-- Description --}}
{{#unless hideDescription}} {{#unless hideDescription}}
<div class="invetory-description"></div> <div class="inventory-item-content{{#unless (or noExtensible (not item.hasDescription))}} extensible{{/unless}}">
{{!-- Description --}}
<div class="inventory-description"></div>
</div>
{{/unless}} {{/unless}}
</div> </div>
{{!-- Dice Resource --}} {{!-- Dice Resource --}}