mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Added countdown automation
This commit is contained in:
parent
b6f78c5102
commit
2299141442
18 changed files with 500 additions and 53 deletions
|
|
@ -13,8 +13,7 @@ import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_m
|
|||
import { getCommandTarget, rollCommandToJSON, setDiceSoNiceForDualityRoll } from './module/helpers/utils.mjs';
|
||||
import { abilities } from './module/config/actorConfig.mjs';
|
||||
import Resources from './module/applications/resources.mjs';
|
||||
import Countdowns from './module/applications/countdowns.mjs';
|
||||
import DhCountdowns from './module/data/countdowns.mjs';
|
||||
import { NarrativeCountdowns, registerCountdownHooks } from './module/applications/countdowns.mjs';
|
||||
import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs';
|
||||
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
|
||||
import { DhMeasuredTemplate } from './module/placeables/_module.mjs';
|
||||
|
|
@ -112,7 +111,6 @@ Hooks.once('init', () => {
|
|||
CONFIG.Token.rulerClass = DhpTokenRuler;
|
||||
|
||||
CONFIG.ui.resources = Resources;
|
||||
CONFIG.ui.countdowns = Countdowns;
|
||||
|
||||
game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent);
|
||||
|
||||
|
|
@ -136,8 +134,7 @@ Hooks.on('ready', () => {
|
|||
DualityRollColor.colorful.value
|
||||
);
|
||||
|
||||
/* Temporary for ease of development. Countdown application should be opened through buttons somewhere */
|
||||
new CONFIG.ui.countdowns(DhCountdowns.CountdownCategories.narrative).render({ force: true });
|
||||
registerCountdownHooks();
|
||||
});
|
||||
|
||||
Hooks.once('dicesoniceready', () => {});
|
||||
|
|
@ -271,6 +268,29 @@ Hooks.on('chatMessage', (_, message) => {
|
|||
}
|
||||
});
|
||||
|
||||
Hooks.on('renderJournalDirectory', async (tab, html, _, options) => {
|
||||
if (tab.id === 'journal') {
|
||||
if (options.parts && !options.parts.includes('footer')) return;
|
||||
|
||||
const buttons = tab.element.querySelector('.directory-footer.action-buttons');
|
||||
const title = game.i18n.format('DAGGERHEART.Countdown.Title', {
|
||||
type: game.i18n.localize('DAGGERHEART.Countdown.Types.narrative')
|
||||
});
|
||||
buttons.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
`
|
||||
<button id="narrative-countdown-button">
|
||||
<i class="fa-solid fa-stopwatch"></i>
|
||||
<span style="font-weight: 400; font-family: var(--font-sans);">${title}</span>
|
||||
</button>`
|
||||
);
|
||||
|
||||
buttons.querySelector('#narrative-countdown-button').onclick = async () => {
|
||||
new NarrativeCountdowns().open();
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const preloadHandlebarsTemplates = async function () {
|
||||
return foundry.applications.handlebars.loadTemplates([
|
||||
'systems/daggerheart/templates/sheets/parts/attributes.hbs',
|
||||
|
|
|
|||
14
lang/en.json
14
lang/en.json
|
|
@ -83,6 +83,10 @@
|
|||
"actionPoints": {
|
||||
"label": "Action Points",
|
||||
"hint": "Automatically give and take Action Points as combatants take their turns."
|
||||
},
|
||||
"countdowns": {
|
||||
"label": "Countdowns",
|
||||
"hint": "Automatically progress non-custom countdowns"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1045,10 +1049,16 @@
|
|||
},
|
||||
"Type": {
|
||||
"Spotlight": "Spotlight",
|
||||
"Custom": "Custom"
|
||||
"Custom": "Custom",
|
||||
"CharacterAttack": "Character Attack"
|
||||
},
|
||||
"NewCountdown": "New Countdown",
|
||||
"Title": "Countdowns"
|
||||
"AddCountdown": "Add Countdown",
|
||||
"Title": "{type} Countdowns",
|
||||
"Types": {
|
||||
"narrative": "Narrative",
|
||||
"encounter": "Encounter"
|
||||
}
|
||||
},
|
||||
"Sheets": {
|
||||
"PC": {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,22 @@
|
|||
import { countdownTypes } from '../config/generalConfig.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(basePath) {
|
||||
super();
|
||||
super({});
|
||||
|
||||
this.basePath = basePath;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return game.i18n.format('DAGGERHEART.Countdown.Title', {
|
||||
type: game.i18n.localize(`DAGGERHEART.Countdown.Types.${this.basePath}`)
|
||||
});
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'countdown',
|
||||
classes: [],
|
||||
classes: ['daggerheart', 'dh-style', 'countdown'],
|
||||
tag: 'form',
|
||||
window: {
|
||||
frame: true,
|
||||
|
|
@ -19,7 +26,8 @@ export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2
|
|||
},
|
||||
actions: {
|
||||
addCountdown: this.addCountdown,
|
||||
removeCountdown: this.removeCountdown
|
||||
removeCountdown: this.removeCountdown,
|
||||
editImage: this.onEditImage
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true }
|
||||
};
|
||||
|
|
@ -30,6 +38,22 @@ export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2
|
|||
}
|
||||
};
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
|
||||
htmlElement.querySelectorAll('.mini-countdown-container').forEach(element => {
|
||||
element.addEventListener('click', event => this.updateCountdownValue.bind(this)(event, true));
|
||||
element.addEventListener('contextmenu', event => this.updateCountdownValue.bind(this)(event, false));
|
||||
});
|
||||
}
|
||||
|
||||
async _onFirstRender(context, options) {
|
||||
super._onFirstRender(context, options);
|
||||
|
||||
this.element.querySelector('.expanded-view').classList.toggle('hidden');
|
||||
this.element.querySelector('.minimized-view').classList.toggle('hidden');
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
const countdownData = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||
|
|
@ -38,6 +62,7 @@ export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2
|
|||
context.source = countdownData.toObject();
|
||||
context.systemFields = countdownData.schema.fields;
|
||||
context.countdownFields = context.systemFields.countdowns.element.fields;
|
||||
context.minimized = this.minimized || _options.isFirstRender;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
@ -52,6 +77,63 @@ export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2
|
|||
this.render();
|
||||
}
|
||||
|
||||
async minimize() {
|
||||
await super.minimize();
|
||||
|
||||
this.element.querySelector('.expanded-view').classList.toggle('hidden');
|
||||
this.element.querySelector('.minimized-view').classList.toggle('hidden');
|
||||
}
|
||||
|
||||
async maximize() {
|
||||
if (this.minimized) {
|
||||
this.element.querySelector('.expanded-view').classList.toggle('hidden');
|
||||
this.element.querySelector('.minimized-view').classList.toggle('hidden');
|
||||
}
|
||||
|
||||
await super.maximize();
|
||||
}
|
||||
|
||||
static onEditImage(_, target) {
|
||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||
const current = setting.countdowns[target.dataset.countdown].img;
|
||||
const fp = new FilePicker({
|
||||
current,
|
||||
type: 'image',
|
||||
callback: async path => this.updateImage.bind(this)(path, target.dataset.countdown),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10
|
||||
});
|
||||
return fp.browse();
|
||||
}
|
||||
|
||||
async updateImage(path, countdown) {
|
||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
||||
await setting.updateSource({
|
||||
[`${this.basePath}.countdowns.${countdown}.img`]: path
|
||||
});
|
||||
|
||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, setting);
|
||||
this.render();
|
||||
}
|
||||
|
||||
async updateCountdownValue(event, increase) {
|
||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
||||
const countdown = countdownSetting[this.basePath].countdowns[event.currentTarget.dataset.countdown];
|
||||
const currentValue = countdown.progress.current;
|
||||
|
||||
if (increase && currentValue === countdown.progress.max) return;
|
||||
if (!increase && currentValue === 0) return;
|
||||
|
||||
await countdownSetting.updateSource({
|
||||
[`${this.basePath}.countdowns.${event.currentTarget.dataset.countdown}.progress.current`]: increase
|
||||
? currentValue + 1
|
||||
: currentValue - 1
|
||||
});
|
||||
|
||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, countdownSetting.toObject());
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async addCountdown() {
|
||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
||||
await countdownSetting.updateSource({
|
||||
|
|
@ -71,4 +153,75 @@ export default class Countdowns extends HandlebarsApplicationMixin(ApplicationV2
|
|||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, countdownSetting.toObject());
|
||||
this.render();
|
||||
}
|
||||
|
||||
async open() {
|
||||
await this.render(true);
|
||||
if (
|
||||
Object.keys(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath].countdowns)
|
||||
.length > 0
|
||||
) {
|
||||
this.minimize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class NarrativeCountdowns extends Countdowns {
|
||||
constructor() {
|
||||
super('narrative');
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'narrative-countdowns'
|
||||
};
|
||||
}
|
||||
|
||||
export class EncounterCountdowns extends Countdowns {
|
||||
constructor() {
|
||||
super('encounter');
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'encounter-countdowns'
|
||||
};
|
||||
}
|
||||
|
||||
export const registerCountdownHooks = () => {
|
||||
const updateCountdowns = async shouldIncrease => {
|
||||
if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).countdowns) {
|
||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
||||
for (let countdownCategoryKey in countdownSetting) {
|
||||
const countdownCategory = countdownSetting[countdownCategoryKey];
|
||||
for (let countdownKey in countdownCategory.countdowns) {
|
||||
const countdown = countdownCategory.countdowns[countdownKey];
|
||||
|
||||
if (shouldIncrease(countdown)) {
|
||||
await countdownSetting.updateSource({
|
||||
[`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]:
|
||||
countdown.progress.current + 1
|
||||
});
|
||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, countdownSetting);
|
||||
foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Hooks.on(SYSTEM.HOOKS.characterAttack, async () => {
|
||||
updateCountdowns(countdown => {
|
||||
return (
|
||||
countdown.progress.type.value === countdownTypes.characterAttack.id &&
|
||||
countdown.progress.current < countdown.progress.max
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Hooks.on(SYSTEM.HOOKS.spotlight, async () => {
|
||||
updateCountdowns(countdown => {
|
||||
return (
|
||||
countdown.progress.type.value === countdownTypes.spotlight.id &&
|
||||
countdown.progress.current < countdown.progress.max
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -371,7 +371,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
static async attackRoll(event, button) {
|
||||
const weapon = await fromUuid(button.dataset.weapon);
|
||||
if (!weapon) return;
|
||||
weapon.use(event);
|
||||
|
||||
const wasUsed = await weapon.use(event);
|
||||
if (wasUsed) {
|
||||
Hooks.callAll(SYSTEM.HOOKS.characterAttack, {});
|
||||
}
|
||||
}
|
||||
|
||||
static openLevelUp() {
|
||||
|
|
|
|||
|
|
@ -369,6 +369,10 @@ export const countdownTypes = {
|
|||
id: 'spotlight',
|
||||
label: 'DAGGERHEART.Countdown.Type.Spotlight'
|
||||
},
|
||||
characterAttack: {
|
||||
id: 'characterAttack',
|
||||
label: 'DAGGERHEART.Countdown.Type.CharacterAttack'
|
||||
},
|
||||
custom: {
|
||||
id: 'custom',
|
||||
label: 'DAGGERHEART.Countdown.Type.Custom'
|
||||
|
|
|
|||
4
module/config/hooksConfig.mjs
Normal file
4
module/config/hooksConfig.mjs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export const hooks = {
|
||||
characterAttack: 'characterAttackHook',
|
||||
spotlight: 'spotlightHook'
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@ import * as DOMAIN from './domainConfig.mjs';
|
|||
import * as ACTOR from './actorConfig.mjs';
|
||||
import * as ITEM from './itemConfig.mjs';
|
||||
import * as SETTINGS from './settingsConfig.mjs';
|
||||
import { hooks as HOOKS } from './hooksConfig.mjs';
|
||||
import * as EFFECTS from './effectConfig.mjs';
|
||||
import * as ACTIONS from './actionConfig.mjs';
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ export const SYSTEM = {
|
|||
ACTOR,
|
||||
ITEM,
|
||||
SETTINGS,
|
||||
HOOKS,
|
||||
EFFECTS,
|
||||
ACTIONS
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default class DhCountdowns extends foundry.abstract.DataModel {
|
|||
|
||||
return {
|
||||
narrative: new fields.EmbeddedDataField(DhCountdownData),
|
||||
combat: new fields.EmbeddedDataField(DhCountdownData)
|
||||
encounter: new fields.EmbeddedDataField(DhCountdownData)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +32,11 @@ class DhCountdown extends foundry.abstract.DataModel {
|
|||
required: true,
|
||||
label: 'DAGGERHEART.Countdown.FIELDS.countdowns.element.name.label'
|
||||
}),
|
||||
img: new fields.FilePathField({
|
||||
categories: ['IMAGE'],
|
||||
base64: false,
|
||||
initial: 'icons/magic/time/hourglass-yellow-green.webp'
|
||||
}),
|
||||
progress: new fields.SchemaField({
|
||||
current: new fields.NumberField({
|
||||
required: true,
|
||||
|
|
@ -42,7 +47,7 @@ class DhCountdown extends foundry.abstract.DataModel {
|
|||
max: new fields.NumberField({
|
||||
required: true,
|
||||
integer: true,
|
||||
initial: 0,
|
||||
initial: 1,
|
||||
label: 'DAGGERHEART.Countdown.FIELDS.countdowns.element.progress.max.label'
|
||||
}),
|
||||
type: new fields.SchemaField({
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
hope: new fields.BooleanField({ required: true, initial: false }),
|
||||
actionPoints: new fields.BooleanField({ required: true, initial: false })
|
||||
actionPoints: new fields.BooleanField({ required: true, initial: false }),
|
||||
countdowns: new fields.BooleanField({ requireD: true, initial: false })
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ export default class DhpActor extends Actor {
|
|||
);
|
||||
|
||||
if (this.type === 'character') {
|
||||
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
|
||||
const automateHope = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).hope;
|
||||
|
||||
if (automateHope && result.hopeUsed) {
|
||||
await this.update({
|
||||
|
|
@ -330,7 +330,7 @@ export default class DhpActor extends Actor {
|
|||
hope = roll.dice[0].results[0].result;
|
||||
fear = roll.dice[1].results[0].result;
|
||||
if (
|
||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope) &&
|
||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).hope &&
|
||||
config.roll.type === 'action'
|
||||
) {
|
||||
if (hope > fear) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { EncounterCountdowns } from '../applications/countdowns.mjs';
|
||||
|
||||
export default class DhCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
||||
static DEFAULT_OPTIONS = {
|
||||
actions: {
|
||||
requestSpotlight: this.requestSpotlight,
|
||||
toggleSpotlight: this.toggleSpotlight,
|
||||
setActionTokens: this.setActionTokens
|
||||
setActionTokens: this.setActionTokens,
|
||||
openCountdowns: this.openCountdowns
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -83,6 +86,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
.map(x => x.id)
|
||||
.indexOf(combatantId);
|
||||
|
||||
if (this.viewed.turn !== toggleTurn) Hooks.callAll(SYSTEM.HOOKS.spotlight, {});
|
||||
|
||||
await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn });
|
||||
await combatant.update({ 'system.spotlight.requesting': false });
|
||||
}
|
||||
|
|
@ -97,4 +102,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
await combatant.update({ 'system.actionTokens': newIndex });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static openCountdowns() {
|
||||
new EncounterCountdowns().open();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
98
styles/countdown.less
Normal file
98
styles/countdown.less
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
.daggerheart.dh-style.countdown {
|
||||
fieldset {
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
border-radius: 6px;
|
||||
border-color: light-dark(@dark-blue, @golden);
|
||||
|
||||
legend {
|
||||
font-family: @font-body;
|
||||
font-weight: bold;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
|
||||
a {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.minimized {
|
||||
height: auto !important;
|
||||
max-height: unset !important;
|
||||
max-width: 600px !important;
|
||||
width: auto !important;
|
||||
|
||||
.window-content {
|
||||
display: flex;
|
||||
padding: 4px 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.minimized-view {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.mini-countdown-container {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border: 2px solid light-dark(@dark-blue, @golden);
|
||||
border-radius: 6px;
|
||||
padding: 0 4px 0 0;
|
||||
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||
color: light-dark(@beige, @dark);
|
||||
cursor: pointer;
|
||||
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 6px 0 0 6px;
|
||||
}
|
||||
|
||||
.mini-countdown-name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mini-countdown-value {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.countdown-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.countdown-inner-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
.countdown-value-container {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
input {
|
||||
max-width: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1297,25 +1297,38 @@
|
|||
.combat-sidebar .encounter-controls.combat {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-control-fear-container {
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: black;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-control-fear-container .dice {
|
||||
height: 24px;
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .dice {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-control-fear-container .encounter-control-fear {
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-fear {
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-control-fear-container .encounter-control-counter {
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-counter {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-countdowns {
|
||||
color: var(--content-link-icon-color);
|
||||
}
|
||||
.combat-sidebar .encounter-controls.combat .control-buttons {
|
||||
width: min-content;
|
||||
}
|
||||
|
|
@ -3178,6 +3191,84 @@ div.daggerheart.views.multiclass {
|
|||
#resources:has(.fear-bar) {
|
||||
min-width: 200px;
|
||||
}
|
||||
.daggerheart.dh-style.countdown fieldset {
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
border-radius: 6px;
|
||||
border-color: light-dark(#18162e, #f3c267);
|
||||
}
|
||||
.daggerheart.dh-style.countdown fieldset legend {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: bold;
|
||||
color: light-dark(#18162e, #f3c267);
|
||||
}
|
||||
.daggerheart.dh-style.countdown fieldset legend a {
|
||||
text-shadow: none;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized {
|
||||
height: auto !important;
|
||||
max-height: unset !important;
|
||||
max-width: 600px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .window-content {
|
||||
display: flex;
|
||||
padding: 4px 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .minimized-view {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .minimized-view .mini-countdown-container {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border: 2px solid light-dark(#18162e, #f3c267);
|
||||
border-radius: 6px;
|
||||
padding: 0 4px 0 0;
|
||||
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||
color: light-dark(#efe6d8, #222);
|
||||
cursor: pointer;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .minimized-view .mini-countdown-container.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .minimized-view .mini-countdown-container img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 6px 0 0 6px;
|
||||
}
|
||||
.daggerheart.dh-style.countdown.minimized .minimized-view .mini-countdown-container .mini-countdown-name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .hidden {
|
||||
display: none;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .countdown-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .countdown-container img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .countdown-container .countdown-inner-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .countdown-container .countdown-inner-container .countdown-value-container {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
.daggerheart.dh-style.countdown .countdown-container .countdown-inner-container .countdown-value-container input {
|
||||
max-width: 80px;
|
||||
}
|
||||
.daggerheart.dh-style.setting fieldset {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
@import './levelup.less';
|
||||
@import '../node_modules/@yaireo/tagify/dist/tagify.css';
|
||||
@import './resources.less';
|
||||
@import './countdown.less';
|
||||
@import './settings.less';
|
||||
|
||||
// new styles imports
|
||||
|
|
|
|||
|
|
@ -2,26 +2,42 @@
|
|||
.encounter-controls.combat {
|
||||
justify-content: space-between;
|
||||
|
||||
.encounter-control-fear-container {
|
||||
.encounter-fear-controls {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: black;
|
||||
gap: 8px;
|
||||
|
||||
.dice {
|
||||
height: 24px;
|
||||
.encounter-fear-dice-container {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
|
||||
.encounter-control-fear-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: black;
|
||||
|
||||
.dice {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
.encounter-control-fear {
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.encounter-control-counter {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.encounter-control-fear {
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.encounter-control-counter {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
color: var(--color-text-secondary);
|
||||
.encounter-countdowns {
|
||||
color: var(--content-link-icon-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@
|
|||
{{formInput settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{localize "DAGGERHEART.Settings.Automation.FIELDS.countdowns.label"}}</label>
|
||||
<div class="form-fields">
|
||||
{{formInput settingFields.schema.fields.countdowns value=settingFields._source.countdowns }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="form-footer">
|
||||
<button data-action="reset">
|
||||
|
|
|
|||
|
|
@ -52,10 +52,15 @@
|
|||
|
||||
<div class="encounter-controls {{#if hasCombat}}combat{{/if}}">
|
||||
{{#if hasCombat}}
|
||||
<div class="encounter-control-fear-container">
|
||||
<img class="dice " src="../icons/svg/d12-grey.svg"/>
|
||||
<i class="fas fa-skull encounter-control-fear"></i>
|
||||
<div class="encounter-control-counter">{{fear}}</div>
|
||||
<div class="encounter-fear-controls">
|
||||
<div class="encounter-fear-dice-container">
|
||||
<div class="encounter-control-fear-container">
|
||||
<img class="dice " src="../icons/svg/d12-grey.svg"/>
|
||||
<i class="fas fa-skull encounter-control-fear"></i>
|
||||
</div>
|
||||
<div>{{fear}}</div>
|
||||
</div>
|
||||
<a class="encounter-countdowns" data-tooltip="{{localize "DAGGERHEART.Countdown.Title" type=(localize "DAGGERHEART.Countdown.Types.combat")}}" data-action="openCountdowns"><i class="fa-solid fa-stopwatch"></i></a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,31 @@
|
|||
<div>
|
||||
<div>{{localize "DAGGERHEART.Countdown.Title"}} <a><i class="fa-solid fa-plus icon-button" data-action="addCountdown"></i></a></div>
|
||||
{{#each source.countdowns}}
|
||||
<fieldset>
|
||||
<legend>{{this.name}} <a><i class="fa-solid fa-trash icon-button" data-action="removeCountdown" data-countdown="{{@key}}"></i></a></legend>
|
||||
<div class="expanded-view {{#if minimized}}hidden{{/if}}">
|
||||
<div class="flexrow"><button data-action="addCountdown">{{localize "DAGGERHEART.Countdown.AddCountdown"}}</button></div>
|
||||
{{#each source.countdowns}}
|
||||
<fieldset>
|
||||
<legend>{{this.name}} <a><i class="fa-solid fa-trash icon-button" data-action="removeCountdown" data-countdown="{{@key}}"></i></a></legend>
|
||||
|
||||
{{formGroup @root.countdownFields.name name=(concat @root.base ".countdowns." @key ".name") value=this.name localize=true}}
|
||||
|
||||
{{formGroup @root.countdownFields.progress.fields.current name=(concat @root.base ".countdowns." @key ".progress.current") value=this.progress.current localize=true}}
|
||||
{{formGroup @root.countdownFields.progress.fields.type.fields.value name=(concat @root.base ".countdowns." @key ".progress.type.value") value=this.progress.type.value localize=true localize=true}}
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
<div class="countdown-container">
|
||||
<img src="{{this.img}}" data-action='editImage' data-countdown="{{@key}}" />
|
||||
<div class="countdown-inner-container">
|
||||
{{formGroup @root.countdownFields.name name=(concat @root.base ".countdowns." @key ".name") value=this.name localize=true}}
|
||||
<div class="countdown-value-container">
|
||||
{{formGroup @root.countdownFields.progress.fields.current name=(concat @root.base ".countdowns." @key ".progress.current") value=this.progress.current localize=true}}
|
||||
{{formGroup @root.countdownFields.progress.fields.max name=(concat @root.base ".countdowns." @key ".progress.max") value=this.progress.max localize=true}}
|
||||
</div>
|
||||
{{formGroup @root.countdownFields.progress.fields.type.fields.value name=(concat @root.base ".countdowns." @key ".progress.type.value") value=this.progress.type.value localize=true localize=true}}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="minimized-view {{#if (not minimized)}}hidden{{/if}}">
|
||||
{{#each source.countdowns}}
|
||||
<a class="mini-countdown-container" data-countdown="{{@key}}">
|
||||
<img src="{{this.img}}" />
|
||||
<div class="mini-countdown-name">{{this.name}}</div>
|
||||
<div class="mini-countdown-value">{{this.progress.current}}/{{this.progress.max}}</div>
|
||||
</a>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue