diff --git a/daggerheart.d.ts b/daggerheart.d.ts index 1641faa8..891a3a2a 100644 --- a/daggerheart.d.ts +++ b/daggerheart.d.ts @@ -4,6 +4,15 @@ import '@common/primitives/global.mjs'; import Canvas from '@client/canvas/board.mjs'; import { ResourceUpdateMap } from './module/data/action/baseAction.mjs'; +import * as applications from './module/applications/_module.mjs'; +import * as data from './module/data/_module.mjs'; +import * as models from './module/data/_module.mjs'; +import * as documents from './module/documents/_module.mjs'; +import { macros } from './module/_module.mjs'; +import * as dice from './module/dice/_module.mjs'; +import * as fields from './module/data/fields/_module.mjs'; + + // Foundry's use of `Object.assign(globalThis) means many globally available objects are not read as such // This declare global hopefully fixes that // Note: eslint is not aware of these, whatever is added here should go in the eslint's globals list @@ -80,3 +89,17 @@ declare global { damageOptions: object; } } + +declare module '@client/packages/system.mjs' { + export default interface System { + api: { + applications: typeof applications, + data: typeof data, + models: typeof models, + documents: typeof documents, + macros: typeof macros, + dice: typeof dice, + fields: typeof fields + }; + } +} diff --git a/lang/en.json b/lang/en.json index 7d7c63d6..b9a81b29 100755 --- a/lang/en.json +++ b/lang/en.json @@ -114,7 +114,8 @@ "area": { "sectionTitle": "Areas", "shape": "Shape", - "size": "Size" + "size": "Size", + "hasHole": "Area Hole" }, "displayInChat": "Display in chat", "deleteTriggerTitle": "Delete Trigger", @@ -871,6 +872,10 @@ "bruiser": "for each Bruiser adversary.", "solo": "for each Solo adversary." }, + "AreaTypes": { + "attached": { "label": "Attached To Token" }, + "placed": { "label": "Placed In Scene" } + }, "ArmorInteraction": { "none": { "label": "Ignores Armor" }, "active": { "label": "Active w/ Armor" }, diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 85380392..bcfe3cbb 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -7,7 +7,7 @@ export default class AdversarySheet extends DHBaseActorSheet { /** @inheritDoc */ static DEFAULT_OPTIONS = { classes: ['adversary'], - position: { width: 660, height: 766 }, + position: { width: 645, height: 760 }, window: { resizable: true }, actions: { toggleHitPoints: AdversarySheet.#toggleHitPoints, @@ -58,12 +58,13 @@ export default class AdversarySheet extends DHBaseActorSheet { template: 'systems/daggerheart/templates/sheets/actors/adversary/features.hbs', scrollable: ['.feature-section'] }, - notes: { - template: 'systems/daggerheart/templates/sheets/actors/adversary/notes.hbs' - }, effects: { template: 'systems/daggerheart/templates/sheets/actors/adversary/effects.hbs', scrollable: ['.effects-sections'] + }, + notes: { + template: 'systems/daggerheart/templates/sheets/actors/adversary/notes.hbs', + scrollable: ['.editor-content'] } }; diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 3a60e7ca..5006e9d6 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -1057,7 +1057,7 @@ export default class CharacterSheet extends DHBaseActorSheet { direction: 'DOWN' }); - html.querySelectorAll('.armor-slot').forEach(element => { + html.querySelectorAll('.armor .slot').forEach(element => { element.addEventListener('click', CharacterSheet.armorSourcePipUpdate); }); } @@ -1072,7 +1072,7 @@ export default class CharacterSheet extends DHBaseActorSheet { /** Update specific armor source */ static async armorSourcePipUpdate(event) { - const target = event.target.closest('.armor-slot'); + const target = event.target.closest('.slot'); const { uuid, value } = target.dataset; const document = await foundry.utils.fromUuid(uuid); @@ -1100,7 +1100,7 @@ export default class CharacterSheet extends DHBaseActorSheet { } const container = target.closest('.slot-bar'); - for (const armorSlot of container.querySelectorAll('.armor-slot i')) { + for (const armorSlot of container.querySelectorAll('.armor .slot i')) { const index = Number.parseInt(armorSlot.dataset.index); if (decreasing && index >= newCurrent) { armorSlot.classList.remove('fa-shield'); diff --git a/module/canvas/placeables/regionLayer.mjs b/module/canvas/placeables/regionLayer.mjs index 684fdd5e..b71ccc3f 100644 --- a/module/canvas/placeables/regionLayer.mjs +++ b/module/canvas/placeables/regionLayer.mjs @@ -96,7 +96,7 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { return inBounds.length === 1 ? inBounds[0] : null; } - static getTemplateShape({ type, angle, range, direction } = {}) { + static getTemplateShape({ shapeType, angle, range, direction, hasHole } = {}) { const { line, rectangle, inFront, cone, circle, emanation } = CONFIG.DH.GENERAL.templateTypes; /* Length calculation */ @@ -112,11 +112,11 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { const shapeData = { ...canvas.mousePosition, - type: type, + type: shapeType, direction: direction ?? 0 }; - switch (type) { + switch (shapeType) { case rectangle.id: shapeData.width = length; shapeData.height = length; @@ -145,7 +145,8 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { y: 0, width: 1, height: 1, - shape: game.canvas.grid.isHexagonal ? CONST.TOKEN_SHAPES.ELLIPSE_1 : CONST.TOKEN_SHAPES.RECTANGLE_1 + shape: game.canvas.grid.isHexagonal ? CONST.TOKEN_SHAPES.ELLIPSE_1 : CONST.TOKEN_SHAPES.RECTANGLE_1, + hole: hasHole }; break; } diff --git a/module/config/actionConfig.mjs b/module/config/actionConfig.mjs index a6c04e18..e413a828 100644 --- a/module/config/actionConfig.mjs +++ b/module/config/actionConfig.mjs @@ -119,6 +119,10 @@ export const advantageState = { export const areaTypes = { placed: { id: 'placed', - label: 'Placed Area' + label: 'DAGGERHEART.CONFIG.AreaTypes.placed.label' + }, + attached: { + id: 'attached', + label: 'DAGGERHEART.CONFIG.AreaTypes.attached.label' } }; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 58be672b..be7224cd 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -114,7 +114,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel return this._id; } - /** Returns true if the current user is the owner of the containing item */ + /** + * Returns true if the current user is the owner of the containing item. + * @returns {boolean} + */ get isOwner() { return this.item?.isOwner ?? true; } @@ -143,6 +146,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel /** * Return the first Actor parent found. + * @returns {DhpActor | null} */ get actor() { return this.item instanceof DhpActor @@ -155,6 +159,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel /** * Returns true if the action is usable. * An action is usable on any actor type. For example, an adversary might have a base attack action. + * @returns {boolean} */ get usable() { const actor = this.actor; diff --git a/module/data/fields/action/areasField.mjs b/module/data/fields/action/areasField.mjs index 52110045..a4180101 100644 --- a/module/data/fields/action/areasField.mjs +++ b/module/data/fields/action/areasField.mjs @@ -33,6 +33,10 @@ export default class AreasField extends fields.ArrayField { initial: CONFIG.DH.GENERAL.range.veryClose.id, label: 'DAGGERHEART.ACTIONS.Config.area.size' }), + hasHole: new fields.BooleanField({ + initial: false, + label: 'DAGGERHEART.ACTIONS.Config.area.hasHole' + }), effects: new fields.ArrayField(new fields.DocumentIdField()) }); super(element, options, context); diff --git a/module/data/fields/action/transformField.mjs b/module/data/fields/action/transformField.mjs index 951eb0b4..9d3345af 100644 --- a/module/data/fields/action/transformField.mjs +++ b/module/data/fields/action/transformField.mjs @@ -2,6 +2,10 @@ import { getWorldActor } from '../../../helpers/utils.mjs'; const fields = foundry.data.fields; +/** + * @import DHSummonAction from '../../action/summonAction.mjs' + */ + export default class DHSummonField extends fields.SchemaField { /** * Action Workflow order @@ -22,6 +26,11 @@ export default class DHSummonField extends fields.SchemaField { super(transformFields, options, context); } + /** + * Runs the execute. This is run on behalf of DHSummonAction. + * @todo move this function to be on the summon action. + * @this DHSummonAction + */ static async execute() { if (!this.transform.actorUUID) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.noTransformActor')); @@ -39,10 +48,11 @@ export default class DHSummonField extends fields.SchemaField { return false; } - const activeTokens = this.actor.getActiveTokens().map(x => x.document); + const activeTokens = this.actor.getActiveTokens(false, true); const controlledMatchingTokens = canvas.tokens.controlled .filter(x => x.actor && x.actor.uuid === this.actor.uuid) .map(x => x.document); + /** @type {typeof game.system.api.documents.DhToken | null} */ const token = this.actor.token ?? ( activeTokens.length === 1 ? activeTokens[0] : (controlledMatchingTokens.length === 1 ? controlledMatchingTokens[0] : null) @@ -62,9 +72,10 @@ export default class DHSummonField extends fields.SchemaField { const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; const tokenSize = actor?.system.metadata.usesSize ? tokenSizes[actor.system.size] : actor.prototypeToken.width; - const createdTokens = await canvas.scene.createEmbeddedDocuments( + const prototypeTokenData = actor.prototypeToken.toObject(); + const createdToken = (await canvas.scene.createEmbeddedDocuments( 'Token', [{ - ...actor.prototypeToken.toObject(), + ...prototypeTokenData, actorId: actor.id, x: token.x, y: token.y, @@ -74,8 +85,7 @@ export default class DHSummonField extends fields.SchemaField { elevation: token.elevation }], { controlObject: true, parent: canvas.scene } - ); - const createdToken = createdTokens[0]; + ))[0]; /* Swap out previous combatant for a new one if applicable */ if (token.combatant) { diff --git a/module/documents/_types.d.ts b/module/documents/_types.d.ts index a94d6395..a3af1b33 100644 --- a/module/documents/_types.d.ts +++ b/module/documents/_types.d.ts @@ -3,17 +3,26 @@ import DHItem from './item.mjs'; import BaseDataItem from '../data/item/base.mjs'; import DhActiveEffect from './activeEffect.mjs'; import EmbeddedCollection from '@common/abstract/embedded-collection.mjs'; +import DHToken from './token.mjs'; +import Actor from '@client/documents/actor.mjs'; +import Item from '@client/documents/item.mjs'; declare module './actor.mjs' { - export default interface DhpActor { + export default interface DhpActor extends Actor { system: T; items: EmbeddedCollection; effects: EmbeddedCollection; + get token(): DHToken | null; + + /** @inheritdoc */ + getActiveTokens(linked?: boolean, document?: boolean): (DHToken | foundry.canvas.placeables.Token)[]; + getActiveTokens(linked?: boolean, document: true): DHToken[]; + getActiveTokens(linked?: boolean, document: false): foundry.canvas.placeables.Token[]; } } declare module './item.mjs' { - export default interface DHItem { + export default interface DHItem extends Item { parent: DhpActor; actor: DhpActor; system: T; diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index b555dfca..fd68997c 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -276,8 +276,12 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { async onCreateAreas(event) { const createArea = async selectedArea => { const effects = selectedArea.effects.map(effect => this.system.action.item.effects.get(effect).uuid); - const { shape: type, size: range } = selectedArea; - const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range }); + const { shape: shapeType, size: range, hasHole } = selectedArea; + const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ + shapeType, + range, + hasHole + }); const scene = game.scenes.get(game.user.viewedScene); const level = scene.levels.find(x => x.isView); @@ -305,7 +309,10 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { visibility: CONST.REGION_VISIBILITY.ALWAYS }; const placeRegion = data => { - canvas.regions.placeRegion(data, { create: true }); + canvas.regions.placeRegion(data, { + create: true, + attachToToken: selectedArea.type === CONFIG.DH.ACTIONS.areaTypes.attached.id + }); }; // Regions with effects must be placed by the GM diff --git a/module/enrichers/TemplateEnricher.mjs b/module/enrichers/TemplateEnricher.mjs index bbe93b17..4478ea14 100644 --- a/module/enrichers/TemplateEnricher.mjs +++ b/module/enrichers/TemplateEnricher.mjs @@ -58,10 +58,11 @@ export const renderMeasuredTemplate = async event => { if (!type || !range || !game.canvas.scene) return; const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ - type, + shapetype: type, angle, range, - direction + direction, + hasHole: false }); await canvas.regions.placeRegion( diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index cb79a76b..84bcacf2 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -1,6 +1,10 @@ import { diceTypes, getDiceSoNicePresets, getDiceSoNicePreset, range } from '../config/generalConfig.mjs'; import Tagify from '@yaireo/tagify'; +/** + * @import DhpActor from '../documents/actor.mjs'; + */ + export const capitalize = string => { return string.charAt(0).toUpperCase() + string.slice(1); }; @@ -891,15 +895,21 @@ export function shouldUseHopeFearAutomation(options = { gmAsPlayer: true }) { return (!game.user.isGM || options.gmAsPlayer) ? hopeFear.players : hopeFear.gm; } +/** + * Returns the given actor if its a world actor, + * finds a world actor equivalent, + * or imports the actor and returns the imported actor. + * @param {DhpActor} baseActor + * @returns {Promise} a world actor + */ export async function getWorldActor(baseActor) { if (baseActor.inCompendium) { - const worldActorCopy = game.actors.find(x => - x._stats.compendiumSource === baseActor.uuid && - (!x.prototypeToken.actorLink || x.name === baseActor.name) + const worldActorCandidates = game.actors.filter(x => + x._stats.compendiumSource === baseActor.uuid && + x.prototypeToken.actorLink === baseActor.prototypeToken.actorLink ); - - if (worldActorCopy) - return worldActorCopy; + const worldActorCopy = worldActorCandidates.find(a => a.name === baseActor.name) ?? worldActorCandidates[0]; + if (worldActorCopy) return worldActorCopy; const baseActorData = baseActor; return await game.system.api.documents.DhpActor.create({ diff --git a/src/packs/subclasses/feature_Elemental_Aura_2JH9NaOh69yN80Gw.json b/src/packs/subclasses/feature_Elemental_Aura_2JH9NaOh69yN80Gw.json index 7a3ebd91..e0476a56 100644 --- a/src/packs/subclasses/feature_Elemental_Aura_2JH9NaOh69yN80Gw.json +++ b/src/packs/subclasses/feature_Elemental_Aura_2JH9NaOh69yN80Gw.json @@ -52,7 +52,7 @@ "includeBase": false }, "target": { - "type": "hostile", + "type": "", "amount": 1 }, "effects": [ @@ -63,13 +63,23 @@ ], "name": "Fire", "img": "icons/magic/fire/barrier-wall-explosion-orange.webp", - "range": "close" + "range": "", + "areas": [ + { + "name": "Elemental Aura: Fire", + "type": "attached", + "shape": "emanation", + "size": "close", + "hasHole": false, + "effects": [] + } + ] }, "xDBLH5TWidvrYF7z": { "type": "effect", "_id": "xDBLH5TWidvrYF7z", "systemPath": "actions", - "description": "

When an adversary marks 1 or more Hit Points, they must also mark a Stress.

", + "description": "

Your allies gain a +1 bonus to Strength.

", "chatDisplay": true, "actionType": "action", "cost": [], @@ -78,19 +88,26 @@ "max": "", "recovery": null }, - "effects": [ - { - "_id": "WRuijfHxmUscAa69", - "onSave": false - } - ], + "effects": [], "target": { - "type": "friendly", + "type": "", "amount": null }, "name": "Earth", "img": "icons/magic/control/buff-strength-muscle-damage-red.webp", - "range": "close" + "range": "", + "areas": [ + { + "name": "Elemental Aura: Earth", + "type": "attached", + "shape": "emanation", + "size": "close", + "hasHole": true, + "effects": [ + "yvpWNCNobg0LLjey" + ] + } + ] }, "S4t5HlgxWlHwaBDw": { "type": "effect", @@ -112,12 +129,22 @@ } ], "target": { - "type": "hostile", + "type": "self", "amount": null }, "name": "Water", "img": "icons/magic/water/vortex-water-whirlpool.webp", - "range": "close" + "range": "self", + "areas": [ + { + "name": "Elemental Aura: Water", + "type": "attached", + "shape": "emanation", + "size": "close", + "hasHole": false, + "effects": [] + } + ] }, "hAsKFFewtTqd1gg9": { "type": "attack", @@ -138,15 +165,10 @@ "includeBase": false }, "target": { - "type": "any", + "type": "self", "amount": null }, - "effects": [ - { - "_id": "mJBA2QTyM9SM5NVS", - "onSave": false - } - ], + "effects": [], "roll": { "type": "diceSet", "trait": null, @@ -169,7 +191,19 @@ }, "name": "Air", "img": "icons/magic/air/air-burst-spiral-blue-gray.webp", - "range": "" + "range": "self", + "areas": [ + { + "name": "Elemental Aura: Air", + "type": "attached", + "shape": "emanation", + "size": "close", + "hasHole": false, + "effects": [ + "vnKV5hsO4DVjURAl" + ] + } + ] } }, "originItemType": null, @@ -181,49 +215,6 @@ } }, "effects": [ - { - "name": "Elemental Aura (Earth)", - "img": "icons/magic/control/buff-strength-muscle-damage-orange.webp", - "origin": "Compendium.daggerheart.subclasses.Item.2JH9NaOh69yN80Gw", - "transfer": false, - "_id": "WRuijfHxmUscAa69", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "changes": [ - { - "key": "system.traits.strength.value", - "mode": 2, - "value": "1", - "priority": null - } - ], - "disabled": false, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "", - "tint": "#ffffff", - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!items.effects!2JH9NaOh69yN80Gw.WRuijfHxmUscAa69" - }, { "name": "Elemental Aura (Water)", "img": "icons/magic/water/vortex-water-whirlpool.webp", @@ -237,18 +228,15 @@ "type": "withinRange", "target": "hostile", "range": "melee" - } + }, + "changes": [] }, - "changes": [], "disabled": false, "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null + "value": null, + "units": "seconds", + "expiry": null, + "expired": false }, "description": "", "tint": "#ffffff", @@ -258,6 +246,9 @@ "_stats": { "compendiumSource": null }, + "start": null, + "showIcon": 1, + "folder": null, "_key": "!items.effects!2JH9NaOh69yN80Gw.H7W52ps5d3UGmaFr" }, { @@ -273,18 +264,15 @@ "type": "withinRange", "target": "hostile", "range": "melee" - } + }, + "changes": [] }, - "changes": [], "disabled": false, "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null + "value": null, + "units": "seconds", + "expiry": null, + "expired": false }, "description": "", "tint": "#ffffff", @@ -294,43 +282,120 @@ "_stats": { "compendiumSource": null }, + "start": null, + "showIcon": 1, + "folder": null, "_key": "!items.effects!2JH9NaOh69yN80Gw.WX5AMEpmUAutB9Hm" }, { - "name": "Elemental Aura (Air)", - "img": "icons/magic/air/air-burst-spiral-blue-gray.webp", - "origin": "Compendium.daggerheart.subclasses.Item.2JH9NaOh69yN80Gw", + "name": "Elemental Aura: Earth", + "disabled": false, + "img": "icons/magic/control/buff-strength-muscle-damage-red.webp", + "description": "

Your allies gain a +1 bonus to Strength.

", "transfer": false, - "_id": "mJBA2QTyM9SM5NVS", - "type": "base", + "statuses": [], "system": { "rangeDependence": { "enabled": false, "type": "withinRange", "target": "hostile", "range": "melee" - } + }, + "changes": [ + { + "key": "system.traits.strength.value", + "type": "add", + "value": 1, + "priority": null, + "phase": "initial" + } + ], + "duration": { + "description": "", + "type": "" + }, + "stacking": null, + "targetDispositions": [ + 1 + ] }, - "changes": [], - "disabled": false, - "duration": { - "startTime": null, + "_id": "yvpWNCNobg0LLjey", + "type": "base", + "start": { + "time": 0, "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null + "combatant": null, + "initiative": null, + "round": null, + "turn": null }, - "description": "", + "duration": { + "value": null, + "units": "seconds", + "expiry": null, + "expired": false + }, + "origin": null, "tint": "#ffffff", - "statuses": [], + "showIcon": 1, + "folder": null, "sort": 0, "flags": {}, "_stats": { "compendiumSource": null }, - "_key": "!items.effects!2JH9NaOh69yN80Gw.mJBA2QTyM9SM5NVS" + "_key": "!items.effects!2JH9NaOh69yN80Gw.yvpWNCNobg0LLjey" + }, + { + "name": "Elemental Aura: Air", + "disabled": false, + "img": "icons/magic/air/air-burst-spiral-blue-gray.webp", + "description": "

When you or an ally takes damage from an attack beyond Melee range, reduce the damage by 1d8.

", + "transfer": false, + "statuses": [], + "system": { + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + }, + "changes": [], + "duration": { + "description": "", + "type": "" + }, + "stacking": null, + "targetDispositions": [ + 1 + ] + }, + "_id": "vnKV5hsO4DVjURAl", + "type": "base", + "start": { + "time": 0, + "combat": null, + "combatant": null, + "initiative": null, + "round": null, + "turn": null + }, + "duration": { + "value": null, + "units": "seconds", + "expiry": null, + "expired": false + }, + "origin": null, + "tint": "#ffffff", + "showIcon": 1, + "folder": null, + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null + }, + "_key": "!items.effects!2JH9NaOh69yN80Gw.vnKV5hsO4DVjURAl" } ], "sort": 100000, diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index e57ba50d..df12eda4 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -384,6 +384,10 @@ justify-content: space-between; } + label { + white-space: nowrap; + } + .btn { padding-top: 15px; } @@ -399,6 +403,13 @@ > .checkbox { align-self: end; } + + .auto-sized { + width: auto; + display: flex; + flex-direction: column; + align-items: center; + } } .form-group { diff --git a/styles/less/global/resource-bar.less b/styles/less/global/resource-bar.less index d06b43a8..3560285a 100644 --- a/styles/less/global/resource-bar.less +++ b/styles/less/global/resource-bar.less @@ -9,111 +9,108 @@ } }); +/** Pips styling, can exist standalone even without a slot-value */ +.slot-bar { + display: flex; + gap: 4px; + padding: 5px; + border: 1px solid @color-border; + border-radius: 6px; + z-index: 1; + color: @color-text-emphatic; + width: fit-content; + min-height: 22px; + flex-wrap: wrap; + + .slot { + transition: all 0.3s ease; + cursor: pointer; + } + + .slot:not(:has(i)) { + width: 15px; + height: 10px; + border: 1px solid @color-border; + background: light-dark(@dark-blue-10, @golden-10); + border-radius: 3px; + + &.large { + width: 20px; + } + + &.filled { + background: light-dark(@dark-blue, @golden); + } + } + + &.armor .slot { + font-size: var(--font-size-12); + .fa-shield-halved { + color: light-dark(@dark-blue-40, @golden-40); + } + } + + .empty-slot { + width: 15px; + height: 10px; + } +} + +.slot-value { + display: flex; + flex-direction: column; + font-size: 1.5rem; + align-items: center; + justify-content: center; + text-align: center; + z-index: 2; + color: @beige; + + .slot-label { + display: flex; + align-items: center; + color: light-dark(@beige, @dark-blue); + background: light-dark(@dark-blue, @golden); + padding: 0 5px; + width: fit-content; + font-weight: bold; + border-radius: 0px 0px 5px 5px; + font-size: var(--font-size-12); + + .label { + padding-right: 5px; + } + + .value { + padding-left: 6px; + border-left: 1px solid light-dark(@beige, @dark-golden); + } + } +} + .status-bar { display: flex; - justify-content: center; + flex-direction: column; + align-items: center; position: relative; - width: 120px; - height: 40px; - - .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(@beige, @dark-blue); - } - } - .slot-value { - position: absolute; - display: flex; - flex-direction: column; - padding: 0 5px; - font-size: 1.5rem; - align-items: center; - width: 140px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: @beige; - - .slot-bar { - display: flex; - flex-wrap: wrap; - gap: 5px; - padding: 5px; - border: 1px solid @color-border; - border-radius: 6px; - z-index: 1; - color: @color-text-emphatic; - width: fit-content; - - .slot { - width: 15px; - height: 10px; - border: 1px solid @color-border; - background: light-dark(@dark-blue-10, @golden-10); - border-radius: 3px; - transition: all 0.3s ease; - cursor: pointer; - - &.large { - width: 20px; - } - - &.filled { - background: light-dark(@dark-blue, @golden); - } - } - - .empty-slot { - width: 15px; - height: 10px; - } - } - .slot-label { - display: flex; - align-items: center; - color: light-dark(@beige, @dark-blue); - background: light-dark(@dark-blue, @golden); - padding: 0 5px; - width: fit-content; - font-weight: bold; - border-radius: 0px 0px 5px 5px; - font-size: var(--font-size-12); - - .label { - padding-right: 5px; - } - - .value { - padding-left: 6px; - border-left: 1px solid light-dark(@beige, @dark-golden); - } - } - } .status-value { - position: absolute; + position: relative; display: flex; padding: 0 5px; font-size: 1.5rem; align-items: center; - width: 140px; + width: 100px; height: 40px; justify-content: center; text-align: center; z-index: 2; color: @beige; + > * { + z-index: 1; + } + input[type='number'] { background: transparent; font-size: 1.5rem; @@ -146,11 +143,11 @@ .progress-bar { position: absolute; appearance: none; - width: 100px; - height: 40px; + width: 100%; + height: 100%; border: 1px solid @color-border; border-radius: 6px; - z-index: 1; + z-index: 0; background: @dark-blue; &::-webkit-progress-bar { @@ -175,4 +172,29 @@ border-radius: 6px; } } + .status-label { + position: relative; + height: 22px; + width: 79px; + background: light-dark(@dark-blue, @golden); + + &.pointy { + clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); + margin-bottom: -2px; // compensate for pointy bottom so spacing feels more "right" + } + + h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + color: light-dark(@beige, @dark-blue); + } + } } + +// Overrides for sidebar usage. +aside[data-application-part="sidebar"] .resources-section .slot-bar { + display: grid; + grid-template-columns: repeat(6, min-content); + grid-auto-flow: row; +} \ No newline at end of file diff --git a/styles/less/sheets/actors/adversary/index.less b/styles/less/sheets/actors/adversary/index.less index 28ff9d22..978cf1f8 100644 --- a/styles/less/sheets/actors/adversary/index.less +++ b/styles/less/sheets/actors/adversary/index.less @@ -1,7 +1,6 @@ +@import './sheet.less'; @import './features.less'; @import './header.less'; -@import './sheet.less'; @import './sidebar.less'; @import './effects.less'; @import './notes.less'; - diff --git a/styles/less/sheets/actors/adversary/sheet.less b/styles/less/sheets/actors/adversary/sheet.less index 0bd845fa..639af98b 100644 --- a/styles/less/sheets/actors/adversary/sheet.less +++ b/styles/less/sheets/actors/adversary/sheet.less @@ -2,35 +2,37 @@ @import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.adversary { + --sidebar-width: 260px; + .window-content { display: grid; - grid-template-columns: 275px 1fr; + grid-template-columns: var(--sidebar-width) 1fr; grid-template-rows: auto 1fr; height: 100%; width: 100%; padding-bottom: 0; + } - .adversary-sidebar-sheet { - grid-row: 1 / span 2; - grid-column: 1; + .adversary-sidebar-sheet { + grid-row: 1 / span 2; + grid-column: 1; + overflow: hidden; + display: flex; + flex-direction: column; + } + + .adversary-header-sheet { + grid-row: 1; + grid-column: 2; + } + + .tab { + grid-row: 2; + grid-column: 2; + &.active { overflow: hidden; display: flex; flex-direction: column; } - - .adversary-header-sheet { - grid-row: 1; - grid-column: 2; - } - - .tab { - grid-row: 2; - grid-column: 2; - &.active { - overflow: hidden; - display: flex; - flex-direction: column; - } - } } -} +} \ No newline at end of file diff --git a/styles/less/sheets/actors/adversary/sidebar.less b/styles/less/sheets/actors/adversary/sidebar.less index 5db9f5e9..8353d092 100644 --- a/styles/less/sheets/actors/adversary/sidebar.less +++ b/styles/less/sheets/actors/adversary/sidebar.less @@ -22,8 +22,8 @@ .application.sheet.daggerheart.actor.dh-style.adversary { .adversary-sidebar-sheet { - width: 275px; - min-width: 275px; + width: var(--sidebar-width); + min-width: var(--sidebar-width); border-right: 1px solid light-dark(@dark-blue, @golden); .portrait { @@ -52,7 +52,7 @@ } img { - height: 275px; + height: var(--sidebar-width); } .death-roll-btn { @@ -63,7 +63,7 @@ .threshold-section { position: relative; display: flex; - gap: 10px; + gap: 7px; background-color: light-dark(transparent, @dark-blue); color: @color-text-emphatic; padding: 5px 10px; @@ -106,8 +106,8 @@ display: flex; flex-direction: column; top: -20px; - gap: 16px; - margin-bottom: -10px; + gap: 10px; + margin-bottom: -16px; &.pip-display { top: -15px; @@ -120,105 +120,6 @@ .resources-section { display: flex; justify-content: space-evenly; - margin-bottom: 16px; - - .status-bar { - display: flex; - justify-content: center; - position: relative; - width: 100px; - height: 40px; - - .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(@beige, @dark-blue); - } - } - .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: @beige; - - input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: @beige; - - &.bar-input { - padding: 0; - color: @beige; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; - - &:hover, - &:focus { - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9.5px); - } - } - } - - .bar-label { - width: 40px; - } - } - .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid @color-border; - border-radius: 6px; - z-index: 1; - background: @dark-blue; - - &::-webkit-progress-bar { - border: none; - background: @dark-blue; - border-radius: 6px; - } - &::-webkit-progress-value { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-webkit-progress-value { - background: @gradient-stress; - border-radius: 6px; - } - &::-moz-progress-bar { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-moz-progress-bar { - background: @gradient-stress; - border-radius: 6px; - } - } - } } .status-section { @@ -256,7 +157,7 @@ .status-label { padding: 2px 10px; width: 100%; - border-radius: 3px; + border-radius: 0 0 3px 3px; background: light-dark(@dark-blue, @golden); h4 { @@ -284,8 +185,8 @@ .shortcut-items-section { overflow-y: hidden; - padding-top: 10px; - padding-bottom: 20px; + padding: 10px 0; + flex: 1; scrollbar-gutter: stable; .with-scroll-shadows(); @@ -313,8 +214,6 @@ } .experience-section { - margin-bottom: 20px; - .title { display: flex; gap: 15px; @@ -331,21 +230,21 @@ gap: 5px; width: 100%; margin-top: 10px; - align-items: center; + align-items: stretch; + padding: 0 4px 0 12px; .experience-row { display: flex; gap: 5px; - width: 250px; align-items: center; justify-content: space-between; .experience-name { - width: 180px; display: flex; align-items: center; text-align: start; font-size: var(--font-size-14); + flex: 1; color: light-dark(@dark, @beige); line-height: 1; } @@ -370,9 +269,7 @@ .reaction-section { display: flex; - padding: 0 10px; - margin-top: 20px; - width: 100%; + margin: 10px; button { height: 40px; diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index c76ee9ff..66f09cfc 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -89,113 +89,13 @@ .resources-section { justify-content: space-around; - margin: 8px 2px 8px 2px; + margin: 8px 2px 0 2px; } } .resources-section { display: flex; justify-content: space-evenly; - margin-bottom: 20px; - - .status-bar { - display: flex; - justify-content: center; - position: relative; - width: 120px; - height: 40px; - - .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(@beige, @dark-blue); - } - } - - .status-value { - position: absolute; - display: flex; - padding: 0 5px; - font-size: 1.5rem; - align-items: center; - width: 140px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: @beige; - - input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: @beige; - - &.bar-input { - padding: 0; - color: @beige; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; - - &:hover, - &:focus { - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9.5px); - } - } - } - - .bar-label { - width: 40px; - } - } - .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid @color-border; - border-radius: 6px; - z-index: 1; - background: @dark-blue; - - &::-webkit-progress-bar { - border: none; - background: @dark-blue; - border-radius: 6px; - } - &::-webkit-progress-value { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-webkit-progress-value { - background: @gradient-stress; - border-radius: 6px; - } - &::-moz-progress-bar { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-moz-progress-bar { - background: @gradient-stress; - border-radius: 6px; - } - } - } } .status-section { @@ -245,21 +145,21 @@ .status-bar.armor-slots { display: flex; - justify-content: center; - position: relative; width: 95px; - height: 30px; white-space: nowrap; + .status-label { + height: 30px; + } + .status-label { padding: 2px 2px; position: relative; - top: 30px; height: 22px; width: 95px; border-radius: 3px; background: light-dark(@dark-blue, @golden); - clip-path: none; + display: flex; align-items: center; justify-content: center; @@ -291,40 +191,16 @@ } } .slot-value { - position: absolute; - display: flex; - padding: 0 5px; font-size: 1.2rem; - align-items: center; width: 80px; height: 30px; - justify-content: center; - text-align: center; - z-index: 2; color: light-dark(@dark-blue, @beige); flex-direction: column; .slot-bar { - display: flex; - flex-wrap: wrap; - gap: 4px; - padding: 5px; - border: 1px solid @color-border; - border-radius: 6px; - z-index: 1; background: @dark-blue; justify-content: center; - color: @color-text-emphatic; - - .armor-slot { - cursor: pointer; - transition: all 0.3s ease; - font-size: var(--font-size-12); - - .fa-shield-halved { - color: light-dark(@dark-blue-40, @golden-40); - } - } + border-bottom: none; } .slot-label { display: flex; @@ -364,41 +240,21 @@ } } .status-value { - position: absolute; - display: flex; padding: 0 6px; font-size: 1.2rem; - align-items: center; width: 80px; height: 30px; justify-content: center; - text-align: center; - z-index: 2; color: light-dark(@dark-blue, @beige); - border: 1px solid @color-border; - border-bottom: none; - border-radius: 6px 6px 0 0; input[type='number'] { - background: transparent; font-size: 1.2rem; width: 30px; height: 20px; - text-align: center; - border: none; - outline: 2px solid transparent; color: light-dark(@dark-blue, @beige); &.bar-input { - padding: 0; color: light-dark(@dark-blue, @beige); - backdrop-filter: none; - background: transparent; - &:hover, - &:focus { - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9.5px); - } } } @@ -407,32 +263,9 @@ } } .progress-bar { - position: absolute; - appearance: none; - width: 80px; - height: 30px; - border: 1px solid @color-border; - border-radius: 6px; - z-index: 1; background: light-dark(transparent, @dark-blue); border-bottom: none; border-radius: 6px 6px 0 0; - &::-webkit-progress-bar { - border: none; - background: light-dark(transparent, @dark-blue); - } - &::-webkit-progress-value { - background: @gradient-stress; - } - &.stress-color::-webkit-progress-value { - background: @gradient-stress; - } - &::-moz-progress-bar { - background: @gradient-stress; - } - &.stress-color::-moz-progress-bar { - background: @gradient-stress; - } } } diff --git a/styles/less/sheets/actors/party/party-members.less b/styles/less/sheets/actors/party/party-members.less index dc464291..2490757f 100644 --- a/styles/less/sheets/actors/party/party-members.less +++ b/styles/less/sheets/actors/party/party-members.less @@ -1,295 +1,265 @@ -@import '../../../utils/colors.less'; -@import '../../../utils/fonts.less'; -@import '../../../utils/mixin.less'; - -.application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers { - overflow: auto; - - .actors-list { - display: flex; - flex-direction: column; - gap: 8px; - align-items: stretch; - width: 100%; - - .actor-resources { - display: grid; - grid-template: - "img header" min-content - "img body" 1fr - / 7.5rem 1fr; - gap: 6px; - column-gap: 12px; - padding: 6px; - background-color: light-dark(@dark-blue-10, @golden-10); - - .actor-img-frame { - grid-area: img; - width: 7.375rem; - height: 7.375rem; - position: relative; - - .actor-img { - object-fit: cover; - object-position: top center; - border-radius: 6px; - width: 100%; - height: 100%; - } - - .equipped-weapons { - position: absolute; - top: -2px; - left: -3px; - display: flex; - flex-direction: column; - gap: 1px; - img { - border-radius: 50%; - width: 24px; - height: 24px; - border: 1px solid @color-border; - object-fit: cover; - } - } - - .evasion { - position: absolute; - top: 1px; - right: 1px; - width: 1.75rem; - height: 1.75rem; - background: url('../assets/svg/trait-shield.svg') no-repeat; - background-size: 100%; - color: var(--color-light-1); - font-size: var(--font-size-14); - font-weight: 700; - display: flex; - align-items: center; - justify-content: center; - } - - .threshold-section { - position: absolute; - left: 0; - right: 0; - bottom: -2px; - margin: auto; - - display: flex; - gap: 4px; - background-color: light-dark(var(--color-light-1), @dark-blue); - color: @color-text-emphatic; - padding: 4px 6px; - border: 1px solid @color-border; - border-radius: 3px; - align-items: baseline; - width: fit-content; - - h4 { - font-weight: bold; - text-transform: uppercase; - white-space: nowrap; - - &.threshold-label { - font-size: var(--font-size-10); - color: @color-text-emphatic; - } - - &.threshold-value { - font-size: var(--font-size-11); - color: light-dark(@dark, @beige); - } - } - } - } - - header { - grid-area: header; - display: grid; - grid-template: - "name hope" min-content - "subtitle subtitle" min-content - / 1fr min-content; - - .actor-name { - width: 100%; - z-index: 1; - font-size: var(--font-size-20); - color: @color-text-emphatic; - font-weight: bold; - } - - .delete-icon { - font-size: 0.75em; - } - - .subtitle { - grid-area: subtitle; - font-size: var(--font-size-14); - } - - .hope-section { - display: flex; - background-color: light-dark(transparent, @dark-blue); - color: @color-text-emphatic; - padding: 3px 6px; - border: 1px solid @color-border; - border-radius: 3px; - align-items: center; - width: fit-content; - margin-left: auto; - - h4 { - font-size: var(--font-size-12); - font-weight: bold; - text-transform: uppercase; - color: @color-text-emphatic; - margin-right: 3px; - } - - .hope-value { - display: flex; - cursor: pointer; - font-size: var(--font-size-12); - margin-left: 1px; - } - } - } - - .body { - grid-area: body; - display: flex; - align-items: start; - justify-content: space-between; - } - - .resources { - display: flex; - flex-direction: column; - gap: 4px; - - .slot-section { - display: flex; - flex-direction: row; - align-items: stretch; - - .slot-label { - display: flex; - align-items: center; - color: light-dark(@beige, @dark-blue); - background: light-dark(@dark-blue, @golden); - padding: 0 4px; - width: fit-content; - font-weight: bold; - border-radius: 6px 0px 0px 6px; - font-size: var(--font-size-12); - white-space: nowrap; - - .label { - padding-right: 2px; - } - - .value { - font-variant-numeric: tabular-nums; - .current { - display: inline-block; - text-align: end; - width: 2ch; - } - .max { - display: inline-block; - text-align: start; - width: 2ch; - } - } - } - - .slot-bar { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 4px; - - background-color: light-dark(@dark-blue-10, @dark-blue); - color: @color-text-emphatic; - padding: 2px 5px; - border: 1px solid @color-border; - border-radius: 0 6px 6px 0; - width: fit-content; - min-height: 22px; - - .armor-slot { - cursor: pointer; - transition: all 0.3s ease; - font-size: var(--font-size-12); - - .fa-shield-halved { - color: light-dark(@dark-blue-40, @golden-40); - } - } - - .slot { - width: 16px; - height: 10px; - border: 1px solid @color-border; - background: light-dark(@dark-blue-10, @golden-10); - border-radius: 3px; - transition: all 0.3s ease; - cursor: pointer; - - &.filled { - background: light-dark(@dark-blue, @golden); - } - } - } - } - } - - .traits { - background-color: light-dark(@dark-blue-10, @dark-blue); - border: 1px solid @color-border; - border-radius: 6px; - display: grid; - grid-template-columns: 1fr 1fr; - font-size: var(--font-size-12); - padding: 3px 4px; - gap: 3px 7px; - .trait { - display: flex; - justify-content: space-between; - gap: 3px; - .label { - color: @color-text-emphatic; - } - .value { - font-weight: 600; - } - } - } - } - } - - .actors-list.limited { - .actor-resources { - display: flex; - align-items: center; - } - .actor-img-frame { - width: 3rem; - height: 3rem; - } - } - - .actors-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - border: 1px dashed light-dark(@dark-blue-50, @beige-50); - border-radius: 3px; - color: light-dark(@dark-blue-50, @beige-50); - } -} +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; + +.application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers { + overflow: auto; + + .actors-list { + display: flex; + flex-direction: column; + gap: 8px; + align-items: stretch; + width: 100%; + + .actor-resources { + display: grid; + grid-template: + "img header" min-content + "img body" 1fr + / 7.5rem 1fr; + gap: 6px; + column-gap: 12px; + padding: 6px; + background-color: light-dark(@dark-blue-10, @golden-10); + + .actor-img-frame { + grid-area: img; + width: 7.375rem; + height: 7.375rem; + position: relative; + + .actor-img { + object-fit: cover; + object-position: top center; + border-radius: 6px; + width: 100%; + height: 100%; + } + + .equipped-weapons { + position: absolute; + top: -2px; + left: -3px; + display: flex; + flex-direction: column; + gap: 1px; + img { + border-radius: 50%; + width: 24px; + height: 24px; + border: 1px solid @color-border; + object-fit: cover; + } + } + + .evasion { + position: absolute; + top: 1px; + right: 1px; + width: 1.75rem; + height: 1.75rem; + background: url('../assets/svg/trait-shield.svg') no-repeat; + background-size: 100%; + color: var(--color-light-1); + font-size: var(--font-size-14); + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + } + + .threshold-section { + position: absolute; + left: 0; + right: 0; + bottom: -2px; + margin: auto; + + display: flex; + gap: 4px; + background-color: light-dark(var(--color-light-1), @dark-blue); + color: @color-text-emphatic; + padding: 4px 6px; + border: 1px solid @color-border; + border-radius: 3px; + align-items: baseline; + width: fit-content; + + h4 { + font-weight: bold; + text-transform: uppercase; + white-space: nowrap; + + &.threshold-label { + font-size: var(--font-size-10); + color: @color-text-emphatic; + } + + &.threshold-value { + font-size: var(--font-size-11); + color: light-dark(@dark, @beige); + } + } + } + } + + header { + grid-area: header; + display: grid; + grid-template: + "name hope" min-content + "subtitle subtitle" min-content + / 1fr min-content; + + .actor-name { + width: 100%; + z-index: 1; + font-size: var(--font-size-20); + color: @color-text-emphatic; + font-weight: bold; + } + + .delete-icon { + font-size: 0.75em; + } + + .subtitle { + grid-area: subtitle; + font-size: var(--font-size-14); + } + + .hope-section { + display: flex; + background-color: light-dark(transparent, @dark-blue); + color: @color-text-emphatic; + padding: 3px 6px; + border: 1px solid @color-border; + border-radius: 3px; + align-items: center; + width: fit-content; + margin-left: auto; + + h4 { + font-size: var(--font-size-12); + font-weight: bold; + text-transform: uppercase; + color: @color-text-emphatic; + margin-right: 3px; + } + + .hope-value { + display: flex; + cursor: pointer; + font-size: var(--font-size-12); + margin-left: 1px; + } + } + } + + .body { + grid-area: body; + display: flex; + align-items: start; + justify-content: space-between; + } + + .resources { + display: flex; + flex-direction: column; + gap: 4px; + + .slot-section { + display: flex; + flex-direction: row; + align-items: stretch; + + .slot-label { + display: flex; + align-items: center; + color: light-dark(@beige, @dark-blue); + background: light-dark(@dark-blue, @golden); + padding: 0 4px; + width: fit-content; + font-weight: bold; + border-radius: 6px 0px 0px 6px; + font-size: var(--font-size-12); + white-space: nowrap; + + .label { + padding-right: 2px; + } + + .value { + font-variant-numeric: tabular-nums; + .current { + display: inline-block; + text-align: end; + width: 2ch; + } + .max { + display: inline-block; + text-align: start; + width: 2ch; + } + } + } + + .slot-bar { + align-items: center; + flex-wrap: wrap; + background-color: light-dark(@dark-blue-10, @dark-blue); + padding: 2px 5px; + border-radius: 0 6px 6px 0; + width: fit-content; + } + } + } + + .traits { + background-color: light-dark(@dark-blue-10, @dark-blue); + border: 1px solid @color-border; + border-radius: 6px; + display: grid; + grid-template-columns: 1fr 1fr; + font-size: var(--font-size-12); + padding: 3px 4px; + gap: 3px 7px; + .trait { + display: flex; + justify-content: space-between; + gap: 3px; + .label { + color: @color-text-emphatic; + } + .value { + font-weight: 600; + } + } + } + } + } + + .actors-list.limited { + .actor-resources { + display: flex; + align-items: center; + } + .actor-img-frame { + width: 3rem; + height: 3rem; + } + } + + .actors-dragger { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + border: 1px dashed light-dark(@dark-blue-50, @beige-50); + border-radius: 3px; + color: light-dark(@dark-blue-50, @beige-50); + } +} diff --git a/templates/actionTypes/areas.hbs b/templates/actionTypes/areas.hbs index 2e010c72..662716f5 100644 --- a/templates/actionTypes/areas.hbs +++ b/templates/actionTypes/areas.hbs @@ -11,9 +11,10 @@
- {{formField ../fields.type value=area.type name=(concat "areas." index ".type") localize=true}} - {{formField ../fields.shape value=area.shape name=(concat "areas." index ".shape") localize=true}} - {{formField ../fields.size value=area.size name=(concat "areas." index ".size") localize=true}} + {{formField ../fields.type value=area.type name=(concat "areas." index ".type") localize=true blank=false}} + {{formField ../fields.shape value=area.shape name=(concat "areas." index ".shape") localize=true blank=false}} + {{formField ../fields.size value=area.size name=(concat "areas." index ".size") localize=true blank=false}} + {{formField ../fields.hasHole value=area.hasHole name=(concat "areas." index ".hasHole") localize=true classes="auto-sized" }}
diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index d2fca5f1..213c96ee 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -1,100 +1,102 @@ -