diff --git a/lang/en.json b/lang/en.json
index c46f0f21..c2e72a18 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -1801,6 +1801,7 @@
"plural": "Costs"
},
"Damage": {
+ "massive": "Massive",
"severe": "Severe",
"major": "Major",
"minor": "Minor",
@@ -2442,9 +2443,12 @@
},
"currency": {
"title": "Currency Overrides",
+ "changeIcon": "Change Currency Icon",
"currencyName": "Currency Name",
"coinName": "Coin Name",
"handfulName": "Handful Name",
+ "iconName": "Icon Name",
+ "iconNameHint": "Icons are from fontawesome",
"bagName": "Bag Name",
"chestName": "Chest Name"
},
@@ -2506,6 +2510,11 @@
"hint": "Apply variant rules from the Daggerheart system",
"name": "Variant Rules",
"actionTokens": "Action Tokens"
+ },
+ "SpotlightRequestQueue": {
+ "name": "Spotlight Request Queue",
+ "label": "Spotlight Request Queue",
+ "hint": "Adds more structure to spotlight requests by ordering them from oldest to newest"
}
},
"Resources": {
@@ -2519,6 +2528,10 @@
"actionTokens": {
"enabled": { "label": "Enabled" },
"tokens": { "label": "Tokens" }
+ },
+ "massiveDamage":{
+ "title":"Massive Damage",
+ "enabled": { "label": "Enabled" }
}
}
},
diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs
index 8e566106..6d36a2b3 100644
--- a/module/applications/settings/homebrewSettings.mjs
+++ b/module/applications/settings/homebrewSettings.mjs
@@ -32,6 +32,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
icon: 'fa-solid fa-gears'
},
actions: {
+ editCurrencyIcon: this.changeCurrencyIcon,
addItem: this.addItem,
editItem: this.editItem,
removeItem: this.removeItem,
@@ -115,6 +116,45 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
this.render();
}
+ static async changeCurrencyIcon(_, target) {
+ const type = target.dataset.currency;
+ const currentIcon = this.settings.currency[type].icon;
+ const icon = await foundry.applications.api.DialogV2.input({
+ classes: ['daggerheart', 'dh-style', 'change-currency-icon'],
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/settings/homebrew-settings/change-currency-icon.hbs',
+ { currentIcon }
+ ),
+ window: {
+ title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon'),
+ icon: 'fa-solid fa-coins'
+ },
+ render: (_, dialog) => {
+ const icon = dialog.element.querySelector('.displayed-icon i');
+ const input = dialog.element.querySelector('input');
+ const reset = dialog.element.querySelector('button[data-action=reset]');
+ input.addEventListener('input', () => {
+ icon.classList.value = input.value;
+ });
+ reset.addEventListener('click', () => {
+ const currencyField = DhHomebrew.schema.fields.currency.fields[type];
+ const initial = currencyField.fields.icon.getInitialValue();
+ input.value = icon.classList.value = initial;
+ });
+ },
+ ok: {
+ callback: (_, button) => button.form.elements.icon.value
+ }
+ });
+
+ if (icon !== null) {
+ await this.settings.updateSource({
+ [`currency.${type}.icon`]: icon
+ });
+ this.render();
+ }
+ }
+
static async addItem(_, target) {
const { type } = target.dataset;
if (['shortRest', 'longRest'].includes(type)) {
diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs
index ee356bfd..91f6cfa7 100644
--- a/module/applications/sheets/actors/character.mjs
+++ b/module/applications/sheets/actors/character.mjs
@@ -685,8 +685,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
ability: abilityLabel
})
});
-
- if (result) game.system.api.fields.ActionFields.CostField.execute.call(this, result);
}
//TODO: redo toggleEquipItem method
diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs
index 449d6723..619305f1 100644
--- a/module/applications/sheets/api/application-mixin.mjs
+++ b/module/applications/sheets/api/application-mixin.mjs
@@ -178,6 +178,80 @@ export default function DHApplicationMixin(Base) {
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
this._dragDrop.forEach(d => d.bind(htmlElement));
+
+ // Handle delta inputs
+ for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) {
+ deltaInput.dataset.numValue = deltaInput.value;
+ deltaInput.inputMode = 'numeric';
+ deltaInput.pattern = '^[+=\\-]?\d*';
+
+ const handleUpdate = (delta = 0) => {
+ const min = Number(deltaInput.min) || 0;
+ const max = Number(deltaInput.max) || Infinity;
+ const current = Number(deltaInput.dataset.numValue);
+ const rawNumber = Number(deltaInput.value);
+ if (Number.isNaN(rawNumber)) {
+ deltaInput.value = delta ? Math.clamp(current + delta, min, max) : current;
+ return;
+ }
+
+ const newValue =
+ deltaInput.value.startsWith('+') || deltaInput.value.startsWith('-')
+ ? Math.clamp(current + rawNumber + delta, min, max)
+ : Math.clamp(rawNumber + delta, min, max);
+ deltaInput.value = deltaInput.dataset.numValue = newValue;
+ };
+
+ // Force valid characters while inputting
+ deltaInput.addEventListener('input', () => {
+ deltaInput.value = /[+=\-]?\d*/.exec(deltaInput.value)?.at(0) ?? deltaInput.value;
+ });
+
+ // Recreate Keyup/Keydown support
+ deltaInput.addEventListener('keydown', event => {
+ const step = event.key === 'ArrowUp' ? 1 : event.key === 'ArrowDown' ? -1 : 0;
+ if (step !== 0) {
+ handleUpdate(step);
+ deltaInput.dispatchEvent(new Event("change", { bubbles: true }));
+ }
+ });
+
+ // Mousewheel while focused support
+ deltaInput.addEventListener(
+ 'wheel',
+ event => {
+ if (deltaInput === document.activeElement) {
+ event.preventDefault();
+ handleUpdate(Math.sign(-1 * event.deltaY));
+ deltaInput.dispatchEvent(new Event("change", { bubbles: true }));
+ }
+ },
+ { passive: false }
+ );
+
+ deltaInput.addEventListener('change', () => {
+ handleUpdate();
+ });
+ }
+
+ // Handle contenteditable
+ for (const input of htmlElement.querySelectorAll('[contenteditable][data-property]')) {
+ const property = input.dataset.property;
+ input.addEventListener("blur", () => {
+ const selection = document.getSelection();
+ if (input.contains(selection.anchorNode)) {
+ selection.empty();
+ }
+ this.document.update({ [property]: input.textContent });
+ });
+
+ input.addEventListener("keydown", event => {
+ if (event.key === "Enter") input.blur();
+ });
+
+ // Chrome sometimes add
, which aren't a problem for the value but are for the placeholder
+ input.addEventListener("input", () => input.querySelectorAll("br").forEach((i) => i.remove()));
+ }
}
/**@inheritdoc */
diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs
index 871ff173..47dfe500 100644
--- a/module/applications/ui/chatLog.mjs
+++ b/module/applications/ui/chatLog.mjs
@@ -245,7 +245,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
});
if (!result) return;
- await game.system.api.fields.ActionFields.CostField.execute.call({ actor }, result);
const newMessageData = foundry.utils.deepClone(message.system);
foundry.utils.setProperty(newMessageData, `${path}.result`, result.roll);
diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs
index 23bede60..babc4a65 100644
--- a/module/applications/ui/combatTracker.mjs
+++ b/module/applications/ui/combatTracker.mjs
@@ -5,8 +5,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
actions: {
requestSpotlight: this.requestSpotlight,
toggleSpotlight: this.toggleSpotlight,
- setActionTokens: this.setActionTokens,
- openCountdowns: this.openCountdowns
+ setActionTokens: this.setActionTokens
}
};
@@ -57,21 +56,26 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
const adversaries = context.turns?.filter(x => x.isNPC) ?? [];
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
+ const spotlightQueueEnabled = game.settings.get(
+ CONFIG.DH.id,
+ CONFIG.DH.SETTINGS.gameSettings.SpotlightRequestQueue
+ );
const spotlightRequests = characters
- ?.filter(x => !x.isNPC)
+ ?.filter(x => !x.isNPC && spotlightQueueEnabled)
.filter(x => x.system.spotlight.requestOrderIndex > 0)
.sort((a, b) => {
const valueA = a.system.spotlight.requestOrderIndex;
const valueB = b.system.spotlight.requestOrderIndex;
-
return valueA - valueB;
});
Object.assign(context, {
actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens,
adversaries,
- characters: characters?.filter(x => !x.isNPC).filter(x => x.system.spotlight.requestOrderIndex == 0),
+ characters: characters
+ ?.filter(x => !x.isNPC)
+ .filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0),
spotlightRequests
});
}
@@ -161,9 +165,13 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
if (this.viewed.turn !== toggleTurn) {
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
- await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id);
if (combatant.actor.type === 'character') {
- await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.characterSpotlight.id);
+ await updateCountdowns(
+ CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id,
+ CONFIG.DH.GENERAL.countdownProgressionTypes.characterSpotlight.id
+ );
+ } else {
+ await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id);
}
const autoPoints = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).actionPoints;
diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs
index 96315b17..42920a4a 100644
--- a/module/applications/ui/countdowns.mjs
+++ b/module/applications/ui/countdowns.mjs
@@ -245,14 +245,20 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
return super.close(options);
}
- static async updateCountdowns(progressType) {
+ /**
+ * Sends updates of the countdowns to the GM player. Since this is asynchronous, be sure to
+ * update all the countdowns at the same time.
+ *
+ * @param {...any} progressTypes Countdowns to be updated
+ */
+ static async updateCountdowns(...progressTypes) {
const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
if (!countdownAutomation) return;
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => {
const countdown = countdownSetting.countdowns[key];
- if (countdown.progress.type === progressType && countdown.progress.current > 0) {
+ if (progressTypes.indexOf(countdown.progress.type) !== -1 && countdown.progress.current > 0) {
acc.push(key);
}
@@ -260,7 +266,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
}, []);
const countdownData = countdownSetting.toObject();
- await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, {
+ const settings = {
...countdownData,
countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => {
const countdown = foundry.utils.deepClone(countdownData.countdowns[key]);
@@ -271,14 +277,12 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
acc[key] = countdown;
return acc;
}, {})
+ };
+ await emitAsGM(GMUpdateEvent.UpdateCountdowns,
+ DhCountdowns.gmSetSetting.bind(settings),
+ settings, null, {
+ refreshType: RefreshType.Countdown
});
-
- const data = { refreshType: RefreshType.Countdown };
- await game.socket.emit(`system.${CONFIG.DH.id}`, {
- action: socketEvent.Refresh,
- data
- });
- Hooks.callAll(socketEvent.Refresh, data);
}
async _onRender(context, options) {
diff --git a/module/applications/ui/effectsDisplay.mjs b/module/applications/ui/effectsDisplay.mjs
index 7f90e30b..0875e783 100644
--- a/module/applications/ui/effectsDisplay.mjs
+++ b/module/applications/ui/effectsDisplay.mjs
@@ -87,7 +87,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
async removeEffect(event) {
const element = event.target.closest('.effect-container');
const effects = DhEffectsDisplay.getTokenEffects();
- const effect = effects.find(x => x.id === element.id);
+ const effect = effects.find(x => x.id === element.dataset.effectId);
await effect.delete();
this.render();
}
diff --git a/module/config/encounterConfig.mjs b/module/config/encounterConfig.mjs
index 0269b5c1..7565652f 100644
--- a/module/config/encounterConfig.mjs
+++ b/module/config/encounterConfig.mjs
@@ -84,6 +84,7 @@ export const BPModifiers = {
increaseDamage: {
sort: 2,
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.description',
+ effectTargetTypes: ['adversary'],
effects: [
{
name: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.effect.name',
diff --git a/module/config/settingsConfig.mjs b/module/config/settingsConfig.mjs
index aea9bc48..3d993949 100644
--- a/module/config/settingsConfig.mjs
+++ b/module/config/settingsConfig.mjs
@@ -28,7 +28,8 @@ export const gameSettings = {
LevelTiers: 'LevelTiers',
Countdowns: 'Countdowns',
LastMigrationVersion: 'LastMigrationVersion',
- TagTeamRoll: 'TagTeamRoll'
+ TagTeamRoll: 'TagTeamRoll',
+ SpotlightRequestQueue: 'SpotlightRequestQueue',
};
export const actionAutomationChoices = {
diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs
index 93de0a2d..ae085064 100644
--- a/module/data/action/baseAction.mjs
+++ b/module/data/action/baseAction.mjs
@@ -193,8 +193,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
async use(event) {
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
- if (this.chatDisplay) await this.toChat();
-
let config = this.prepareConfig(event);
if (!config) return;
@@ -211,6 +209,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
+ if (this.chatDisplay) await this.toChat();
+
return config;
}
diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs
index ead3c962..6f280cbd 100644
--- a/module/data/settings/Homebrew.mjs
+++ b/module/data/settings/Homebrew.mjs
@@ -1,14 +1,15 @@
import { defaultRestOptions } from '../../config/generalConfig.mjs';
import { ActionsField } from '../fields/actionField.mjs';
-const currencyField = (initial, label) =>
+const currencyField = (initial, label, icon) =>
new foundry.data.fields.SchemaField({
enabled: new foundry.data.fields.BooleanField({ required: true, initial: true }),
label: new foundry.data.fields.StringField({
required: true,
initial,
label
- })
+ }),
+ icon: new foundry.data.fields.StringField({ required: true, nullable: false, blank: true, initial: icon })
});
export default class DhHomebrew extends foundry.abstract.DataModel {
@@ -45,10 +46,22 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
initial: 'Gold',
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.currencyName'
}),
- coins: currencyField('Coins', 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName'),
- handfuls: currencyField('Handfuls', 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName'),
- bags: currencyField('Bags', 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName'),
- chests: currencyField('Chests', 'DAGGERHEART.SETTINGS.Homebrew.currency.chestName')
+ coins: currencyField(
+ 'Coins',
+ 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName',
+ 'fa-solid fa-coin-front'
+ ),
+ handfuls: currencyField(
+ 'Handfuls',
+ 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName',
+ 'fa-solid fa-coins'
+ ),
+ bags: currencyField('Bags', 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName', 'fa-solid fa-sack'),
+ chests: currencyField(
+ 'Chests',
+ 'DAGGERHEART.SETTINGS.Homebrew.currency.chestName',
+ 'fa-solid fa-treasure-chest'
+ )
}),
restMoves: new fields.SchemaField({
longRest: new fields.SchemaField({
@@ -139,22 +152,10 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
/** @inheritDoc */
_initializeSource(source, options = {}) {
source = super._initializeSource(source, options);
- source.currency.coins = {
- enabled: source.currency.coins.enabled ?? true,
- label: source.currency.coins.label || source.currency.coins
- };
- source.currency.handfuls = {
- enabled: source.currency.handfuls.enabled ?? true,
- label: source.currency.handfuls.label || source.currency.handfuls
- };
- source.currency.bags = {
- enabled: source.currency.bags.enabled ?? true,
- label: source.currency.bags.label || source.currency.bags
- };
- source.currency.chests = {
- enabled: source.currency.chests.enabled ?? true,
- label: source.currency.chests.label || source.currency.chests
- };
+ for (const type of ['coins', 'handfuls', 'bags', 'chests']) {
+ const initial = this.schema.fields.currency.fields[type].getInitialValue();
+ source.currency[type] = foundry.utils.mergeObject(initial, source.currency[type], { inplace: false });
+ }
return source;
}
}
diff --git a/module/data/settings/VariantRules.mjs b/module/data/settings/VariantRules.mjs
index ad7d707a..41c63be2 100644
--- a/module/data/settings/VariantRules.mjs
+++ b/module/data/settings/VariantRules.mjs
@@ -39,6 +39,13 @@ export default class DhVariantRules extends foundry.abstract.DataModel {
label: 'DAGGERHEART.CONFIG.Range.close.name'
}),
far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.CONFIG.Range.far.name' })
+ }),
+ massiveDamage: new fields.SchemaField({
+ enabled: new fields.BooleanField({
+ required: true,
+ initial: false,
+ label: 'DAGGERHEART.SETTINGS.VariantRules.FIELDS.massiveDamage.enabled.label'
+ })
})
};
}
diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs
index e6856dab..ce39ed6a 100644
--- a/module/dice/dhRoll.mjs
+++ b/module/dice/dhRoll.mjs
@@ -237,6 +237,51 @@ export default class DHRoll extends Roll {
}
}
+async function automateHopeFear(config) {
+ const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
+ const hopeFearAutomation = automationSettings.hopeFear;
+ if (!config.source?.actor ||
+ (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
+ config.actionType === 'reaction' ||
+ config.tagTeamSelected ||
+ config.skips?.resources)
+ return;
+ const actor = await fromUuid(config.source.actor);
+ let updates = [];
+ if (!actor) return;
+
+ if (config.rerolledRoll) {
+ if (config.roll.result.duality != config.rerolledRoll.result.duality) {
+ const hope = (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0)
+ - (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0);
+ const stress = (config.roll.isCritical ? 1 : 0) - (config.rerolledRoll.isCritical ? 1 : 0);
+ const fear = (config.roll.result.duality === -1 ? 1 : 0)
+ - (config.rerolledRoll.result.duality === -1 ? 1 : 0)
+
+ if (hope !== 0)
+ updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true });
+ if (stress !== 0)
+ updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true });
+ if (fear !== 0)
+ updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true });
+ }
+ } else {
+ if (config.roll.isCritical || config.roll.result.duality === 1)
+ updates.push({ key: 'hope', value: 1, total: -1, enabled: true });
+ if (config.roll.isCritical)
+ updates.push({ key: 'stress', value: -1, total: 1, enabled: true });
+ if (config.roll.result.duality === -1)
+ updates.push({ key: 'fear', value: 1, total: -1, enabled: true });
+ }
+
+ if (updates.length) {
+ const target = actor.system.partner ?? actor;
+ if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) {
+ await target.modifyResource(updates);
+ }
+ }
+}
+
export const registerRollDiceHooks = () => {
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
@@ -247,45 +292,16 @@ export const registerRollDiceHooks = () => {
!config.skips?.updateCountdowns
) {
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
- await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id);
if (config.roll.result.duality === -1) {
- await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id);
+ await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id,
+ CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id);
+ } else {
+ await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id);
}
}
- const hopeFearAutomation = automationSettings.hopeFear;
- if (
- !config.source?.actor ||
- (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
- config.actionType === 'reaction' ||
- config.tagTeamSelected ||
- config.skips?.resources
- )
- return;
- const actor = await fromUuid(config.source.actor);
- let updates = [];
- if (!actor) return;
- if (config.roll.isCritical || config.roll.result.duality === 1)
- updates.push({ key: 'hope', value: 1, total: -1, enabled: true });
- if (config.roll.isCritical) updates.push({ key: 'stress', value: 1, total: -1, enabled: true });
- if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true });
-
- if (config.rerolledRoll) {
- if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1)
- updates.push({ key: 'hope', value: -1, total: 1, enabled: true });
- if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true });
- if (config.rerolledRoll.result.duality === -1)
- updates.push({ key: 'fear', value: -1, total: 1, enabled: true });
- }
-
- if (updates.length) {
- const target = actor.system.partner ?? actor;
- if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) {
- if (config.rerolledRoll) target.modifyResource(updates);
- else config.costs = [...(config.costs ?? []), ...updates];
- }
- }
+ await automateHopeFear(config);
if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return;
@@ -296,7 +312,5 @@ export const registerRollDiceHooks = () => {
const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId);
if (currentCombatant?.actorId == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
}
-
- return;
});
};
diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs
index 813c913b..59cb6e02 100644
--- a/module/dice/dualityRoll.mjs
+++ b/module/dice/dualityRoll.mjs
@@ -262,8 +262,7 @@ export default class DualityRoll extends D20Roll {
targets: message.system.targets,
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
roll: newRoll,
- rerolledRoll:
- newRoll.result.duality !== message.system.roll.result.duality ? message.system.roll : undefined
+ rerolledRoll: message.system.roll
});
return { newRoll, parsedRoll };
}
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index 8999fdd8..35ab5cc6 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -526,7 +526,7 @@ export default class DhpActor extends Actor {
/**@inheritdoc */
getRollData() {
- const rollData = super.getRollData();
+ const rollData = super.getRollData().clone();
rollData.name = this.name;
rollData.system = this.system.getRollData();
rollData.prof = this.system.proficiency ?? 1;
@@ -679,6 +679,10 @@ export default class DhpActor extends Actor {
return updates;
}
+ /**
+ * Resources are modified asynchronously, so be careful not to update the same resource in
+ * quick succession.
+ */
async modifyResource(resources) {
if (!resources?.length) return;
@@ -761,6 +765,10 @@ export default class DhpActor extends Actor {
}
convertDamageToThreshold(damage) {
+ const massiveDamageEnabled=game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).massiveDamage.enabled;
+ if (massiveDamageEnabled && damage >= (this.system.damageThresholds.severe * 2)) {
+ return 4;
+ }
return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1;
}
diff --git a/module/documents/combat.mjs b/module/documents/combat.mjs
index 01cbee61..20996b77 100644
--- a/module/documents/combat.mjs
+++ b/module/documents/combat.mjs
@@ -28,6 +28,7 @@ export default class DhpCombat extends Combat {
...effect,
name: game.i18n.localize(effect.name),
description: game.i18n.localize(effect.description),
+ effectTargetTypes: grouping.effectTargetTypes ?? [],
flags: {
[`${CONFIG.DH.id}.${CONFIG.DH.FLAGS.combatToggle}`]: {
category: toggle.category,
@@ -45,11 +46,7 @@ export default class DhpCombat extends Combat {
for (let actor of actors) {
await actor.createEmbeddedDocuments(
'ActiveEffect',
- effects.map(effect => ({
- ...effect,
- name: game.i18n.localize(effect.name),
- description: game.i18n.localize(effect.description)
- }))
+ effects.filter(x => x.effectTargetTypes.includes(actor.type))
);
}
} else {
diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs
index 1784698a..b0a107b9 100644
--- a/module/documents/tooltipManager.mjs
+++ b/module/documents/tooltipManager.mjs
@@ -75,7 +75,8 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
{
item: item,
description: item.system?.enrichedDescription ?? item.enrichedDescription,
- config: CONFIG.DH
+ config: CONFIG.DH,
+ allDomains: CONFIG.DH.DOMAIN.allDomains()
}
);
diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs
index ca0ff06c..7fb830d9 100644
--- a/module/helpers/utils.mjs
+++ b/module/helpers/utils.mjs
@@ -212,7 +212,7 @@ foundry.dice.terms.Die.prototype.selfCorrecting = function (modifier) {
};
export const getDamageKey = damage => {
- return ['none', 'minor', 'major', 'severe', 'any'][damage];
+ return ['none', 'minor', 'major', 'severe', 'massive','any'][damage];
};
export const getDamageLabel = damage => {
@@ -225,7 +225,8 @@ export const damageKeyToNumber = key => {
minor: 1,
major: 2,
severe: 3,
- any: 4
+ massive: 4,
+ any: 5
}[key];
};
diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs
index 6954730f..d08d65d1 100644
--- a/module/systemRegistration/settings.mjs
+++ b/module/systemRegistration/settings.mjs
@@ -13,6 +13,16 @@ export const registerDHSettings = () => {
registerMenuSettings();
registerMenus();
registerNonConfigSettings();
+
+ game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.SpotlightRequestQueue, {
+ name: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.name'),
+ label: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.label'),
+ hint: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.hint'),
+ scope: 'world',
+ config: true,
+ type: Boolean,
+ onChange: () => ui.combat.render(),
+ })
};
const registerMenuSettings = () => {
diff --git a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json
index 95e6c243..0e3a89c6 100644
--- a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json
+++ b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json
@@ -427,7 +427,8 @@
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
diff --git a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json
index d77d3379..cf6583e4 100644
--- a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json
+++ b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json
@@ -307,7 +307,8 @@
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
@@ -319,7 +320,7 @@
"trait": null,
"difficulty": null,
"bonus": null,
- "advState": "neutral",
+ "advState": "advantage",
"diceRolling": {
"multiplier": "prof",
"flatMultiplier": 1,
diff --git a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json
index 3ccac5dd..fd73ee36 100644
--- a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json
+++ b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json
@@ -39,7 +39,8 @@
"experiences": {
"7GpgCWSe6hNwnOO7": {
"name": "Throw",
- "value": 2
+ "value": 2,
+ "description": ""
}
},
"bonuses": {
@@ -105,7 +106,8 @@
},
"base": false
}
- ]
+ ],
+ "direct": true
},
"name": "Club",
"img": "icons/weapons/clubs/club-banded-barbed-black.webp",
@@ -337,10 +339,11 @@
{
"value": {
"custom": {
- "enabled": false
+ "enabled": false,
+ "formula": ""
},
"flatMultiplier": 1,
- "dice": "d12",
+ "dice": "d10",
"bonus": 2,
"multiplier": "flat"
},
@@ -356,12 +359,14 @@
"dice": "d6",
"bonus": null,
"custom": {
- "enabled": false
+ "enabled": false,
+ "formula": ""
}
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
@@ -528,7 +533,8 @@
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
diff --git a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json
index 08b22a0b..7ea12036 100644
--- a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json
+++ b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json
@@ -107,7 +107,8 @@
},
"base": false
}
- ]
+ ],
+ "direct": true
},
"img": "icons/magic/symbols/rune-sigil-rough-white-teal.webp",
"type": "attack",
diff --git a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json
index 13b9d624..72ec986d 100644
--- a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json
+++ b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json
@@ -108,7 +108,8 @@
},
"base": false
}
- ]
+ ],
+ "direct": true
},
"type": "attack",
"chatDisplay": false
@@ -358,7 +359,8 @@
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
diff --git a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json
index e3b34aea..a900aa7b 100644
--- a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json
+++ b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json
@@ -377,7 +377,8 @@
}
}
],
- "includeBase": false
+ "includeBase": false,
+ "direct": true
},
"target": {
"type": "any",
diff --git a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json
index 943559e1..557ef607 100644
--- a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json
+++ b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json
@@ -233,7 +233,89 @@
"system": {
"description": "
The Assassin deals direct damage while they’re Hidden.
", "resource": null, - "actions": {}, + "actions": { + "xFBE0jLf96fbCY7K": { + "type": "attack", + "_id": "xFBE0jLf96fbCY7K", + "systemPath": "actions", + "baseAction": false, + "description": "The Assassin deals direct damage while they’re Hidden.
", + "chatDisplay": true, + "originItem": { + "type": "itemCollection" + }, + "actionType": "action", + "cost": [], + "uses": { + "value": null, + "max": "", + "recovery": null, + "consumeOnSuccess": false + }, + "damage": { + "parts": [ + { + "value": { + "custom": { + "enabled": false, + "formula": "" + }, + "flatMultiplier": 2, + "dice": "d10", + "bonus": 2, + "multiplier": "flat" + }, + "applyTo": "hitPoints", + "type": [ + "physical" + ], + "base": false, + "resultBased": false, + "valueAlt": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d6", + "bonus": null, + "custom": { + "enabled": false, + "formula": "" + } + } + } + ], + "includeBase": false, + "direct": true + }, + "target": { + "type": "any", + "amount": null + }, + "effects": [], + "roll": { + "type": "attack", + "trait": null, + "difficulty": null, + "bonus": null, + "advState": "neutral", + "diceRolling": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d6", + "compare": null, + "treshold": null + }, + "useDefault": false + }, + "save": { + "trait": null, + "difficulty": null, + "damageMod": "none" + }, + "name": "Hidden attack", + "img": "icons/magic/perception/silhouette-stealth-shadow.webp", + "range": "close" + } + }, "originItemType": null, "originId": null }, diff --git a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json index 10f48d17..570db804 100644 --- a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json +++ b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json @@ -478,7 +478,8 @@ } } ], - "includeBase": false + "includeBase": false, + "direct": true }, "target": { "type": "any", diff --git a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json index 74d7e2c3..721d8973 100644 --- a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json +++ b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json @@ -340,6 +340,87 @@ "name": "Curse", "img": "icons/magic/unholy/hand-marked-pink.webp", "range": "veryClose" + }, + "zLKfwa8a2YBRLKAF": { + "type": "attack", + "_id": "zLKfwa8a2YBRLKAF", + "systemPath": "actions", + "baseAction": false, + "description": "Attacks made by the Hunter against a Deathlocked target deal direct damage.
", + "chatDisplay": true, + "originItem": { + "type": "itemCollection" + }, + "actionType": "action", + "cost": [], + "uses": { + "value": null, + "max": "", + "recovery": null, + "consumeOnSuccess": false + }, + "damage": { + "parts": [ + { + "value": { + "custom": { + "enabled": false, + "formula": "" + }, + "flatMultiplier": 2, + "dice": "d12", + "bonus": 1, + "multiplier": "flat" + }, + "applyTo": "hitPoints", + "type": [ + "physical" + ], + "base": false, + "resultBased": false, + "valueAlt": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d6", + "bonus": null, + "custom": { + "enabled": false, + "formula": "" + } + } + } + ], + "includeBase": false, + "direct": true + }, + "target": { + "type": "any", + "amount": null + }, + "effects": [], + "roll": { + "type": "attack", + "trait": null, + "difficulty": null, + "bonus": null, + "advState": "neutral", + "diceRolling": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d6", + "compare": null, + "treshold": null + }, + "useDefault": false + }, + "save": { + "trait": null, + "difficulty": null, + "damageMod": "none" + }, + "name": "Deathlocked attack", + "img": "icons/magic/unholy/hand-marked-pink.webp", + "range": "veryClose" } }, "originItemType": null, diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json index d5f30dda..2a753812 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json @@ -312,9 +312,10 @@ { "value": { "custom": { - "enabled": false + "enabled": false, + "formula": "" }, - "flatMultiplier": 1, + "flatMultiplier": 2, "dice": "d6", "bonus": 8, "multiplier": "flat" @@ -331,12 +332,14 @@ "dice": "d6", "bonus": null, "custom": { - "enabled": false + "enabled": false, + "formula": "" } } } ], - "includeBase": false + "includeBase": false, + "direct": true }, "target": { "type": "any", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json index 056bf848..d04dab50 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json @@ -804,7 +804,8 @@ } } ], - "includeBase": false + "includeBase": false, + "direct": true }, "target": { "type": "any", diff --git a/src/packs/domains/domainCard_Conjure_Swarm_rZPH0BY8Sznc9sFG.json b/src/packs/domains/domainCard_Conjure_Swarm_rZPH0BY8Sznc9sFG.json index 2fca6775..ededde93 100644 --- a/src/packs/domains/domainCard_Conjure_Swarm_rZPH0BY8Sznc9sFG.json +++ b/src/packs/domains/domainCard_Conjure_Swarm_rZPH0BY8Sznc9sFG.json @@ -208,13 +208,13 @@ }, "changes": [ { - "key": "system.resistance.magical.reduction", + "key": "system.rules.damageReduction.reduceSeverity.magical", "mode": 2, "value": "1", "priority": null }, { - "key": "system.resistance.magical.reduction", + "key": "system.rules.damageReduction.reduceSeverity.physical", "mode": 2, "value": "1", "priority": null diff --git a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json index 81ce16f9..39070236 100644 --- a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json +++ b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json @@ -457,7 +457,8 @@ } } ], - "includeBase": false + "includeBase": false, + "direct": true }, "target": { "type": "any", diff --git a/src/packs/items/armors/armor_Elundrian_Chain_Mail_Q6LxmtFetDDkoZVZ.json b/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json similarity index 97% rename from src/packs/items/armors/armor_Elundrian_Chain_Mail_Q6LxmtFetDDkoZVZ.json rename to src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json index d8b938fd..abf81dae 100644 --- a/src/packs/items/armors/armor_Elundrian_Chain_Mail_Q6LxmtFetDDkoZVZ.json +++ b/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json @@ -1,6 +1,6 @@ { "folder": "hLn0v6ov6KuFgptu", - "name": "Elundrian Chain Mail", + "name": "Elundrian Chain Armor", "type": "armor", "_id": "Q6LxmtFetDDkoZVZ", "img": "icons/equipment/chest/breastplate-sculpted-green.webp", diff --git a/src/packs/subclasses/feature_Iron_Will_7AVRNyBcd1Nffjtn.json b/src/packs/subclasses/feature_Iron_Will_7AVRNyBcd1Nffjtn.json index eda72fd7..bea62e2b 100644 --- a/src/packs/subclasses/feature_Iron_Will_7AVRNyBcd1Nffjtn.json +++ b/src/packs/subclasses/feature_Iron_Will_7AVRNyBcd1Nffjtn.json @@ -32,7 +32,7 @@ "img": "icons/equipment/chest/breastplate-helmet-metal.webp", "changes": [ { - "key": "system.rules.damageReduction.maxArmorMarked.stressExtra", + "key": "system.rules.damageReduction.maxArmorMarked.value", "mode": 2, "value": "1", "priority": null diff --git a/src/packs/subclasses/feature_Wings_of_Light_KkQH0tYhagIqe2MT.json b/src/packs/subclasses/feature_Wings_of_Light_KkQH0tYhagIqe2MT.json index 2fa32bec..5b86e348 100644 --- a/src/packs/subclasses/feature_Wings_of_Light_KkQH0tYhagIqe2MT.json +++ b/src/packs/subclasses/feature_Wings_of_Light_KkQH0tYhagIqe2MT.json @@ -15,7 +15,16 @@ "description": "Mark a Stress to pick up and carry another willing creature approximately your size or smaller.
", "chatDisplay": true, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "stress", + "value": 1, + "itemId": null, + "step": null, + "consumeOnSuccess": false + } + ], "uses": { "value": null, "max": "", @@ -60,12 +69,12 @@ } ], "target": { - "type": "any", + "type": "self", "amount": null }, "name": "Spend Hope", "img": "icons/magic/light/projectile-beam-yellow.webp", - "range": "" + "range": "self" } }, "originItemType": null, diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index 91b2846b..b5ed8764 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -37,3 +37,5 @@ @import './image-select/sheet.less'; @import './item-transfer/sheet.less'; + +@import './settings/change-currency-icon.less'; \ No newline at end of file diff --git a/styles/less/dialog/settings/change-currency-icon.less b/styles/less/dialog/settings/change-currency-icon.less new file mode 100644 index 00000000..61870a4b --- /dev/null +++ b/styles/less/dialog/settings/change-currency-icon.less @@ -0,0 +1,13 @@ +.application.daggerheart.dialog.dh-style.change-currency-icon { + .displayed-icon { + height: 2.5rem; + text-align: center; + font-size: 2.5rem; + margin-bottom: 1.25rem; + } + .input-row { + display: flex; + gap: 4px; + align-items: center; + } +} \ No newline at end of file diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 79deb99d..e740d917 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -6,7 +6,8 @@ input[type='text'], input[type='number'], - textarea { + textarea, + .input[contenteditable] { background: light-dark(transparent, transparent); border-radius: 6px; box-shadow: 0 4px 30px @soft-shadow; @@ -43,6 +44,14 @@ } } + .input[contenteditable] { + cursor: var(--cursor-text); + &:empty:before { + color: light-dark(@dark-40, @beige-50); + content: attr(placeholder); + } + } + input[type='checkbox'], input[type='radio'] { &:checked::after { diff --git a/styles/less/hud/token-hud/token-hud.less b/styles/less/hud/token-hud/token-hud.less index ac269172..46003975 100644 --- a/styles/less/hud/token-hud/token-hud.less +++ b/styles/less/hud/token-hud/token-hud.less @@ -56,7 +56,7 @@ .effect-locked { position: absolute; bottom: 2px; - right: 2px; + left: 11.5px; font-size: 12px; color: @golden; filter: drop-shadow(0 0 3px black); diff --git a/styles/less/sheets/actors/adversary/header.less b/styles/less/sheets/actors/adversary/header.less index d4a7812e..aa3e6e83 100644 --- a/styles/less/sheets/actors/adversary/header.less +++ b/styles/less/sheets/actors/adversary/header.less @@ -12,18 +12,19 @@ gap: 5px; align-items: center; justify-content: space-between; - padding: 0; - padding-top: 5px; - padding-bottom: 8px; + padding: 8px 0; flex: 1; - input[type='text'] { + h1 { + display: flex; + flex: 1; + padding: 6px 0 0 0; font-size: var(--font-size-32); - height: 42px; text-align: start; border: 1px solid transparent; outline: 2px solid transparent; transition: all 0.3s ease; + word-break: break-word; &:hover { outline: 2px solid light-dark(@dark, @golden); diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 80089cf7..4115fbd5 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -34,19 +34,22 @@ .name-row { display: flex; gap: 5px; - align-items: end; + align-items: start; justify-content: space-between; padding: 0; padding-top: 5px; flex: 1; - input[type='text'] { + h1 { + display: flex; + flex: 1; + padding: 6px 0 0 0; font-size: var(--font-size-32); - height: 42px; text-align: start; border: 1px solid transparent; outline: 2px solid transparent; transition: all 0.3s ease; + word-break: break-word; &:hover { outline: 2px solid light-dark(@dark, @golden); @@ -57,6 +60,8 @@ white-space: nowrap; display: flex; justify-content: end; + height: var(--font-size-32); + margin-top: 6px; .label { display: flex; diff --git a/styles/less/utils/fonts.less b/styles/less/utils/fonts.less index 7d84366a..5c1e597a 100755 --- a/styles/less/utils/fonts.less +++ b/styles/less/utils/fonts.less @@ -2,14 +2,14 @@ @import './mixin.less'; :root { - --font-title: 'Cinzel Decorative'; - --font-subtitle: 'Cinzel'; - --font-body: 'Montserrat'; + --dh-font-title: 'Cinzel Decorative'; + --dh-font-subtitle: 'Cinzel'; + --dh-font-body: 'Montserrat'; } -@font-title: ~"var(--font-title, 'Cinzel Decorative'), serif"; -@font-subtitle: ~"var(--font-subtitle, 'Cinzel'), serif"; -@font-body: ~"var(--font-body, 'Montserrat'), sans-serif"; +@font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif"; +@font-subtitle: ~"var(--dh-font-subtitle, 'Cinzel'), serif"; +@font-body: ~"var(--dh-font-body, 'Montserrat'), sans-serif"; .dh-style { .dh-typography(); diff --git a/templates/hud/tokenHUD.hbs b/templates/hud/tokenHUD.hbs index 09259d4a..f079e5d9 100644 --- a/templates/hud/tokenHUD.hbs +++ b/templates/hud/tokenHUD.hbs @@ -46,8 +46,12 @@