diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2c6ec7e9..ca744ed5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,7 +14,9 @@ jobs: run: npm ci - name: Build Packs - run: npm run pullYMLtoLDB + run: | + npm run pullYMLtoLDB + mv --force src/packs/LICENSE packs/LICENSE - name: Build daggerheart.js run: npm run build diff --git a/lang/en.json b/lang/en.json index 8af39fa3..bf2f0fc3 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1695,7 +1695,8 @@ "makeDeathMove": "Make a Death Move", "rangeAndTarget": "Range & Target", "dragApplyEffect": "Drag effect to apply it to an actor", - "appliedEvenIfSuccessful": "Applied even if save succeeded" + "appliedEvenIfSuccessful": "Applied even if save succeeded", + "diceIsRerolled": "The dice has been rerolled (x{times})" } } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index bcdff961..c1801097 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -47,13 +47,13 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo element.addEventListener('click', this.onToggleTargets) ); html.querySelectorAll('.ability-use-button').forEach(element => - element.addEventListener('click', event => this.abilityUseButton(this, event, data.message)) + element.addEventListener('click', event => this.abilityUseButton(event, data.message)) ); html.querySelectorAll('.action-use-button').forEach(element => - element.addEventListener('click', event => this.actionUseButton(this, event, data.message)) + element.addEventListener('click', event => this.actionUseButton(event, data.message)) ); html.querySelectorAll('.reroll-button').forEach(element => - element.addEventListener('click', event => this.rerollEvent(this, event, data.message)) + element.addEventListener('click', event => this.rerollEvent(event, data.message)) ); }; @@ -271,6 +271,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo } async rerollEvent(event, message) { + event.stopPropagation(); if (!event.shiftKey) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { @@ -287,6 +288,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo game.system.api.dice[ message.type === 'dualityRoll' ? 'DualityRoll' : target.dataset.type === 'damage' ? 'DHRoll' : 'D20Roll' ]; + + if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice }); + const { newRoll, parsedRoll } = await rollClass.reroll(originalRoll_parsed, target, message); await game.messages.get(message._id).update({ diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 5f95b80d..dcf0143a 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -1,4 +1,5 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; +import { getDiceSoNicePresets } from '../config/generalConfig.mjs'; import DHRoll from './dhRoll.mjs'; export default class D20Roll extends DHRoll { @@ -156,6 +157,14 @@ export default class D20Roll extends DHRoll { dice: roll.dAdvantage?.denomination, value: roll.dAdvantage?.total }; + data.dice = data.dice.map(dice => ({ + ...dice, + results: dice.results.filter(x => !x.rerolled), + rerolled: { + any: dice.results.some(x => x.rerolled), + rerolls: dice.results.filter(x => x.rerolled) + } + })); data.isCritical = roll.isCritical; data.extra = roll.dice .filter(d => !roll.baseTerms.includes(d)) @@ -188,6 +197,26 @@ export default class D20Roll extends DHRoll { await game.dice3d.showForRoll(parsedRoll, game.user, true); } - return { newRoll, parsedRoll }; + const rerolled = { + any: true, + rerolls: [ + ...(message.system.roll.dice[0].rerolled?.rerolls?.length > 0 + ? [message.system.roll.dice[0].rerolled?.rerolls] + : []), + rollString.terms[0].results + ] + }; + return { + newRoll: { + ...newRoll, + dice: [ + { + ...newRoll.dice[0], + rerolled: rerolled + } + ] + }, + parsedRoll + }; } } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index c50c126a..52759316 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -193,6 +193,11 @@ export const registerRollDiceHooks = () => { if (config.roll.isCritical) updates.push({ key: 'stress', value: -1 }); if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 }); + if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1) + updates.push({ key: 'hope', value: -1 }); + if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: 1 }); + if (config.rerolledRoll.result.duality === -1) updates.push({ key: 'fear', value: -1 }); + if (updates.length) { const target = actor.system.partner ?? actor; if (!['dead', 'unconcious'].some(x => actor.statuses.has(x))) { diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 151d63df..1c414a63 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -171,11 +171,19 @@ export default class DualityRoll extends D20Roll { data.hope = { dice: roll.dHope.denomination, - value: roll.dHope.total + value: roll.dHope.total, + rerolled: { + any: roll.dHope.results.some(x => x.rerolled), + rerolls: roll.dHope.results.filter(x => x.rerolled) + } }; data.fear = { dice: roll.dFear.denomination, - value: roll.dFear.total + value: roll.dFear.total, + rerolled: { + any: roll.dFear.results.some(x => x.rerolled), + rerolls: roll.dFear.results.filter(x => x.rerolled) + } }; data.rally = { dice: roll.dRally?.denomination, @@ -232,6 +240,13 @@ export default class DualityRoll extends D20Roll { }); newRoll.extra = newRoll.extra.slice(2); + Hooks.call(`${CONFIG.DH.id}.postRollDuality`, { + source: { actor: message.system.source.actor ?? '' }, + targets: message.system.targets, + roll: newRoll, + rerolledRoll: + newRoll.result.duality !== message.system.roll.result.duality ? message.system.roll : undefined + }); return { newRoll, parsedRoll }; } } diff --git a/src/packs/LICENSE b/src/packs/LICENSE new file mode 100644 index 00000000..9a2a5c9f --- /dev/null +++ b/src/packs/LICENSE @@ -0,0 +1,7 @@ +This product includes materials from the +Daggerheart System Reference Document 1.0, © +Critical Role, LLC. under the terms of the +Darrington Press Community Gaming (DPCGL) +License. More information can be found at +https://www.daggerheart.com/. There are no +previous modifications by others. \ No newline at end of file diff --git a/styles/less/sheets/actors/character/effects.less b/styles/less/sheets/actors/character/effects.less new file mode 100644 index 00000000..1549c834 --- /dev/null +++ b/styles/less/sheets/actors/character/effects.less @@ -0,0 +1,19 @@ +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; + +.application.sheet.daggerheart.actor.dh-style.character { + .tab.effects { + .effects-sections { + display: flex; + flex-direction: column; + gap: 10px; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); + padding: 20px 0; + padding-top: 10px; + + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; + } + } +} diff --git a/styles/less/sheets/actors/character/features.less b/styles/less/sheets/actors/character/features.less index c2feb6b1..af53e11d 100644 --- a/styles/less/sheets/actors/character/features.less +++ b/styles/less/sheets/actors/character/features.less @@ -11,7 +11,6 @@ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); padding: 20px 0; padding-top: 10px; - height: 84%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; diff --git a/styles/less/sheets/actors/character/inventory.less b/styles/less/sheets/actors/character/inventory.less index eac1065d..48bdd682 100644 --- a/styles/less/sheets/actors/character/inventory.less +++ b/styles/less/sheets/actors/character/inventory.less @@ -56,7 +56,6 @@ overflow-y: auto; mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); padding: 20px 0; - height: 73%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; diff --git a/styles/less/sheets/actors/character/loadout.less b/styles/less/sheets/actors/character/loadout.less index b7863e77..98fe9eed 100644 --- a/styles/less/sheets/actors/character/loadout.less +++ b/styles/less/sheets/actors/character/loadout.less @@ -97,7 +97,6 @@ overflow-y: auto; mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); padding: 20px 0; - height: 84%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; diff --git a/styles/less/sheets/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less index 3d19a3b2..f09ee541 100644 --- a/styles/less/sheets/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -11,6 +11,7 @@ width: 100%; padding-bottom: 0; overflow-x: auto; + margin-bottom: 0; .character-sidebar-sheet { grid-row: 1 / span 2; @@ -25,6 +26,11 @@ .tab { grid-row: 2; grid-column: 2; + &.active { + display: flex; + flex-direction: column; + overflow: hidden; + } } } } diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index 2c88d14f..7cfeffac 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -63,7 +63,7 @@ flex-direction: column; top: -20px; gap: 30px; - margin-bottom: -10px; + margin-bottom: -16px; .resources-section { display: flex; @@ -357,54 +357,39 @@ } } - .equipment-section { - .title { - display: flex; - gap: 15px; - align-items: center; + .shortcut-items-section { + overflow-y: hidden; + max-height: 56%; + padding-top: 16px; + padding-bottom: 20px; + mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - h3 { - font-size: 20px; - } - } - .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; + &:hover { + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; } } - .loadout-section { + .equipment-section, + .loadout-section, + .experience-section { .title { - display: flex; - gap: 15px; - align-items: center; + .section-title(); + } + } - h3 { - font-size: 20px; - } + .equipment-section { + .items-list { + .column-list(10px); } } .experience-section { - .title { - display: flex; - gap: 15px; - align-items: center; - - h3 { - font-size: 20px; - } - } - .experience-list { - display: flex; - flex-direction: column; - gap: 5px; + .column-list(5px); width: 100%; margin-top: 10px; - align-items: center; .experience-row { display: flex; diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 3470de37..aa2f4356 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -4,6 +4,7 @@ @import './actors/adversary/sidebar.less'; @import './actors/character/biography.less'; +@import './actors/character/effects.less'; @import './actors/character/features.less'; @import './actors/character/header.less'; @import './actors/character/inventory.less'; diff --git a/styles/less/ui/chat/chat.less b/styles/less/ui/chat/chat.less index c593a919..4558cf8e 100644 --- a/styles/less/ui/chat/chat.less +++ b/styles/less/ui/chat/chat.less @@ -62,6 +62,17 @@ } &.rerollable { + position: relative; + flex: none; + + .dice-rerolled { + z-index: 2; + position: absolute; + right: 0; + font-size: 12px; + cursor: help; + } + .reroll-button { border: none; background: initial; @@ -85,12 +96,21 @@ display: flex; flex-direction: column; gap: 2px; + position: relative; .dice-title { color: var(--color-light-1); text-shadow: 0 0 1px black; } + .dice-rerolled { + z-index: 2; + position: absolute; + right: -2px; + font-size: 12px; + cursor: help; + } + .dice-inner-container { display: flex; align-items: center; diff --git a/styles/less/utils/mixin.less b/styles/less/utils/mixin.less index 39c2bee0..0e52fa82 100644 --- a/styles/less/utils/mixin.less +++ b/styles/less/utils/mixin.less @@ -20,3 +20,27 @@ @lightRules(); } } + +/** + * Apply a style to sidebar titles. + */ +.section-title() { + display: flex; + gap: 15px; + align-items: center; + + h3 { + font-size: 20px; + } +} + +/** + * Apply default item list style. + * @param {Length} @gap - The vertical spacing between elements (e.g., 10px, 1rem) + */ +.column-list(@gap: 10px) { + display: flex; + flex-direction: column; + gap: @gap; + align-items: center; +} diff --git a/templates/dialogs/ownershipSelection.hbs b/templates/dialogs/ownershipSelection.hbs index 5c1def0e..43711c07 100644 --- a/templates/dialogs/ownershipSelection.hbs +++ b/templates/dialogs/ownershipSelection.hbs @@ -1,7 +1,7 @@