diff --git a/daggerheart.mjs b/daggerheart.mjs index 4f411b0f..5a6d8193 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -41,10 +41,14 @@ Hooks.once('init', () => { ] ); - CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({ - ...x, - name: game.i18n.localize(x.name) - })); + CONFIG.statusEffects = [ + ...CONFIG.statusEffects, + ...Object.values(SYSTEM.GENERAL.conditions).map(x => ({ + ...x, + name: game.i18n.localize(x.name), + systemEffect: true + })) + ]; CONFIG.Dice.daggerheart = { DualityDie: DualityDie, @@ -108,6 +112,8 @@ Hooks.once('init', () => { } ); + CONFIG.Token.hudClass = applications.hud.DHTokenHUD; + CONFIG.Combat.dataModels = { base: models.DhCombat }; diff --git a/lang/en.json b/lang/en.json index a7197047..2e938914 100755 --- a/lang/en.json +++ b/lang/en.json @@ -279,6 +279,11 @@ } } }, + "HUD": { + "tokenHUD": { + "genericEffects": "Foundry Effects" + } + }, "Levelup": { "actions": { "creatureComfort": { @@ -672,6 +677,10 @@ "name": "Dice Set" } }, + "SelectAction": { + "selectType": "Select Action Type", + "selectAction": "Select Action" + }, "Traits": { "agility": { "name": "Agility", @@ -968,6 +977,10 @@ "singular": "Character", "plural": "Characters" }, + "Cost": { + "single": "Cost", + "plural": "Costs" + }, "Damage": { "severe": "Severe", "major": "Major", @@ -1078,6 +1091,7 @@ "specialization": "Specialization", "mastery": "Mastery", "optional": "Optional", + "recovery": "Recovery", "setup": "Setup", "equipment": "Equipment" }, @@ -1099,6 +1113,8 @@ "burden": "Burden", "check": "{check} Check", "criticalSuccess": "Critical Success", + "damage": "Damage", + "damageType": "Damage Type", "description": "Description", "duality": "Duality", "dualityRoll": "Duality Roll", @@ -1111,17 +1127,25 @@ "inactiveEffects": "Inactive Effects", "inventory": "Inventory", "level": "Level", + "max": "Max", "modifier": "Modifier", "multiclass": "Multiclass", + "none": "None", "quantity": "Quantity", "range": "Range", + "recovery": "Recovery", + "scalable": "Scalable", "stress": "Stress", "take": "Take", "target": "Target", "title": "Title", + "true": "True", "type": "Type", "unarmored": "Unarmored", - "use": "Use" + "use": "Use", + "used": "Used", + "uses": "Uses", + "value": "Value" }, "ITEMS": { "Armor": { @@ -1178,6 +1202,7 @@ "spellcastingTrait": "Spellcasting Trait" }, "Weapon": { + "weaponType": "Weapon Type", "primaryWeapon": "Primary Weapon", "secondaryWeapon": "Secondary Weapon" } @@ -1185,7 +1210,8 @@ "SETTINGS": { "Appearance": { "FIELDS": { - "displayFear": { "label": "Fear Display" } + "displayFear": { "label": "Fear Display" }, + "showGenericStatusEffects": { "label": "Show Foundry Status Effects" } }, "fearDisplay": { "token": "Tokens", @@ -1385,7 +1411,8 @@ "unequip": "Unequip", "sendToVault": "Send to Vault", "sendToLoadout": "Send to Loadout", - "makeDeathMove": "Make a Death Move" + "makeDeathMove": "Make a Death Move", + "rangeAndTarget": "Range & Target" } } } diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 82c2866c..d4ceb229 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -1,5 +1,6 @@ export * as characterCreation from './characterCreation/_module.mjs'; export * as dialogs from './dialogs/_module.mjs'; +export * as hud from './hud/_module.mjs'; export * as levelup from './levelup/_module.mjs'; export * as settings from './settings/_module.mjs'; export * as sheets from './sheets/_module.mjs'; diff --git a/module/applications/dialogs/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs index 026aac46..abb79e6a 100644 --- a/module/applications/dialogs/costSelectionDialog.mjs +++ b/module/applications/dialogs/costSelectionDialog.mjs @@ -11,7 +11,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 442a1491..4030d7a7 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -11,11 +11,14 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application static DEFAULT_OPTIONS = { tag: 'form', id: 'roll-selection', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' }, + window: { + icon: 'fa-solid fa-dice' + }, actions: { submitRoll: this.submitRoll }, @@ -34,9 +37,15 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application } }; + get title() { + return game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); + } + async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.title = this.config.title; + context.title = this.config.title + ? this.config.title + : game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); return context; diff --git a/module/applications/dialogs/damageSelectionDialog.mjs b/module/applications/dialogs/damageSelectionDialog.mjs index 5248e81d..547ba87c 100644 --- a/module/applications/dialogs/damageSelectionDialog.mjs +++ b/module/applications/dialogs/damageSelectionDialog.mjs @@ -23,7 +23,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' diff --git a/module/applications/hud/_module.mjs b/module/applications/hud/_module.mjs new file mode 100644 index 00000000..70edaf8f --- /dev/null +++ b/module/applications/hud/_module.mjs @@ -0,0 +1 @@ +export { default as DHTokenHUD } from './tokenHud.mjs'; diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs new file mode 100644 index 00000000..9a58bab2 --- /dev/null +++ b/module/applications/hud/tokenHUD.mjs @@ -0,0 +1,84 @@ +export default class DHTokenHUD extends TokenHUD { + static DEFAULT_OPTIONS = { + classes: ['daggerheart'] + }; + + /** @override */ + static PARTS = { + hud: { + root: true, + template: 'systems/daggerheart/templates/hud/tokenHUD.hbs' + } + }; + + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => { + const effect = context.statusEffects[key]; + if (effect.systemEffect) acc[key] = effect; + + return acc; + }, {}); + + const useGeneric = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.appearance + ).showGenericStatusEffects; + context.genericStatusEffects = useGeneric + ? Object.keys(context.statusEffects).reduce((acc, key) => { + const effect = context.statusEffects[key]; + if (!effect.systemEffect) acc[key] = effect; + + return acc; + }, {}) + : null; + + return context; + } + + _getStatusEffectChoices() { + // Include all HUD-enabled status effects + const choices = {}; + for (const status of CONFIG.statusEffects) { + if ( + status.hud === false || + (foundry.utils.getType(status.hud) === 'Object' && + status.hud.actorTypes?.includes(this.document.actor.type) === false) + ) { + continue; + } + choices[status.id] = { + _id: status._id, + id: status.id, + systemEffect: status.systemEffect, + title: game.i18n.localize(status.name ?? /** @deprecated since v12 */ status.label), + src: status.img ?? /** @deprecated since v12 */ status.icon, + isActive: false, + isOverlay: false + }; + } + + // Update the status of effects which are active for the token actor + const activeEffects = this.actor?.effects || []; + for (const effect of activeEffects) { + for (const statusId of effect.statuses) { + const status = choices[statusId]; + if (!status) continue; + if (status._id) { + if (status._id !== effect.id) continue; + } else { + if (effect.statuses.size !== 1) continue; + } + status.isActive = true; + if (effect.getFlag('core', 'overlay')) status.isOverlay = true; + break; + } + } + + // Flag status CSS class + for (const status of Object.values(choices)) { + status.cssClass = [status.isActive ? 'active' : null, status.isOverlay ? 'overlay' : null].filterJoin(' '); + } + return choices; + } +} diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 67f57781..0b01ebee 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -10,6 +10,7 @@ export default class AdversarySheet extends DHBaseActorSheet { actions: { reactionRoll: AdversarySheet.#reactionRoll, useItem: this.useItem, + useAction: this.useItem, toChat: this.toChat }, window: { diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index e70774f5..ae7ffbf9 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -24,6 +24,7 @@ export default class CharacterSheet extends DHBaseActorSheet { levelManagement: CharacterSheet.#levelManagement, toggleEquipItem: CharacterSheet.#toggleEquipItem, useItem: this.useItem, //TODO Fix this + useAction: this.useAction, toChat: this.toChat }, window: { @@ -620,6 +621,20 @@ export default class CharacterSheet extends DHBaseActorSheet { } } + /** + * Use an action + * @type {ApplicationClickAction} + */ + static async useAction(event, button) { + const item = this.getItem(button); + if (!item) return; + + const action = item.system.actions.find(x => x.id === button.dataset.actionId); + if (!action) return; + + action.use(event); + } + /** * Send item to Chat * @type {ApplicationClickAction} diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs index 188d24b4..05958cf5 100644 --- a/module/applications/sheets/actors/environment.mjs +++ b/module/applications/sheets/actors/environment.mjs @@ -11,6 +11,7 @@ export default class DhpEnvironment extends DHBaseActorSheet { }, actions: { useItem: this.useItem, + useAction: this.useItem, toChat: this.toChat }, dragDrop: [{ dragSelector: '.action-section .inventory-item', dropSelector: null }] diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index a54c3bcb..3d13d7de 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -61,12 +61,17 @@ export default class FeatureSheet extends DHBaseItemSheet { static async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } + { + types: CONFIG.DH.ACTIONS.actionTypes, + itemName: game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType') + } ), - title = 'Select Action Type'; + title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType'); + console.log(this.document); return foundry.applications.api.DialogV2.prompt({ window: { title }, + classes: ['daggerheart', 'dh-style'], content, ok: { label: title, diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 7a179308..02cfd4a9 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -113,7 +113,7 @@ export const adversaryTypes = { }, social: { id: 'social', - label: 'DAGGERHEART.CONFIG.AdversaryTypee.social.label', + label: 'DAGGERHEART.CONFIG.AdversaryType.social.label', description: 'DAGGERHEART.ACTORS.Adversary.social.description' }, solo: { diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 21db5809..b1c41ea3 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -70,7 +70,7 @@ export default class DhCompanion extends BaseDataActor { type: ['physical'], value: { dice: 'd6', - multiplier: 'flat' + multiplier: 'prof' } } ] @@ -88,6 +88,12 @@ export default class DhCompanion extends BaseDataActor { }; } + get proficiency() { + return { + total: this.partner?.system?.proficiency?.total ?? 1 + }; + } + prepareBaseData() { const partnerSpellcastingModifier = this.partner?.system?.spellcastingModifiers?.main; const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.total; diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 696a95a2..bf2bf73e 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -44,6 +44,12 @@ export default class DHArmor extends BaseDataItem { }; } + get customActions() { + return this.actions.filter( + action => !this.armorFeatures.some(feature => feature.actionIds.includes(action.id)) + ); + } + async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index b999e1e5..8f580b6d 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -74,6 +74,12 @@ export default class DHWeapon extends BaseDataItem { return [this.attack, ...this.actions]; } + get customActions() { + return this.actions.filter( + action => !this.weaponFeatures.some(feature => feature.actionIds.includes(action.id)) + ); + } + async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; diff --git a/module/data/settings/Appearance.mjs b/module/data/settings/Appearance.mjs index 8b04f558..d8b4c687 100644 --- a/module/data/settings/Appearance.mjs +++ b/module/data/settings/Appearance.mjs @@ -40,6 +40,10 @@ export default class DhAppearance extends foundry.abstract.DataModel { outline: new fields.ColorField({ required: true, initial: '#ffffff' }), edge: new fields.ColorField({ required: true, initial: '#000000' }) }) + }), + showGenericStatusEffects: new fields.BooleanField({ + initial: true, + label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.showGenericStatusEffects.label' }) }; } diff --git a/module/data/settings/RangeMeasurement.mjs b/module/data/settings/RangeMeasurement.mjs index 71fb7787..552963f0 100644 --- a/module/data/settings/RangeMeasurement.mjs +++ b/module/data/settings/RangeMeasurement.mjs @@ -2,7 +2,7 @@ export default class DhRangeMeasurement extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { - enabled: new fields.BooleanField({ required: true, initial: false, label: 'DAGGERHEART.GENERAL.enabled' }), + enabled: new fields.BooleanField({ required: true, initial: true, label: 'DAGGERHEART.GENERAL.enabled' }), melee: new fields.NumberField({ required: true, initial: 5, label: 'DAGGERHEART.CONFIG.Range.melee.name' }), veryClose: new fields.NumberField({ required: true, diff --git a/module/documents/item.mjs b/module/documents/item.mjs index db34fa49..6c3732db 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -80,12 +80,16 @@ export default class DHItem extends foundry.documents.Item { async selectActionDialog(prevEvent) { const content = await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/dialogs/actionSelect.hbs', - { actions: this.system.actionsList } + { + actions: this.system.actionsList, + itemName: this.name + } ), - title = 'Select Action'; + title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectAction'); return foundry.applications.api.DialogV2.prompt({ window: { title }, + classes: ['daggerheart', 'dh-style'], content, ok: { label: title, diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index 2e660cff..d9444207 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -2,15 +2,33 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti async activate(element, options = {}) { let html = options.html; if (element.dataset.tooltip?.startsWith('#item#')) { - const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6)); + const splitValues = element.dataset.tooltip.slice(6).split('#action#'); + const itemUuid = splitValues[0]; + const actionId = splitValues.length > 1 ? splitValues[1] : null; + + const baseItem = await foundry.utils.fromUuid(itemUuid); + const item = actionId ? baseItem.system.actions.find(x => x.id === actionId) : baseItem; if (item) { + const type = actionId ? 'action' : item.type; html = await foundry.applications.handlebars.renderTemplate( - `systems/daggerheart/templates/ui/tooltip/${item.type}.hbs`, - item + `systems/daggerheart/templates/ui/tooltip/${type}.hbs`, + { + item: item, + config: CONFIG.DH + } ); + + this.tooltip.innerHTML = html; + options.direction = this._determineItemTooltipDirection(element); } } super.activate(element, { ...options, html: html }); } + + _determineItemTooltipDirection(element) { + const pos = element.getBoundingClientRect(); + const dirs = this.constructor.TOOLTIP_DIRECTIONS; + return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT']; + } } diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 6db51225..feeebbd2 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -1,47 +1,49 @@ -import { getWidthOfText } from './utils.mjs'; - export default class RegisterHandlebarsHelpers { static registerHelpers() { Handlebars.registerHelper({ - times: this.times, - join: this.join, add: this.add, - subtract: this.subtract, includes: this.includes, - case: this.case + times: this.times, + damageFormula: this.damageFormula, + damageSymbols: this.damageSymbols, + tertiary: this.tertiary, + signedNumber: this.signedNumber }); } - static times(nr, block) { - var accum = ''; - for (var i = 0; i < nr; ++i) accum += block.fn(i); - return accum; - } - - static join(...options) { - return options.slice(0, options.length - 1); - } - static add(a, b) { const aNum = Number.parseInt(a); const bNum = Number.parseInt(b); return (Number.isNaN(aNum) ? 0 : aNum) + (Number.isNaN(bNum) ? 0 : bNum); } - static subtract(a, b) { - const aNum = Number.parseInt(a); - const bNum = Number.parseInt(b); - return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum); - } - static includes(list, item) { return list.includes(item); } - static case(value, options) { - if (value == this.switch_value) { - this.switch_break = true; - return options.fn(this); - } + static times(nr, block) { + var accum = ''; + for (var i = 0; i < nr; ++i) accum += block.fn(i); + return accum; + } + + static damageFormula(attack, actor) { + const traitTotal = actor.system.traits?.[attack.roll.trait]?.total; + const instances = [ + attack.damage.parts.map(x => Roll.replaceFormulaData(x.value.getFormula(), actor)).join(' + '), + traitTotal + ].filter(x => x); + + return instances.join(traitTotal > 0 ? ' + ' : ' - '); + } + + static damageSymbols(damageParts) { + const symbols = new Set(); + damageParts.forEach(part => symbols.add(...CONFIG.DH.GENERAL.damageTypes[part.type].icon)); + return new Handlebars.SafeString(Array.from(symbols).map(symbol => ``)); + } + + static tertiary(a, b) { + return a ?? b; } } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 75a5aff6..e4cc1a2c 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -22,6 +22,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/actionTypes/beastform.hbs', '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/chat/parts/target-chat.hbs', + 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs' ]); }; diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index a4ed05c8..fea12acd 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -60,7 +60,7 @@ const registerMenuSettings = () => { }); game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement, { - scope: 'client', + scope: 'world', config: false, type: DhRangeMeasurement }); diff --git a/styles/daggerheart.less b/styles/daggerheart.less index 86b504b2..c2127681 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -3,6 +3,8 @@ @import './less/dialog/index.less'; +@import './less//hud/index.less'; + @import './less/utils/colors.less'; @import './less/utils/fonts.less'; @@ -10,4 +12,6 @@ @import './less/ui/index.less'; +@import './less/ux/index.less'; + @import '../node_modules/@yaireo/tagify/dist/tagify.css'; diff --git a/styles/less/dialog/actions/action-list.less b/styles/less/dialog/actions/action-list.less new file mode 100644 index 00000000..800f7d8e --- /dev/null +++ b/styles/less/dialog/actions/action-list.less @@ -0,0 +1,19 @@ +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style { + .actions-list { + display: flex; + flex-direction: column; + gap: 10px; + + .action-item { + display: flex; + align-items: center; + gap: 5px; + + .label { + font-family: @font-body; + } + } + } +} diff --git a/styles/less/dialog/damage-selection/sheet.less b/styles/less/dialog/damage-selection/sheet.less new file mode 100644 index 00000000..43e4f4d2 --- /dev/null +++ b/styles/less/dialog/damage-selection/sheet.less @@ -0,0 +1,20 @@ +@import '../../utils/colors.less'; + +.daggerheart.dialog.dh-style.views.damage-selection { + .damage-section-container { + display: flex; + flex-direction: column; + gap: 12px; + + input[type='text'], + input[type='number'] { + color: light-dark(@dark, @beige); + outline: 2px solid transparent; + transition: all 0.3s ease; + + &:hover { + outline: 2px solid light-dark(@dark, @beige); + } + } + } +} diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index b2f05dc2..575b7ce9 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -114,15 +114,5 @@ } } } - - .formula-label { - font-family: @font-body; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 17px; - - color: light-dark(@dark, @beige); - } } } diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index 40280270..545ce2e1 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -4,6 +4,10 @@ @import './level-up/summary-container.less'; @import './level-up/tiers-container.less'; +@import './actions/action-list.less'; + +@import './damage-selection/sheet.less'; + @import './downtime/downtime-container.less'; @import './beastform/beastform-container.less'; diff --git a/styles/less/global/dialog.less b/styles/less/global/dialog.less index 3856facb..11a4eee9 100644 --- a/styles/less/global/dialog.less +++ b/styles/less/global/dialog.less @@ -1,5 +1,6 @@ @import '../utils/colors.less'; @import '../utils/fonts.less'; +@import '../utils/mixin.less'; .appTheme({ &.dialog { @@ -40,4 +41,19 @@ } } } + + .submit-btn { + width: 100%; + height: 38px; + } + + .formula-label { + font-family: @font-body; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 17px; + + color: light-dark(@dark, @beige); + } } diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index c732f256..ab519a1c 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -35,15 +35,16 @@ } } - input[type='checkbox'] { + input[type='checkbox'], + input[type='radio'] { &:checked::after { - color: light-dark(@dark, @golden); + color: light-dark(@dark-40, @golden); } &:checked::before { - color: light-dark(transparent, @dark-blue); + color: light-dark(@dark-40, @golden-40); } &::before { - color: light-dark(@dark, @beige); + color: light-dark(@dark-40, @golden-40); } } @@ -353,6 +354,17 @@ transform: translateY(-20px); transform-origin: top; } + + .item-buttons { + grid-column: span 3; + display: flex; + gap: 8px; + flex-wrap: wrap; + + button { + white-space: nowrap; + } + } } .application.setting.dh-style { diff --git a/styles/less/global/sheet.less b/styles/less/global/sheet.less index 1e44d7a0..1a00239a 100755 --- a/styles/less/global/sheet.less +++ b/styles/less/global/sheet.less @@ -4,8 +4,8 @@ // Theme handling .appTheme({ - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9px); + background: @dark-blue-60; + backdrop-filter: blur(10px); }, { background: url('../assets/parchments/dh-parchment-light.png') no-repeat center; }); @@ -44,6 +44,8 @@ top: -36px; min-height: -webkit-fill-available; transition: opacity 0.3s ease; + padding-bottom: 20px; + margin-bottom: -36px; .tab { padding: 0 10px; diff --git a/styles/less/hud/index.less b/styles/less/hud/index.less new file mode 100644 index 00000000..459f8fd7 --- /dev/null +++ b/styles/less/hud/index.less @@ -0,0 +1 @@ +@import './token-hud/token-hud.less'; diff --git a/styles/less/hud/token-hud/token-hud.less b/styles/less/hud/token-hud/token-hud.less new file mode 100644 index 00000000..7d231e8c --- /dev/null +++ b/styles/less/hud/token-hud/token-hud.less @@ -0,0 +1,10 @@ +.daggerheart.placeable-hud { + .col.right { + .palette { + .palette-category-title { + grid-column: span var(--effect-columns); + font-weight: bold; + } + } + } +} diff --git a/styles/less/sheets-settings/adversary-settings/experiences.less b/styles/less/sheets-settings/adversary-settings/experiences.less index 89a7c2d9..05595ed4 100644 --- a/styles/less/sheets-settings/adversary-settings/experiences.less +++ b/styles/less/sheets-settings/adversary-settings/experiences.less @@ -5,6 +5,7 @@ .tab.experiences { .add-experience-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/adversary-settings/features.less b/styles/less/sheets-settings/adversary-settings/features.less index 5798bfa9..037a08ea 100644 --- a/styles/less/sheets-settings/adversary-settings/features.less +++ b/styles/less/sheets-settings/adversary-settings/features.less @@ -10,6 +10,7 @@ .add-feature-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/environment-settings/adversaries.less b/styles/less/sheets-settings/environment-settings/adversaries.less index ba8cc8e4..8dc12c87 100644 --- a/styles/less/sheets-settings/environment-settings/adversaries.less +++ b/styles/less/sheets-settings/environment-settings/adversaries.less @@ -10,6 +10,7 @@ .add-action-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/environment-settings/features.less b/styles/less/sheets-settings/environment-settings/features.less index e4bb039f..f2a9583a 100644 --- a/styles/less/sheets-settings/environment-settings/features.less +++ b/styles/less/sheets-settings/environment-settings/features.less @@ -10,6 +10,7 @@ .add-feature-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less index 3e72b743..622480a7 100755 --- a/styles/less/utils/colors.less +++ b/styles/less/utils/colors.less @@ -25,10 +25,12 @@ @dark-blue-10: #18162e10; @dark-blue-40: #18162e40; @dark-blue-50: #18162e50; +@dark-blue-60: #18162e60; @semi-transparent-dark-blue: rgba(24, 22, 46, 0.33); @dark: #222; @dark-15: #22222215; +@dark-40: #22222240; @deep-black: #0e0d15; diff --git a/styles/less/ux/index.less b/styles/less/ux/index.less new file mode 100644 index 00000000..ff645288 --- /dev/null +++ b/styles/less/ux/index.less @@ -0,0 +1 @@ +@import './tooltip/tooltip.less'; diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less new file mode 100644 index 00000000..38502d09 --- /dev/null +++ b/styles/less/ux/tooltip/tooltip.less @@ -0,0 +1,106 @@ +.daggerheart.dh-style.tooltip { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + + .tooltip-title { + margin: 0; + text-align: center; + } + + .tooltip-image { + height: 180px; + width: 180px; + } + + .tooltip-description { + font-style: italic; + } + + .tooltip-sub-title { + margin: 0; + color: light-dark(@dark-blue, @beige); + } + + .tooltip-information-section { + width: 100%; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px; + + &.triple { + grid-template-columns: 1fr 1fr 1fr; + } + + &.border { + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + padding: 2px; + } + + .tooltip-information { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + + &.full-width { + grid-column: span 2; + } + + label { + font-weight: bold; + } + + label, + div { + white-space: nowrap; + } + } + } + + .tooltip-tags { + width: 100%; + display: flex; + flex-direction: column; + gap: 4px; + + .tooltip-tag { + width: 100%; + display: grid; + grid-template-columns: 80px 1fr; + align-items: start; + gap: 8px; + padding: 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + + .tooltip-tag-label-container { + display: flex; + align-items: center; + flex-direction: column; + gap: 2px; + + .tooltip-tag-image { + width: 40px; + height: 40px; + } + } + + .tooltip-tag-label { + font-weight: bold; + text-align: center; + } + + .tooltip-tag-description { + display: flex; + flex-wrap: wrap; + } + } + } + + .spaced { + margin-bottom: 4px; + } +} diff --git a/templates/actionTypes/actionType.hbs b/templates/actionTypes/actionType.hbs index fdffaabe..1cd912e9 100644 --- a/templates/actionTypes/actionType.hbs +++ b/templates/actionTypes/actionType.hbs @@ -1,13 +1,12 @@
-