diff --git a/lang/en.json b/lang/en.json index 80cc67f7..39e49b67 100755 --- a/lang/en.json +++ b/lang/en.json @@ -249,8 +249,9 @@ "title": "{actor} - Death Move" }, "Downtime": { - "downtimeHeader": "Downtime Moves ({current}/{max})", "longRest": { + "title": "Long Rest", + "moves": "Long Rest Moves ({current}/{max})", "clearStress": { "description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.", "name": "Clear Stress" @@ -267,7 +268,6 @@ "description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.", "name": "Tend to Wounds" }, - "title": "Long Rest", "workOnAProject": { "description": "Establish or continue work on a project.", "name": "Work on a Project" @@ -275,6 +275,7 @@ }, "shortRest": { "title": "Short Rest", + "moves": "Short Rest Moves ({current}/{max})", "tendToWounds": { "name": "Tend to Wounds", "description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead." @@ -291,7 +292,8 @@ "name": "Prepare", "description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope." } - } + }, + "takeDowntime": "Take Downtime" }, "HUD": { "tokenHUD": { @@ -1012,6 +1014,30 @@ "singular": "Adversary", "plural": "Adversaries" }, + "Bonuses": { + "rest": { + "shortRest": { + "shortRestMoves": { + "label": "Short Rest: Bonus Short Rest Moves", + "hint": "The number of extra Short Rest Moves the character can take during a Short Rest." + }, + "longRestMoves": { + "label": "Short Rest: Bonus Long Rest Moves", + "hint": "The number of extra Long Rest Moves the character can take during a Short Rest." + } + }, + "longRest": { + "shortRestMoves": { + "label": "Long Rest: Bonus Short Rest Moves", + "hint": "The number of extra Short Rest Moves the character can take during a Long Rest." + }, + "longRestMoves": { + "label": "Long Rest: Bonus Long Rest Moves", + "hint": "The number of extra Long Rest Moves the character can take during a Long Rest." + } + } + } + }, "Character": { "singular": "Character", "plural": "Characters" diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 3966f7e4..15add3ad 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -7,8 +7,22 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV this.actor = actor; this.shortrest = shortrest; - const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves; - this.moveData = shortrest ? options.shortRest : options.longRest; + this.moveData = foundry.utils.deepClone( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves + ); + this.nrChoices = { + shortRest: { + max: + (shortrest ? this.moveData.shortRest.nrChoices : 0) + + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].shortMoves + }, + longRest: { + max: + (!shortrest ? this.moveData.longRest.nrChoices : 0) + + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].longMoves + } + }; + this.nrChoices.total = { max: this.nrChoices.shortRest.max + this.nrChoices.longRest.max }; } get title() { @@ -17,8 +31,8 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'downtime'], - position: { width: 680, height: 'auto' }, + classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'downtime'], + position: { width: 'auto', height: 'auto' }, actions: { selectMove: this.selectMove, takeDowntime: this.takeDowntime @@ -29,7 +43,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static PARTS = { application: { id: 'downtime', - template: 'systems/daggerheart/templates/dialogs/downtime.hbs' + template: 'systems/daggerheart/templates/dialogs/downtime/downtime.hbs' } }; @@ -37,46 +51,83 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV super._attachPartListeners(partId, htmlElement, options); htmlElement - .querySelectorAll('.activity-image') + .querySelectorAll('.activity-container') .forEach(element => element.addEventListener('contextmenu', this.deselectMove.bind(this))); } async _prepareContext(_options) { const context = await super._prepareContext(_options); + context.title = game.i18n.localize( + `DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title` + ); context.selectedActivity = this.selectedActivity; context.moveData = this.moveData; - context.nrCurrentChoices = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); - context.disabledDowntime = context.nrCurrentChoices < context.moveData.nrChoices; + context.nrCurrentChoices = Object.values(this.moveData).reduce((acc, category) => { + acc += Object.values(category.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); + return acc; + }, 0); + + context.nrChoices = { + ...this.nrChoices, + shortRest: { + ...this.nrChoices.shortRest, + current: Object.values(this.moveData.shortRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + }, + longRest: { + ...this.nrChoices.longRest, + current: Object.values(this.moveData.longRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + } + }; + context.nrChoices.total = { + ...this.nrChoices.total, + current: context.nrChoices.shortRest.current + context.nrChoices.longRest.current + }; + + context.shortRestMoves = this.nrChoices.shortRest.max > 0 ? this.moveData.shortRest : null; + context.longRestMoves = this.nrChoices.longRest.max > 0 ? this.moveData.longRest : null; + + context.disabledDowntime = context.nrChoices.total.current < context.nrChoices.total.max; return context; } - static selectMove(_, button) { - const nrSelected = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); - if (nrSelected === this.moveData.nrChoices) { + static selectMove(_, target) { + const nrSelected = Object.values(this.moveData[target.dataset.category].moves).reduce( + (acc, x) => acc + (x.selected ?? 0), + 0 + ); + + if (nrSelected === this.nrChoices[target.dataset.category].max) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves')); return; } - const move = button.dataset.move; - this.moveData.moves[move].selected = this.moveData.moves[move].selected - ? this.moveData.moves[move].selected + 1 + const move = target.dataset.move; + this.moveData[target.dataset.category].moves[move].selected = this.moveData[target.dataset.category].moves[move] + .selected + ? this.moveData[target.dataset.category].moves[move].selected + 1 : 1; this.render(); } deselectMove(event) { - const move = event.currentTarget.dataset.move; - this.moveData.moves[move].selected = this.moveData.moves[move].selected - ? this.moveData.moves[move].selected - 1 + const button = event.target.closest('.activity-container'); + const move = button.dataset.move; + this.moveData[button.dataset.category].moves[move].selected = this.moveData[button.dataset.category].moves[move] + .selected + ? this.moveData[button.dataset.category].moves[move].selected - 1 : 0; this.render(); } static async takeDowntime() { - const moves = Object.values(this.moveData.moves).filter(x => x.selected); + const moves = Object.values(this.moveData).flatMap(category => { + return Object.values(category.moves) + .filter(x => x.selected) + .flatMap(move => [...Array(move.selected).keys()].map(_ => move)); + }); const cls = getDocumentClass('ChatMessage'); const msg = new cls({ diff --git a/module/applications/settings/components/settingsActionsView.mjs b/module/applications/settings/components/settingsActionsView.mjs index a905e824..f77c5fce 100644 --- a/module/applications/settings/components/settingsActionsView.mjs +++ b/module/applications/settings/components/settingsActionsView.mjs @@ -4,13 +4,14 @@ import DHActionConfig from '../../sheets-configs/action-config.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DhSettingsActionView extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(resolve, reject, title, name, img, description, actions) { + constructor(resolve, reject, title, name, icon, img, description, actions) { super({}); this.resolve = resolve; this.reject = reject; this.viewTitle = title; this.name = name; + this.icon = icon; this.img = img; this.description = description; this.actions = actions; @@ -23,7 +24,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App static DEFAULT_OPTIONS = { tag: 'form', classes: ['daggerheart', 'setting', 'dh-style'], - position: { width: '400', height: 'auto' }, + position: { width: 440, height: 'auto' }, actions: { editImage: this.onEditImage, addItem: this.addItem, @@ -46,6 +47,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App async _prepareContext(_options) { const context = await super._prepareContext(_options); context.name = this.name; + context.icon = this.icon; context.img = this.img; context.description = this.description; context.enrichedDescription = await foundry.applications.ux.TextEditor.enrichHTML(context.description); @@ -55,8 +57,9 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App } static async updateData(event, element, formData) { - const { name, img, description } = foundry.utils.expandObject(formData.object); + const { name, icon, description } = foundry.utils.expandObject(formData.object); this.name = name; + this.icon = icon; this.description = description; this.render(); @@ -65,6 +68,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App static async saveForm(event) { this.resolve({ name: this.name, + icon: this.icon, img: this.img, description: this.description, actions: this.actions diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 08b4cf4e..e516be03 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -76,6 +76,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli reject, game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.downtimeMoves'), move.name, + move.icon, move.img, move.description, move.actions @@ -87,6 +88,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli await this.settings.updateSource({ [`restMoves.${type}.moves.${id}`]: { name: data.name, + icon: data.icon, img: data.img, description: data.description } diff --git a/module/applications/sheets-configs/activeEffectConfig.mjs b/module/applications/sheets-configs/activeEffectConfig.mjs index 8574a5db..087b5b08 100644 --- a/module/applications/sheets-configs/activeEffectConfig.mjs +++ b/module/applications/sheets-configs/activeEffectConfig.mjs @@ -88,6 +88,9 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac element.value = `system.${item.value}`; }, click: e => e.fetch(), + customize: function (_input, _inputRect, container) { + container.style.zIndex = foundry.applications.api.ApplicationV2._maxZ; + }, minLength: 0 }); }); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 139a1369..0f6f8284 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -28,7 +28,8 @@ export default class CharacterSheet extends DHBaseActorSheet { useAction: this.useAction, toggleResourceDice: this.toggleResourceDice, handleResourceDice: this.handleResourceDice, - toChat: this.toChat + toChat: this.toChat, + useDowntime: this.useDowntime }, window: { resizable: true @@ -752,6 +753,12 @@ export default class CharacterSheet extends DHBaseActorSheet { } } + static useDowntime(_, button) { + new game.system.api.applications.dialogs.Downtime(this.document, button.dataset.type === 'shortRest').render( + true + ); + } + async _onDragStart(event) { const item = this.getItem(event); diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 704a5401..632e5448 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -130,6 +130,7 @@ export const defaultRestOptions = { tendToWounds: { id: 'tendToWounds', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'), + icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.description'), actions: [ @@ -153,6 +154,7 @@ export const defaultRestOptions = { clearStress: { id: 'clearStress', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'), + icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.description'), actions: [ @@ -176,6 +178,7 @@ export const defaultRestOptions = { repairArmor: { id: 'repairArmor', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'), + icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'), actions: [] @@ -183,6 +186,7 @@ export const defaultRestOptions = { prepare: { id: 'prepare', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.name'), + icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'), actions: [] @@ -192,6 +196,7 @@ export const defaultRestOptions = { tendToWounds: { id: 'tendToWounds', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'), + icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.description'), actions: [] @@ -199,6 +204,7 @@ export const defaultRestOptions = { clearStress: { id: 'clearStress', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'), + icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.description'), actions: [] @@ -206,6 +212,7 @@ export const defaultRestOptions = { repairArmor: { id: 'repairArmor', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'), + icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.description'), actions: [] @@ -213,6 +220,7 @@ export const defaultRestOptions = { prepare: { id: 'prepare', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.name'), + icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'), actions: [] @@ -220,19 +228,12 @@ export const defaultRestOptions = { workOnAProject: { id: 'workOnAProject', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.name'), + icon: 'fa-solid fa-diagram-project', img: 'icons/skills/social/thumbsup-approval-like.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'), actions: [] } - }), - custom: { - id: 'customActivity', - name: '', - img: 'icons/skills/trades/academics-investigation-puzzles.webp', - description: '', - namePlaceholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.namePlaceholder', - placeholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.placeholder' - } + }) }; export const deathMoves = { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 1c15d036..c15d2221 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -126,6 +126,44 @@ export default class DhCharacter extends BaseDataActor { }), rally: new fields.ArrayField(new fields.StringField(), { label: 'DAGGERHEART.CLASS.Feature.rallyDice' + }), + rest: new fields.SchemaField({ + shortRest: new fields.SchemaField({ + shortMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.hint' + }), + longMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.hint' + }) + }), + longRest: new fields.SchemaField({ + shortMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.hint' + }), + longMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.hint' + }) + }) }) }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index ead5a09f..008cd73c 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -54,6 +54,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { moves: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField({ required: true }), + icon: new fields.StringField({ required: true }), img: new fields.FilePathField({ initial: 'icons/magic/life/cross-worn-green.webp', categories: ['IMAGE'], @@ -70,6 +71,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { moves: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField({ required: true }), + icon: new fields.StringField({ required: true }), img: new fields.FilePathField({ initial: 'icons/magic/life/cross-worn-green.webp', categories: ['IMAGE'], diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 3e7b49ea..89305128 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -16,7 +16,7 @@ export default class DHToken extends TokenDocument { }); bars.sort((a, b) => a.label.compare(b.label)); - const invalidAttributes = ['gold', 'levelData', 'rules.damageReduction.maxArmorMarked.value']; + const invalidAttributes = ['gold', 'levelData', 'actions', 'rules.damageReduction.maxArmorMarked.value']; const values = attributes.value.reduce((acc, v) => { const a = v.join('.'); if (invalidAttributes.some(x => a.startsWith(x))) return acc; @@ -32,19 +32,19 @@ export default class DHToken extends TokenDocument { return bars.concat(values); } - - static _getTrackedAttributesFromSchema(schema, _path=[]) { - const attributes = {bar: [], value: []}; - for ( const [name, field] of Object.entries(schema.fields) ) { + + static _getTrackedAttributesFromSchema(schema, _path = []) { + const attributes = { bar: [], value: [] }; + for (const [name, field] of Object.entries(schema.fields)) { const p = _path.concat([name]); - if ( field instanceof foundry.data.fields.NumberField ) attributes.value.push(p); - if ( field instanceof foundry.data.fields.ArrayField ) attributes.value.push(p); + if (field instanceof foundry.data.fields.NumberField) attributes.value.push(p); + if (field instanceof foundry.data.fields.ArrayField) attributes.value.push(p); const isSchema = field instanceof foundry.data.fields.SchemaField; const isModel = field instanceof foundry.data.fields.EmbeddedDataField; - if ( isSchema || isModel ) { + if (isSchema || isModel) { const schema = isModel ? field.model.schema : field; - const isBar = schema.has && schema.has("value") && schema.has("max"); - if ( isBar ) attributes.bar.push(p); + const isBar = schema.has && schema.has('value') && schema.has('max'); + if (isBar) attributes.bar.push(p); else { const inner = this.getTrackedAttributes(schema, p); attributes.bar.push(...inner.bar); diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index f24823f4..e622059d 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -22,6 +22,28 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti options.direction = this._determineItemTooltipDirection(element); } } else { + const shortRest = element.dataset.tooltip?.startsWith('#shortRest#'); + const longRest = element.dataset.tooltip?.startsWith('#longRest#'); + if (shortRest || longRest) { + const key = element.dataset.tooltip.slice(shortRest ? 11 : 10); + const downtimeOptions = shortRest + ? CONFIG.DH.GENERAL.defaultRestOptions.shortRest() + : CONFIG.DH.GENERAL.defaultRestOptions.longRest(); + const move = downtimeOptions[key]; + html = await foundry.applications.handlebars.renderTemplate( + `systems/daggerheart/templates/ui/tooltip/downtime.hbs`, + { + move: move + } + ); + + this.tooltip.innerHTML = html; + options.direction = this._determineItemTooltipDirection( + element, + this.constructor.TOOLTIP_DIRECTIONS.UP + ); + } + const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#'); const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#'); if (isAdvantage || isDisadvantage) { @@ -44,9 +66,34 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti super.activate(element, { ...options, html: html }); } - _determineItemTooltipDirection(element) { + _determineItemTooltipDirection(element, prefered = this.constructor.TOOLTIP_DIRECTIONS.LEFT) { const pos = element.getBoundingClientRect(); const dirs = this.constructor.TOOLTIP_DIRECTIONS; - return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT']; + switch (prefered) { + case this.constructor.TOOLTIP_DIRECTIONS.LEFT: + return dirs[ + pos.x - this.tooltip.offsetWidth < 0 + ? this.constructor.TOOLTIP_DIRECTIONS.DOWN + : this.constructor.TOOLTIP_DIRECTIONS.LEFT + ]; + case this.constructor.TOOLTIP_DIRECTIONS.UP: + return dirs[ + pos.y - this.tooltip.offsetHeight < 0 + ? this.constructor.TOOLTIP_DIRECTIONS.RIGHT + : this.constructor.TOOLTIP_DIRECTIONS.UP + ]; + case this.constructor.TOOLTIP_DIRECTIONS.RIGHT: + return dirs[ + pos.x + this.tooltip.offsetWidth > document.body.clientWidth + ? this.constructor.TOOLTIP_DIRECTIONS.DOWN + : this.constructor.TOOLTIP_DIRECTIONS.RIGHT + ]; + case this.constructor.TOOLTIP_DIRECTIONS.DOWN: + return dirs[ + pos.y + this.tooltip.offsetHeight > document.body.clientHeight + ? this.constructor.TOOLTIP_DIRECTIONS.LEFT + : this.constructor.TOOLTIP_DIRECTIONS.DOWN + ]; + } } } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 8456094c..0c455750 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -25,6 +25,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', 'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs', 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs', - 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs' + 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', + 'systems/daggerheart/templates/dialogs/downtime/activities.hbs' ]); }; diff --git a/styles/less/dialog/downtime/downtime-container.less b/styles/less/dialog/downtime/downtime-container.less index 4e785e7b..0f803d9b 100644 --- a/styles/less/dialog/downtime/downtime-container.less +++ b/styles/less/dialog/downtime/downtime-container.less @@ -1,81 +1,75 @@ @import '../../utils/spacing.less'; @import '../../utils/colors.less'; -.daggerheart.views { +.theme-light .daggerheart.dh-style.views.downtime { + .downtime-container .activity-container .activity-selected-marker { + background-image: url(../assets/parchments/dh-parchment-light.png); + } +} + +.daggerheart.dh-style.views.downtime { + font-family: @font-body; + .downtime-container { - .downtime-header { - margin: 0; - color: light-dark(@dark-blue, @golden); - text-align: center; + .activities-grouping { + width: 280px; } - .activity-container { - display: flex; - align-items: center; - padding: 8px; + .activities-container { + width: 100%; - .activity-title { - flex: 1; + .activity-container { display: flex; align-items: center; + justify-content: space-between; + padding: 8px; - .activity-title-text { - font-size: 24px; - font-weight: bold; - } - - .activity-image { - width: 80px; - position: relative; + .activity-inner-container { display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; + align-items: center; + gap: 4px; - .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; + .activity-marker { + font-size: 8px; + flex: none; + color: light-dark(#18162e, #f3c267); + margin-right: 4px; } - img { - border-radius: 50%; - } + .activity-select-section { + display: flex; + align-items: center; + gap: 4px; - &:hover, - &.selected { - filter: drop-shadow(0 0 6px gold); + .activity-icon { + min-width: 24px; + text-align: center; + } } } - .custom-name-input { - font-size: 24px; + .activity-selected-marker { + font-size: 14px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url(../assets/parchments/dh-parchment-dark.png); + padding: 0 8px; + line-height: 1; font-weight: bold; - padding: 0; - background: transparent; - color: rgb(239, 230, 216); } } - - .activity-body { - flex: 1; - font-style: italic; - } } } - &.downtime { - .activity-text-area { - resize: none; + footer { + margin-top: 8px; + display: flex; + gap: 8px; + + button { + flex: 1; + font-family: 'Montserrat', sans-serif; } } } diff --git a/styles/less/global/tab-navigation.less b/styles/less/global/tab-navigation.less index 2880711d..014da89f 100755 --- a/styles/less/global/tab-navigation.less +++ b/styles/less/global/tab-navigation.less @@ -7,12 +7,22 @@ height: 40px; width: 100%; - .feature-tab { - border: none; + .navigation-container { + display: flex; + align-items: center; + gap: 8px; - a { - color: light-dark(@dark-blue, @golden); - font-family: @font-body; + .navigation-inner-container { + flex: 1; + + .feature-tab { + border: none; + + a { + color: light-dark(@dark-blue, @golden); + font-family: @font-body; + } + } } } } diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 6110fcc6..b80da83d 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -193,5 +193,14 @@ } } } + + .character-downtime-container { + display: flex; + gap: 2px; + + button { + flex: 1; + } + } } } diff --git a/styles/less/ux/autocomplete/autocomplete.less b/styles/less/ux/autocomplete/autocomplete.less index 06cabf5a..868b4f43 100644 --- a/styles/less/ux/autocomplete/autocomplete.less +++ b/styles/less/ux/autocomplete/autocomplete.less @@ -10,7 +10,6 @@ border-color: light-dark(@dark, @beige); border-radius: 6px; background-image: url('../assets/parchments/dh-parchment-dark.png'); - z-index: 200; max-height: 400px !important; width: fit-content !important; overflow-y: auto; diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less index 38502d09..0060f74b 100644 --- a/styles/less/ux/tooltip/tooltip.less +++ b/styles/less/ux/tooltip/tooltip.less @@ -4,6 +4,20 @@ align-items: center; gap: 4px; + .tooltip-title-container { + width: 100%; + display: flex; + align-items: center; + gap: 16px; + + .tooltip-image { + height: 40px; + width: 40px; + border-radius: 6px; + border: 1px solid @golden; + } + } + .tooltip-title { margin: 0; text-align: center; diff --git a/templates/dialogs/downtime.hbs b/templates/dialogs/downtime.hbs deleted file mode 100644 index fd5fa405..00000000 --- a/templates/dialogs/downtime.hbs +++ /dev/null @@ -1,24 +0,0 @@ -
-
-

{{localize "DAGGERHEART.APPLICATIONS.Downtime.downtimeHeader" current=nrCurrentChoices max=moveData.nrChoices}}

- {{#each moveData.moves as |move key|}} -
-
-
- {{#if this.selected}}
{{move.selected}}
{{/if}} - -
- - {{localize this.name}} -
-
- {{localize this.description}} -
-
- {{/each}} -
- -
\ No newline at end of file diff --git a/templates/dialogs/downtime/activities.hbs b/templates/dialogs/downtime/activities.hbs new file mode 100644 index 00000000..f67e8a10 --- /dev/null +++ b/templates/dialogs/downtime/activities.hbs @@ -0,0 +1,18 @@ +
+ {{localize (concat "DAGGERHEART.APPLICATIONS.Downtime." category ".moves") max=nrChoices.max current=nrChoices.current}} + +
+ {{#each moves as |move key|}} + +
+ +
+ +
{{move.name}}
+
+
+ {{#if move.selected}}
{{move.selected}}
{{/if}} +
+ {{/each}} +
+
\ No newline at end of file diff --git a/templates/dialogs/downtime/downtime.hbs b/templates/dialogs/downtime/downtime.hbs new file mode 100644 index 00000000..c8e44e5d --- /dev/null +++ b/templates/dialogs/downtime/downtime.hbs @@ -0,0 +1,14 @@ +
+
+

{{title}}

+
+ +
+ {{#if shortRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=shortRestMoves.moves category='shortRest' nrChoices=nrChoices.shortRest}}{{/if}} + {{#if longRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=longRestMoves.moves category='longRest' nrChoices=nrChoices.longRest}}{{/if}} +
+ +
\ No newline at end of file diff --git a/templates/settings/automation-settings.hbs b/templates/settings/automation-settings.hbs index 0e158ab6..910ace56 100644 --- a/templates/settings/automation-settings.hbs +++ b/templates/settings/automation-settings.hbs @@ -6,7 +6,7 @@ {{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}} -s {{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}} + {{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}