diff --git a/assets/icons/dice/adv/d10.svg b/assets/icons/dice/adv/d10.svg
new file mode 100644
index 00000000..4dc6a6f9
--- /dev/null
+++ b/assets/icons/dice/adv/d10.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/adv/d12.svg b/assets/icons/dice/adv/d12.svg
new file mode 100644
index 00000000..f9cf1301
--- /dev/null
+++ b/assets/icons/dice/adv/d12.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/adv/d20.svg b/assets/icons/dice/adv/d20.svg
new file mode 100644
index 00000000..098d3131
--- /dev/null
+++ b/assets/icons/dice/adv/d20.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/adv/d4.svg b/assets/icons/dice/adv/d4.svg
new file mode 100644
index 00000000..e52c5f46
--- /dev/null
+++ b/assets/icons/dice/adv/d4.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/adv/d6.svg b/assets/icons/dice/adv/d6.svg
new file mode 100644
index 00000000..5ea7ebc1
--- /dev/null
+++ b/assets/icons/dice/adv/d6.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/adv/d8.svg b/assets/icons/dice/adv/d8.svg
new file mode 100644
index 00000000..aa733008
--- /dev/null
+++ b/assets/icons/dice/adv/d8.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/default/d10.svg b/assets/icons/dice/default/d10.svg
new file mode 100644
index 00000000..cdca9728
--- /dev/null
+++ b/assets/icons/dice/default/d10.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/dice/default/d12.svg b/assets/icons/dice/default/d12.svg
new file mode 100644
index 00000000..e6271a75
--- /dev/null
+++ b/assets/icons/dice/default/d12.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/dice/default/d20.svg b/assets/icons/dice/default/d20.svg
new file mode 100644
index 00000000..4d3ac16e
--- /dev/null
+++ b/assets/icons/dice/default/d20.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/default/d4.svg b/assets/icons/dice/default/d4.svg
new file mode 100644
index 00000000..db5ad410
--- /dev/null
+++ b/assets/icons/dice/default/d4.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/dice/default/d6.svg b/assets/icons/dice/default/d6.svg
new file mode 100644
index 00000000..6bc98c66
--- /dev/null
+++ b/assets/icons/dice/default/d6.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/dice/default/d8.svg b/assets/icons/dice/default/d8.svg
new file mode 100644
index 00000000..edf35cff
--- /dev/null
+++ b/assets/icons/dice/default/d8.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/dice/disadv/d10.svg b/assets/icons/dice/disadv/d10.svg
new file mode 100644
index 00000000..af4d0d19
--- /dev/null
+++ b/assets/icons/dice/disadv/d10.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/disadv/d12.svg b/assets/icons/dice/disadv/d12.svg
new file mode 100644
index 00000000..75a7073c
--- /dev/null
+++ b/assets/icons/dice/disadv/d12.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/disadv/d20.svg b/assets/icons/dice/disadv/d20.svg
new file mode 100644
index 00000000..e4130440
--- /dev/null
+++ b/assets/icons/dice/disadv/d20.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/disadv/d4.svg b/assets/icons/dice/disadv/d4.svg
new file mode 100644
index 00000000..3ec74176
--- /dev/null
+++ b/assets/icons/dice/disadv/d4.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/disadv/d6.svg b/assets/icons/dice/disadv/d6.svg
new file mode 100644
index 00000000..7e79e2ed
--- /dev/null
+++ b/assets/icons/dice/disadv/d6.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/disadv/d8.svg b/assets/icons/dice/disadv/d8.svg
new file mode 100644
index 00000000..999d818f
--- /dev/null
+++ b/assets/icons/dice/disadv/d8.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/fear/d10.svg b/assets/icons/dice/fear/d10.svg
new file mode 100644
index 00000000..80236173
--- /dev/null
+++ b/assets/icons/dice/fear/d10.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/fear/d12.svg b/assets/icons/dice/fear/d12.svg
new file mode 100644
index 00000000..08841af4
--- /dev/null
+++ b/assets/icons/dice/fear/d12.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/fear/d20.svg b/assets/icons/dice/fear/d20.svg
new file mode 100644
index 00000000..bd4e12a8
--- /dev/null
+++ b/assets/icons/dice/fear/d20.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/fear/d4.svg b/assets/icons/dice/fear/d4.svg
new file mode 100644
index 00000000..b641d519
--- /dev/null
+++ b/assets/icons/dice/fear/d4.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/fear/d6.svg b/assets/icons/dice/fear/d6.svg
new file mode 100644
index 00000000..bcc3fac2
--- /dev/null
+++ b/assets/icons/dice/fear/d6.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/fear/d8.svg b/assets/icons/dice/fear/d8.svg
new file mode 100644
index 00000000..9a706322
--- /dev/null
+++ b/assets/icons/dice/fear/d8.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/hope/d10.svg b/assets/icons/dice/hope/d10.svg
new file mode 100644
index 00000000..e5566c21
--- /dev/null
+++ b/assets/icons/dice/hope/d10.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/dice/hope/d12.svg b/assets/icons/dice/hope/d12.svg
new file mode 100644
index 00000000..a93766fe
--- /dev/null
+++ b/assets/icons/dice/hope/d12.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/hope/d20.svg b/assets/icons/dice/hope/d20.svg
new file mode 100644
index 00000000..bb87a31e
--- /dev/null
+++ b/assets/icons/dice/hope/d20.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/hope/d4.svg b/assets/icons/dice/hope/d4.svg
new file mode 100644
index 00000000..ab238828
--- /dev/null
+++ b/assets/icons/dice/hope/d4.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/hope/d6.svg b/assets/icons/dice/hope/d6.svg
new file mode 100644
index 00000000..26ea78ea
--- /dev/null
+++ b/assets/icons/dice/hope/d6.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/icons/dice/hope/d8.svg b/assets/icons/dice/hope/d8.svg
new file mode 100644
index 00000000..584b0fdc
--- /dev/null
+++ b/assets/icons/dice/hope/d8.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/daggerheart.mjs b/daggerheart.mjs
index 81b404d5..82c56dff 100644
--- a/daggerheart.mjs
+++ b/daggerheart.mjs
@@ -124,7 +124,7 @@ Hooks.once('init', () => {
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
CONFIG.ui.resources = applications.ui.DhFearTracker;
- CONFIG.ux.ContextMenu = applications.ux.ContextMenu;
+ CONFIG.ux.ContextMenu = applications.ux.DHContextMenu;
CONFIG.ux.TooltipManager = documents.DhTooltipManager;
game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent);
diff --git a/lang/en.json b/lang/en.json
index b998cf9f..4a125fe2 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -248,7 +248,8 @@
"potentialAdversaries": "Potential Adversaries",
"adversaries": "Adversaries"
},
- "basics": "Basics"
+ "basics": "Basics",
+ "dualityRoll": "Duality Roll"
},
"ActionType": {
"passive": "Passive",
diff --git a/module/applications/dialogs/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs
index cab0d36d..026aac46 100644
--- a/module/applications/dialogs/costSelectionDialog.mjs
+++ b/module/applications/dialogs/costSelectionDialog.mjs
@@ -30,7 +30,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
static PARTS = {
costSelection: {
id: 'costSelection',
- template: 'systems/daggerheart/templates/dialogs/costSelection.hbs'
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs'
}
};
diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs
index cf620e43..7eaeacb3 100644
--- a/module/applications/dialogs/d20RollDialog.mjs
+++ b/module/applications/dialogs/d20RollDialog.mjs
@@ -20,10 +20,12 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
static DEFAULT_OPTIONS = {
tag: 'form',
id: 'roll-selection',
- classes: ['daggerheart', 'views', 'roll-selection'],
+ classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'roll-selection'],
position: {
- width: 400,
- height: 'auto'
+ width: 550
+ },
+ window: {
+ icon: 'fa-solid fa-dice'
},
actions: {
updateIsAdvantage: this.updateIsAdvantage,
@@ -37,20 +39,29 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}
};
+ get title() {
+ return this.config.title;
+ }
+
/** @override */
static PARTS = {
- costSelection: {
- id: 'costSelection',
- template: 'systems/daggerheart/templates/dialogs/costSelection.hbs'
+ header: {
+ id: 'header',
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/header.hbs'
},
rollSelection: {
id: 'rollSelection',
- template: 'systems/daggerheart/templates/dialogs/rollSelection.hbs'
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/rollSelection.hbs'
+ },
+ costSelection: {
+ id: 'costSelection',
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
+ context.rollConfig = this.config;
context.hasRoll = !!this.config.roll;
context.roll = this.roll;
context.rollType = this.roll?.constructor.name;
@@ -60,6 +71,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}));
context.selectedExperiences = this.config.experiences;
context.advantage = this.config.roll?.advantage;
+ context.disadvantage = this.config.roll?.disadvantage;
context.diceOptions = CONFIG.DH.GENERAL.diceTypes;
context.canRoll = true;
context.isLite = this.config.roll?.lite;
@@ -75,7 +87,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}
context.extraFormula = this.config.extraFormula;
context.formula = this.roll.constructFormula(this.config);
-
return context;
}
@@ -96,6 +107,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
static updateIsAdvantage(_, button) {
const advantage = Number(button.dataset.advantage);
+ this.advantage = advantage === 1;
+ this.disadvantage = advantage === -1;
+
this.config.roll.advantage = this.config.roll.advantage === advantage ? 0 : advantage;
this.render();
}
diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs
index 84709251..442a1491 100644
--- a/module/applications/dialogs/damageDialog.mjs
+++ b/module/applications/dialogs/damageDialog.mjs
@@ -30,7 +30,7 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
static PARTS = {
damageSelection: {
id: 'damageSelection',
- template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs'
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/damageSelection.hbs'
}
};
diff --git a/module/applications/dialogs/damageSelectionDialog.mjs b/module/applications/dialogs/damageSelectionDialog.mjs
index f4f44bc8..5248e81d 100644
--- a/module/applications/dialogs/damageSelectionDialog.mjs
+++ b/module/applications/dialogs/damageSelectionDialog.mjs
@@ -44,7 +44,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
static PARTS = {
damageSelection: {
id: 'damageSelection',
- template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs'
+ template: 'systems/daggerheart/templates/dialogs/dice-roll/damageSelection.hbs'
}
};
diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs
index cbcd3f24..17f56c02 100644
--- a/module/applications/sheets/actors/adversary.mjs
+++ b/module/applications/sheets/actors/adversary.mjs
@@ -85,7 +85,8 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
static async reactionRoll(event) {
const config = {
event: event,
- title: `${this.actor.name} - Reaction Roll`,
+ title: `Reaction Roll: ${this.actor.name}`,
+ headerTitle: 'Adversary Reaction Roll',
roll: {
// modifier: null,
type: 'reaction'
diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs
index 5c5109de..9122122c 100644
--- a/module/applications/sheets/actors/character.mjs
+++ b/module/applications/sheets/actors/character.mjs
@@ -490,6 +490,19 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
}
}
+ static async rollAttribute(event, button) {
+ const abilityLabel = game.i18n.localize(abilities[button.dataset.attribute].label);
+ const config = {
+ event: event,
+ title: `${game.i18n.localize('DAGGERHEART.General.dualityRoll')}: ${this.actor.name}`,
+ headerTitle: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', { ability: abilityLabel }),
+ roll: {
+ trait: button.dataset.attribute
+ }
+ };
+ this.document.diceRoll(config);
+ }
+
/* -------------------------------------------- */
/* Filter Menus */
/* -------------------------------------------- */
diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs
index 182a3539..8b09a643 100644
--- a/module/applications/ui/chatLog.mjs
+++ b/module/applications/ui/chatLog.mjs
@@ -50,13 +50,13 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
element.addEventListener('mouseenter', this.hoverAdvantage)
);
html.querySelectorAll('.advantage').forEach(element =>
- element.addEventListener('click', event => this.selectAdvantage.bind(this)(event, data.message))
+ element.addEventListener('click', event => this.selectAdvantage.call(this, event, data.message))
);
html.querySelectorAll('.ability-use-button').forEach(element =>
- element.addEventListener('click', event => this.abilityUseButton.bind(this)(event, data.message))
+ element.addEventListener('click', event => this.abilityUseButton.call(this, event, data.message))
);
html.querySelectorAll('.action-use-button').forEach(element =>
- element.addEventListener('click', event => this.actionUseButton.bind(this)(event, data.message))
+ element.addEventListener('click', event => this.actionUseButton.call(this, event, data.message))
);
};
@@ -229,24 +229,52 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
}
};
- onToggleTargets = async event => {
+ /**
+ * Toggle visibility of target containers.
+ * @param {MouseEvent} event
+ */
+ onToggleTargets(event) {
event.stopPropagation();
- $($(event.currentTarget).parent()).find('.target-container').toggleClass('hidden');
- };
+ event.currentTarget.parentElement
+ ?.querySelectorAll('.target-container')
+ .forEach(el => el.classList.toggle('hidden'));
+ }
- hoverAdvantage = event => {
- $(event.currentTarget).siblings('.advantage').toggleClass('unused');
- };
+ /**
+ * Highlight advantage icons on hover.
+ * @param {MouseEvent} event
+ */
+ hoverAdvantage(event) {
+ const parent = event.currentTarget.parentElement;
+ if (!parent) return;
- selectAdvantage = async (event, message) => {
+ parent.querySelectorAll('.advantage').forEach(el => {
+ if (el !== event.currentTarget) {
+ el.classList.toggle('unused');
+ }
+ });
+ }
+
+ /**
+ * Handle selecting an advantage and disable further selection.
+ * @param {MouseEvent} event
+ * @param {object} message
+ */
+ async selectAdvantage(event, message) {
event.stopPropagation();
const updateMessage = game.messages.get(message._id);
- await updateMessage.update({ system: { advantageSelected: event.currentTarget.id === 'hope' ? 1 : 2 } });
+ await updateMessage?.update({
+ system: { advantageSelected: event.currentTarget.id === 'hope' ? 1 : 2 }
+ });
- $(event.currentTarget).siblings('.advantage').off('click');
- $(event.currentTarget).off('click');
- };
+ const parent = event.currentTarget.parentElement;
+ if (!parent) return;
+
+ parent.querySelectorAll('.advantage').forEach(el => {
+ el.replaceWith(el.cloneNode(true));
+ });
+ }
abilityUseButton = async (event, message) => {
event.stopPropagation();
diff --git a/module/applications/ux/_module.mjs b/module/applications/ux/_module.mjs
index 5ec0eecf..ead918fa 100644
--- a/module/applications/ux/_module.mjs
+++ b/module/applications/ux/_module.mjs
@@ -1,2 +1,2 @@
export { default as FilterMenu } from './filter-menu.mjs';
-export { default as ContextMenu } from './contextMenu.mjs';
+export { default as DHContextMenu } from './contextMenu.mjs';
diff --git a/module/applications/ux/contextMenu.mjs b/module/applications/ux/contextMenu.mjs
index f7658d42..a913c450 100644
--- a/module/applications/ux/contextMenu.mjs
+++ b/module/applications/ux/contextMenu.mjs
@@ -1,4 +1,63 @@
-export default class DhContextMenu extends foundry.applications.ux.ContextMenu.implementation {
+/**
+ * @typedef ContextMenuEntry
+ * @property {string} name The context menu label. Can be localized.
+ * @property {string} [icon] A string containing an HTML icon element for the menu item.
+ * @property {string} [classes] Additional CSS classes to apply to this menu item.
+ * @property {string} [group] An identifier for a group this entry belongs to.
+ * @property {ContextMenuJQueryCallback} callback The function to call when the menu item is clicked.
+ * @property {ContextMenuCondition|boolean} [condition] A function to call or boolean value to determine if this entry
+ * appears in the menu.
+ */
+
+/**
+ * @callback ContextMenuCondition
+ * @param {jQuery|HTMLElement} html The element of the context menu entry.
+ * @returns {boolean} Whether the entry should be rendered in the context menu.
+ */
+
+/**
+ * @callback ContextMenuCallback
+ * @param {HTMLElement} target The element that the context menu has been triggered for.
+ * @returns {unknown}
+ */
+
+/**
+ * @callback ContextMenuJQueryCallback
+ * @param {HTMLElement|jQuery} target The element that the context menu has been triggered for. Will
+ * either be a jQuery object or an HTMLElement instance, depending
+ * on how the ContextMenu was configured.
+ * @returns {unknown}
+ */
+
+/**
+ * @typedef ContextMenuOptions
+ * @property {string} [eventName="contextmenu"] Optionally override the triggering event which can spawn the menu. If
+ * the menu is using fixed positioning, this event must be a MouseEvent.
+ * @property {ContextMenuCallback} [onOpen] A function to call when the context menu is opened.
+ * @property {ContextMenuCallback} [onClose] A function to call when the context menu is closed.
+ * @property {boolean} [fixed=false] If true, the context menu is given a fixed position rather than being
+ * injected into the target.
+ * @property {boolean} [jQuery=true] If true, callbacks will be passed jQuery objects instead of HTMLElement
+ * instances.
+ */
+
+/**
+ * @typedef ContextMenuRenderOptions
+ * @property {Event} [event] The event that triggered the context menu opening.
+ * @property {boolean} [animate=true] Animate the context menu opening.
+ */
+
+/**
+ * A subclass of ContextMenu.
+ * @extends {foundry.applications.ux.ContextMenu}
+ */
+export default class DHContextMenu extends foundry.applications.ux.ContextMenu {
+ /**
+ * @param {HTMLElement|jQuery} container - The HTML element that contains the context menu targets.
+ * @param {string} selector - A CSS selector which activates the context menu.
+ * @param {ContextMenuEntry[]} menuItems - An Array of entries to display in the menu
+ * @param {ContextMenuOptions} [options] - Additional options to configure the context menu.
+ */
constructor(container, selector, menuItems, options) {
super(container, selector, menuItems, options);
@@ -6,12 +65,21 @@ export default class DhContextMenu extends foundry.applications.ux.ContextMenu.i
this.#jQuery = options.jQuery;
}
+ /**
+ * Whether to pass jQuery objects or HTMLElement instances to callback.
+ * @type {boolean}
+ */
#jQuery;
+ /**@inheritdoc */
activateListeners(menu) {
menu.addEventListener('click', this.#onClickItem.bind(this));
}
+ /**
+ * Handle click events on context menu items.
+ * @param {PointerEvent} event The click event
+ */
#onClickItem(event) {
event.preventDefault();
event.stopPropagation();
@@ -22,6 +90,12 @@ export default class DhContextMenu extends foundry.applications.ux.ContextMenu.i
this.close();
}
+ /* -------------------------------------------- */
+
+ /**
+ * Trigger a context menu event in response to a normal click on a additional options button.
+ * @param {PointerEvent} event
+ */
static triggerContextMenu(event) {
event.preventDefault();
event.stopPropagation();
diff --git a/module/applications/ux/filter-menu.mjs b/module/applications/ux/filter-menu.mjs
index ff2fb036..bc9e2f81 100644
--- a/module/applications/ux/filter-menu.mjs
+++ b/module/applications/ux/filter-menu.mjs
@@ -197,11 +197,9 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
}
}));
- return [
- ...game.i18n.sortObjects(typesFilters, 'name'),
- ...game.i18n.sortObjects(burdenFilter, 'name'),
- ...game.i18n.sortObjects(damageTypeFilter, 'name')
- ];
+ const sort = arr => game.i18n.sortObjects(arr, 'name');
+
+ return [...sort(typesFilters, 'name'), ...sort(burdenFilter, 'name'), ...sort(damageTypeFilter, 'name')];
}
/**
diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs
index e752421c..b9faecc4 100644
--- a/module/data/action/baseAction.mjs
+++ b/module/data/action/baseAction.mjs
@@ -244,7 +244,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
}
if (this.hasRoll) {
- console.log(config);
const rollConfig = this.prepareRoll(config);
config.roll = rollConfig;
config = await this.actor.diceRoll(config);
diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs
index de93e90c..1a250327 100644
--- a/module/data/item/base.mjs
+++ b/module/data/item/base.mjs
@@ -1,5 +1,3 @@
-import { actionsTypes } from '../action/_module.mjs';
-
/**
* Describes metadata about the item data model type
* @typedef {Object} ItemDataModelMetadata
@@ -55,23 +53,27 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
return data;
}
+ /**@inheritdoc */
async _preCreate(data, options, user) {
+ // Skip if no initial action is required or actions already exist
if (!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
- const actionType = {
- weapon: 'attack'
- }[this.constructor.metadata.type],
- cls = actionsTypes[actionType],
- action = new cls(
- {
- _id: foundry.utils.randomID(),
- type: actionType,
- name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
- ...cls.getSourceConfig(this.parent)
- },
- {
- parent: this.parent
- }
- );
+
+ const metadataType = this.constructor.metadata.type;
+ const actionType = { weapon: 'attack' }[metadataType];
+ const ActionClass = game.system.api.models.actions.actionsTypes[actionType];
+
+ const action = new ActionClass(
+ {
+ _id: foundry.utils.randomID(),
+ type: actionType,
+ name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
+ ...ActionClass.getSourceConfig(this.parent)
+ },
+ {
+ parent: this.parent
+ }
+ );
+
this.updateSource({ actions: [action] });
}
diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs
index 6200b690..6db51225 100644
--- a/module/helpers/handlebarsHelper.mjs
+++ b/module/helpers/handlebarsHelper.mjs
@@ -7,49 +7,11 @@ export default class RegisterHandlebarsHelpers {
join: this.join,
add: this.add,
subtract: this.subtract,
- objectSelector: this.objectSelector,
includes: this.includes,
- debug: this.debug,
- signedNumber: this.signedNumber,
- length: this.length,
- switch: this.switch,
- case: this.case,
- eq: this.eq,
- ne: this.ne,
- lt: this.lt,
- gt: this.gt,
- lte: this.lte,
- gte: this.gte,
- and: this.and,
- or: this.or
+ case: this.case
});
}
- static eq(v1, v2) {
- return v1 === v2;
- }
- static ne(v1, v2) {
- return v1 !== v2;
- }
- static lt(v1, v2) {
- return v1 < v2;
- }
- static gt(v1, v2) {
- return v1 > v2;
- }
- static lte(v1, v2) {
- return v1 <= v2;
- }
- static gte(v1, v2) {
- return v1 >= v2;
- }
- static and() {
- return Array.prototype.every.call(arguments, Boolean);
- }
- static or() {
- return Array.prototype.slice.call(arguments, 0, -1).some(Boolean);
- }
-
static times(nr, block) {
var accum = '';
for (var i = 0; i < nr; ++i) accum += block.fn(i);
@@ -72,69 +34,14 @@ export default class RegisterHandlebarsHelpers {
return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum);
}
- static objectSelector(options) {
- let { title, values, titleFontSize, ids, style } = options.hash;
-
- const titleLength = getWidthOfText(title, titleFontSize, true, true);
- const margins = 12;
-
- const buttons = options.fn();
- const nrButtons = Math.max($(buttons).length - 1, 1);
- const iconWidth = 26;
-
- const texts = values
- .reduce((acc, x, index) => {
- if (x) {
- acc.push(
- `${x} `
- );
- }
-
- return acc;
- }, [])
- .join(' ');
-
- const html = `
-
-
${title}
-
- ${texts}
-
- ${buttons}
-
-
- `;
-
- return new Handlebars.SafeString(html);
- }
-
static includes(list, item) {
return list.includes(item);
}
- static signedNumber(number) {
- return number >= 0 ? `+${number}` : number;
- }
-
- static length(obj) {
- return Object.keys(obj).length;
- }
-
- static switch(value, options) {
- this.switch_value = value;
- this.switch_break = false;
- return options.fn(this);
- }
-
static case(value, options) {
if (value == this.switch_value) {
this.switch_break = true;
return options.fn(this);
}
}
-
- static debug(a) {
- console.log(a);
- return a;
- }
}
diff --git a/styles/application.less b/styles/application.less
index 24b6a7d4..412d41e7 100644
--- a/styles/application.less
+++ b/styles/application.less
@@ -233,81 +233,6 @@ div.daggerheart.views.multiclass {
}
.roll-dialog-container {
- .disadvantage,
- .advantage {
- border: 2px solid @secondaryAccent;
- border-radius: 6px;
- display: flex;
- align-items: center;
- padding: 4px;
- margin-bottom: 6px;
-
- &.selected {
- filter: drop-shadow(0px 0px 3px @mainShadow);
- }
-
- input {
- border: 0;
- }
-
- button {
- flex: 0;
- border-radius: 50%;
- height: 20px;
- width: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 2px 0 2px 4px;
- padding: 12px;
-
- i {
- margin: 0;
- }
- }
- }
-
- .roll-dialog-experience-container {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: @halfMargin;
-
- .roll-dialog-chip {
- border: @thinBorder solid black;
- border-radius: 6px;
- min-width: calc(33% - 2px);
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: @halfMargin;
- cursor: pointer;
- padding: @fullPadding;
- background: grey;
- overflow: hidden;
- font-weight: bold;
-
- &.hover {
- filter: drop-shadow(0 0 3px @mainShadow);
- }
-
- span {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-
- &.selected {
- background: green;
-
- span {
- filter: drop-shadow(0 0 3px @secondaryShadow);
- }
- }
- }
- }
-
.hope-container {
display: flex;
gap: @fullMargin;
@@ -371,28 +296,6 @@ div.daggerheart.views.multiclass {
}
}
}
-
- .roll-dialog-experience-container {
- display: flex;
- align-items: flex-start;
- flex-wrap: wrap;
- gap: @halfMargin;
- flex: 1;
- height: 100%;
-
- .experience-chip {
- opacity: 0.6;
- border-radius: 16px;
- width: calc(50% - 4px);
- white-space: nowrap;
-
- &.active,
- &:hover {
- opacity: 1;
- background: var(--button-hover-background-color);
- }
- }
- }
}
}
diff --git a/styles/daggerheart.css b/styles/daggerheart.css
index 01689471..fcae3193 100755
--- a/styles/daggerheart.css
+++ b/styles/daggerheart.css
@@ -2099,74 +2099,6 @@ div.daggerheart.views.multiclass {
.daggerheart.views.roll-selection #roll-selection-costSelection footer {
display: none;
}
-.daggerheart.views.roll-selection .roll-dialog-container .disadvantage,
-.daggerheart.views.roll-selection .roll-dialog-container .advantage {
- border: 2px solid #708090;
- border-radius: 6px;
- display: flex;
- align-items: center;
- padding: 4px;
- margin-bottom: 6px;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .disadvantage.selected,
-.daggerheart.views.roll-selection .roll-dialog-container .advantage.selected {
- filter: drop-shadow(0px 0px 3px red);
-}
-.daggerheart.views.roll-selection .roll-dialog-container .disadvantage input,
-.daggerheart.views.roll-selection .roll-dialog-container .advantage input {
- border: 0;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .disadvantage button,
-.daggerheart.views.roll-selection .roll-dialog-container .advantage button {
- flex: 0;
- border-radius: 50%;
- height: 20px;
- width: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 2px 0 2px 4px;
- padding: 12px;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .disadvantage button i,
-.daggerheart.views.roll-selection .roll-dialog-container .advantage button i {
- margin: 0;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: 4px;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip {
- border: 1px solid black;
- border-radius: 6px;
- min-width: calc(33% - 2px);
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 4px;
- cursor: pointer;
- padding: 4px;
- background: grey;
- overflow: hidden;
- font-weight: bold;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.hover {
- filter: drop-shadow(0 0 3px red);
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip span {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.selected {
- background: green;
-}
-.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.selected span {
- filter: drop-shadow(0 0 3px gold);
-}
.daggerheart.views.roll-selection .roll-dialog-container .hope-container {
display: flex;
gap: 8px;
@@ -2217,25 +2149,6 @@ div.daggerheart.views.multiclass {
.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .advantage-container .advantage-button:hover {
background: var(--button-hover-background-color);
}
-.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container {
- display: flex;
- align-items: flex-start;
- flex-wrap: wrap;
- gap: 4px;
- flex: 1;
- height: 100%;
-}
-.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip {
- opacity: 0.6;
- border-radius: 16px;
- width: calc(50% - 4px);
- white-space: nowrap;
-}
-.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip.active,
-.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip:hover {
- opacity: 1;
- background: var(--button-hover-background-color);
-}
.daggerheart.views.multiclass .multiclass-container {
margin-bottom: 16px;
}
@@ -3708,16 +3621,16 @@ div.daggerheart.views.multiclass {
.daggerheart.dh-style.setting .trait-array-container .trait-array-item input {
text-align: center;
}
-.themed.theme-dark .application.sheet.dh-style .character-header-sheet .trait,
-.themed.theme-dark.application.sheet.dh-style .character-header-sheet .trait,
-body.theme-dark .application .character-header-sheet .trait,
-body.theme-dark.application .character-header-sheet .trait {
+.themed.theme-dark .application.daggerheart.sheet.dh-style .character-header-sheet .trait,
+.themed.theme-dark.application.daggerheart.sheet.dh-style .character-header-sheet .trait,
+body.theme-dark .application.daggerheart .character-header-sheet .trait,
+body.theme-dark.application.daggerheart .character-header-sheet .trait {
background: url(../assets/svg/trait-shield.svg) no-repeat;
}
-.themed.theme-light .application.sheet.dh-style .character-header-sheet .trait,
-.themed.theme-light.application.sheet.dh-style .character-header-sheet .trait,
-body.theme-light .application .character-header-sheet .trait,
-body.theme-light.application .character-header-sheet .trait {
+.themed.theme-light .application.daggerheart.sheet.dh-style .character-header-sheet .trait,
+.themed.theme-light.application.daggerheart.sheet.dh-style .character-header-sheet .trait,
+body.theme-light .application.daggerheart .character-header-sheet .trait,
+body.theme-light.application.daggerheart .character-header-sheet .trait {
background: url('../assets/svg/trait-shield-light.svg') no-repeat;
}
.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet {
@@ -3880,28 +3793,28 @@ body.theme-light.application .character-header-sheet .trait {
font-size: 20px;
text-align: center;
}
-.themed.theme-dark .application.sheet.dh-style .character-sidebar-sheet,
-.themed.theme-dark.application.sheet.dh-style .character-sidebar-sheet,
-body.theme-dark .application .character-sidebar-sheet,
-body.theme-dark.application .character-sidebar-sheet {
+.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet,
+.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet,
+body.theme-dark .application.daggerheart .character-sidebar-sheet,
+body.theme-dark.application.daggerheart .character-sidebar-sheet {
background-image: url('../assets/parchments/dh-parchment-dark.png');
}
-.themed.theme-dark .application.sheet.dh-style .character-sidebar-sheet .experience-value,
-.themed.theme-dark.application.sheet.dh-style .character-sidebar-sheet .experience-value,
-body.theme-dark .application .character-sidebar-sheet .experience-value,
-body.theme-dark.application .character-sidebar-sheet .experience-value {
+.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value,
+.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value,
+body.theme-dark .application.daggerheart .character-sidebar-sheet .experience-value,
+body.theme-dark.application.daggerheart .character-sidebar-sheet .experience-value {
background: url(../assets/svg/experience-shield.svg) no-repeat;
}
-.themed.theme-light .application.sheet.dh-style .character-sidebar-sheet,
-.themed.theme-light.application.sheet.dh-style .character-sidebar-sheet,
-body.theme-light .application .character-sidebar-sheet,
-body.theme-light.application .character-sidebar-sheet {
+.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet,
+.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet,
+body.theme-light .application.daggerheart .character-sidebar-sheet,
+body.theme-light.application.daggerheart .character-sidebar-sheet {
background: transparent;
}
-.themed.theme-light .application.sheet.dh-style .character-sidebar-sheet .experience-value,
-.themed.theme-light.application.sheet.dh-style .character-sidebar-sheet .experience-value,
-body.theme-light .application .character-sidebar-sheet .experience-value,
-body.theme-light.application .character-sidebar-sheet .experience-value {
+.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value,
+.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value,
+body.theme-light .application.daggerheart .character-sidebar-sheet .experience-value,
+body.theme-light.application.daggerheart .character-sidebar-sheet .experience-value {
background: url('../assets/svg/experience-shield-light.svg') no-repeat;
}
.application.sheet.dh-style .character-sidebar-sheet {
@@ -4825,16 +4738,16 @@ body.theme-light.application .character-sidebar-sheet .experience-value {
align-items: center;
padding: 0 20px;
}
-.themed.theme-dark .application.sheet.dh-style.environment,
-.themed.theme-dark.application.sheet.dh-style.environment,
-body.theme-dark .application.environment,
-body.theme-dark.application.environment {
+.themed.theme-dark .application.daggerheart.sheet.dh-style.environment,
+.themed.theme-dark.application.daggerheart.sheet.dh-style.environment,
+body.theme-dark .application.daggerheart.environment,
+body.theme-dark.application.daggerheart.environment {
background-image: url('../assets/parchments/dh-parchment-dark.png');
}
-.themed.theme-light .application.sheet.dh-style.environment,
-.themed.theme-light.application.sheet.dh-style.environment,
-body.theme-light .application.environment,
-body.theme-light.application.environment {
+.themed.theme-light .application.daggerheart.sheet.dh-style.environment,
+.themed.theme-light.application.daggerheart.sheet.dh-style.environment,
+body.theme-light .application.daggerheart.environment,
+body.theme-light.application.daggerheart.environment {
background: url('../assets/parchments/dh-parchment-light.png');
}
.application.sheet.daggerheart.actor.dh-style.environment .tab {
@@ -5282,16 +5195,16 @@ body.theme-light.application.environment {
.theme-light .application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value {
background: url('../assets/svg/experience-shield-light.svg') no-repeat;
}
-.themed.theme-dark .application.sheet.dh-style.companion,
-.themed.theme-dark.application.sheet.dh-style.companion,
-body.theme-dark .application.companion,
-body.theme-dark.application.companion {
+.themed.theme-dark .application.daggerheart.sheet.dh-style.companion,
+.themed.theme-dark.application.daggerheart.sheet.dh-style.companion,
+body.theme-dark .application.daggerheart.companion,
+body.theme-dark.application.daggerheart.companion {
background-image: url('../assets/parchments/dh-parchment-dark.png');
}
-.themed.theme-light .application.sheet.dh-style.companion,
-.themed.theme-light.application.sheet.dh-style.companion,
-body.theme-light .application.companion,
-body.theme-light.application.companion {
+.themed.theme-light .application.daggerheart.sheet.dh-style.companion,
+.themed.theme-light.application.daggerheart.sheet.dh-style.companion,
+body.theme-light .application.daggerheart.companion,
+body.theme-light.application.daggerheart.companion {
background: url('../assets/parchments/dh-parchment-light.png');
}
.application.sheet.daggerheart.actor.dh-style.adversary .window-content {
@@ -5376,6 +5289,111 @@ body.theme-light.application.companion {
justify-content: center;
gap: 10px;
}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section {
+ display: flex;
+ gap: 60px;
+ justify-content: center;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+ width: 120px;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-icon {
+ width: 70px;
+ height: 70px;
+ object-fit: contain;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ height: 32px;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select .label {
+ font-family: 'Cinzel', serif;
+ font-style: normal;
+ font-weight: 700;
+ font-size: 16px;
+ line-height: 19px;
+ color: light-dark(#222, #efe6d8);
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container {
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip {
+ display: flex;
+ align-items: center;
+ border-radius: 5px;
+ width: fit-content;
+ gap: 5px;
+ cursor: pointer;
+ padding: 5px;
+ background: light-dark(#18162e10, #f3c26710);
+ color: light-dark(#18162e, #f3c267);
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip .label {
+ font-family: 'Montserrat', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 17px;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip.selected {
+ background: light-dark(#18162e40, #f3c26740);
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip,
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip {
+ display: flex;
+ align-items: center;
+ border-radius: 5px;
+ width: fit-content;
+ gap: 5px;
+ cursor: pointer;
+ padding: 5px;
+ transition: all 0.3s ease;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip .label,
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip .label {
+ font-family: 'Montserrat', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 17px;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip {
+ background: #40a64010;
+ color: #40a640;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip.selected {
+ color: #efe6d8;
+ background: linear-gradient(151.21deg, #40a640 7.21%, #011b01 92.79%);
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip {
+ background: #e54e4e10;
+ color: #e54e4e;
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip.selected {
+ color: #efe6d8;
+ background: linear-gradient(151.21deg, #e54e4e 7.21%, #3c0000 92.79%);
+}
+.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .formula-label {
+ font-family: 'Montserrat', sans-serif;
+ font-style: normal;
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 17px;
+ color: light-dark(#222, #efe6d8);
+}
@keyframes glow {
0% {
box-shadow: 0 0 1px 1px #f3c267;
@@ -5469,17 +5487,17 @@ body.theme-light.application.companion {
* @param {Rules} @darkRules - Styles to apply when `.theme-dark` is present
* @param {Rules} @lightRules - Styles to apply when `.theme-light` is present
*/
-.themed.theme-dark .application.sheet.dh-style,
-.themed.theme-dark.application.sheet.dh-style,
-body.theme-dark .application,
-body.theme-dark.application {
+.themed.theme-dark .application.daggerheart.sheet.dh-style,
+.themed.theme-dark.application.daggerheart.sheet.dh-style,
+body.theme-dark .application.daggerheart,
+body.theme-dark.application.daggerheart {
background: rgba(24, 22, 46, 0.33);
backdrop-filter: blur(9px);
}
-.themed.theme-light .application.sheet.dh-style,
-.themed.theme-light.application.sheet.dh-style,
-body.theme-light .application,
-body.theme-light.application {
+.themed.theme-light .application.daggerheart.sheet.dh-style,
+.themed.theme-light.application.daggerheart.sheet.dh-style,
+body.theme-light .application.daggerheart,
+body.theme-light.application.daggerheart {
background: url('../assets/parchments/dh-parchment-light.png') no-repeat center;
}
.application.sheet.dh-style {
@@ -5527,18 +5545,18 @@ body.theme-light.application {
.application.sheet.dh-style:not(.minimized) .window-content {
opacity: 1;
}
-.themed.theme-dark .application.sheet.dh-style.dialog,
-.themed.theme-dark.application.sheet.dh-style.dialog,
-body.theme-dark .application.dialog,
-body.theme-dark.application.dialog {
+.themed.theme-dark .application.daggerheart.sheet.dh-style.dialog,
+.themed.theme-dark.application.daggerheart.sheet.dh-style.dialog,
+body.theme-dark .application.daggerheart.dialog,
+body.theme-dark.application.daggerheart.dialog {
background-image: url('../assets/parchments/dh-parchment-dark.png');
background-repeat: no-repeat;
background-position: center;
}
-.themed.theme-light .application.sheet.dh-style.dialog,
-.themed.theme-light.application.sheet.dh-style.dialog,
-body.theme-light .application.dialog,
-body.theme-light.application.dialog {
+.themed.theme-light .application.daggerheart.sheet.dh-style.dialog,
+.themed.theme-light.application.daggerheart.sheet.dh-style.dialog,
+body.theme-light .application.daggerheart.dialog,
+body.theme-light.application.daggerheart.dialog {
background-image: url('../assets/parchments/dh-parchment-light.png');
background-repeat: no-repeat;
background-position: center;
diff --git a/styles/daggerheart.less b/styles/daggerheart.less
index f946c344..ebecdc95 100755
--- a/styles/daggerheart.less
+++ b/styles/daggerheart.less
@@ -53,6 +53,8 @@
@import './less/items/domainCard.less';
@import './less/items/class.less';
+@import './less/dialog/dice-roll/roll-selection.less';
+
@import './less/utils/colors.less';
@import './less/utils/fonts.less';
diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less
new file mode 100644
index 00000000..b2f05dc2
--- /dev/null
+++ b/styles/less/dialog/dice-roll/roll-selection.less
@@ -0,0 +1,128 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.daggerheart.dialog.dh-style.views.roll-selection {
+ .roll-dialog-container {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+
+ .dices-section {
+ display: flex;
+ gap: 60px;
+ justify-content: center;
+
+ .dice-option {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+ width: 120px;
+
+ .dice-icon {
+ width: 70px;
+ height: 70px;
+ object-fit: contain;
+ }
+ .dice-select {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ height: 32px;
+
+ .label {
+ font-family: @font-subtitle;
+ font-style: normal;
+ font-weight: 700;
+ font-size: 16px;
+ line-height: 19px;
+
+ color: light-dark(@dark, @beige);
+ }
+ }
+ }
+ }
+
+ .experience-container {
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+
+ .experience-chip {
+ display: flex;
+ align-items: center;
+ border-radius: 5px;
+ width: fit-content;
+ gap: 5px;
+ cursor: pointer;
+ padding: 5px;
+ background: light-dark(@dark-blue-10, @golden-10);
+ color: light-dark(@dark-blue, @golden);
+
+ .label {
+ font-family: @font-body;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 17px;
+ }
+
+ &.selected {
+ background: light-dark(@dark-blue-40, @golden-40);
+ }
+ }
+ }
+
+ .modifier-container {
+ .advantage-chip,
+ .disadvantage-chip {
+ display: flex;
+ align-items: center;
+ border-radius: 5px;
+ width: fit-content;
+ gap: 5px;
+ cursor: pointer;
+ padding: 5px;
+ transition: all 0.3s ease;
+
+ .label {
+ font-family: @font-body;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 17px;
+ }
+ }
+
+ .advantage-chip {
+ background: @green-10;
+ color: @green;
+
+ &.selected {
+ color: @beige;
+ background: @gradient-green;
+ }
+ }
+
+ .disadvantage-chip {
+ background: @red-10;
+ color: @red;
+
+ &.selected {
+ color: @beige;
+ background: @gradient-red;
+ }
+ }
+ }
+
+ .formula-label {
+ font-family: @font-body;
+ font-style: normal;
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 17px;
+
+ color: light-dark(@dark, @beige);
+ }
+ }
+}
diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less
index 7ac572b9..57a6b018 100755
--- a/styles/less/utils/colors.less
+++ b/styles/less/utils/colors.less
@@ -1,22 +1,47 @@
@primary-blue: #1488cc;
@secondary-blue: #2b32b2;
+
@golden: #f3c267;
-@golden-40: #f3c26740;
-@dark-blue-40: #18162e40;
@golden-10: #f3c26710;
-@dark-blue-10: #18162e10;
-@dark-blue-50: #18162e50;
+@golden-40: #f3c26740;
+
+@red: #e54e4e;
+@red-10: #e54e4e10;
+@red-40: #e54e4e40;
+
+@dark-red: #3c0000;
+@dark-red-10: #3c000010;
+@dark-red-40: #3c000040;
+
+@green: #40a640;
+@green-10: #40a64010;
+@green-40: #40a64040;
+
+@dark-green: #011b01;
+@dark-green-10: #011b0110;
+@dark-green-40: #011b0140;
+
@dark-blue: #18162e;
+@dark-blue-10: #18162e10;
+@dark-blue-40: #18162e40;
+@dark-blue-50: #18162e50;
+@semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
+
+@dark: #222;
+@dark-15: #22222215;
+
@deep-black: #0e0d15;
+
@beige: #efe6d8;
@beige-15: #efe6d815;
@beige-50: #efe6d850;
-@dark-blue: rgb(24, 22, 46);
-@semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
-@dark: #222;
-@dark-15: #22222215;
+
@light-black: rgba(0, 0, 0, 0.3);
@soft-shadow: rgba(0, 0, 0, 0.05);
+
+@gradient-green: linear-gradient(151.21deg, @green 7.21%, @dark-green 92.79%);
+@gradient-red: linear-gradient(151.21deg, @red 7.21%, @dark-red 92.79%);
+
@gradient-hp: linear-gradient(15deg, rgb(70, 20, 10) 0%, rgb(190, 0, 0) 42%, rgb(252, 176, 69) 100%);
@gradient-stress: linear-gradient(15deg, rgb(130, 59, 1) 0%, rgb(252, 142, 69) 65%, rgb(190, 0, 0) 100%);
diff --git a/styles/less/utils/mixin.less b/styles/less/utils/mixin.less
index c30a5535..39c2bee0 100644
--- a/styles/less/utils/mixin.less
+++ b/styles/less/utils/mixin.less
@@ -5,18 +5,18 @@
*/
.appTheme(@darkRules, @lightRules) {
// Dark theme selectors
- .themed.theme-dark .application.sheet.dh-style,
- .themed.theme-dark.application.sheet.dh-style,
- body.theme-dark .application,
- body.theme-dark.application {
+ .themed.theme-dark .application.daggerheart.sheet.dh-style,
+ .themed.theme-dark.application.daggerheart.sheet.dh-style,
+ body.theme-dark .application.daggerheart,
+ body.theme-dark.application.daggerheart {
@darkRules();
}
// Light theme selectors
- .themed.theme-light .application.sheet.dh-style,
- .themed.theme-light.application.sheet.dh-style,
- body.theme-light .application,
- body.theme-light.application {
+ .themed.theme-light .application.daggerheart.sheet.dh-style,
+ .themed.theme-light.application.daggerheart.sheet.dh-style,
+ body.theme-light .application.daggerheart,
+ body.theme-light.application.daggerheart {
@lightRules();
}
}
diff --git a/templates/characterCreation/tabs/setup.hbs b/templates/characterCreation/tabs/setup.hbs
index 4d6e638c..6dd04345 100644
--- a/templates/characterCreation/tabs/setup.hbs
+++ b/templates/characterCreation/tabs/setup.hbs
@@ -74,7 +74,7 @@
{{#each experience.values as |experience id|}}
-
{{signedNumber this.value}}
+
{{numberFormat this.value sign=true}}
{{/each}}
diff --git a/templates/dialogs/costSelection.hbs b/templates/dialogs/dice-roll/costSelection.hbs
similarity index 100%
rename from templates/dialogs/costSelection.hbs
rename to templates/dialogs/dice-roll/costSelection.hbs
diff --git a/templates/dialogs/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs
similarity index 100%
rename from templates/dialogs/damageSelection.hbs
rename to templates/dialogs/dice-roll/damageSelection.hbs
diff --git a/templates/dialogs/dice-roll/header.hbs b/templates/dialogs/dice-roll/header.hbs
new file mode 100644
index 00000000..462408f6
--- /dev/null
+++ b/templates/dialogs/dice-roll/header.hbs
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs
new file mode 100644
index 00000000..fb0b2074
--- /dev/null
+++ b/templates/dialogs/dice-roll/rollSelection.hbs
@@ -0,0 +1,126 @@
+
+ {{#if @root.hasRoll}}
+
+ {{#unless @root.isLite}}
+
+ {{#if (eq @root.rollType 'D20Roll')}}
+
+
+
+
+ {{selectOptions diceOptions selected=@root.roll.d20.denomination}}
+
+
+
+ {{#if @root.advantage}}
+ {{#if (eq @root.advantage 1)}}
+
+
+
+ Advantage
+
+
+ {{else if (eq @root.advantage -1)}}
+
+
+
+ Disdvantage
+
+
+ {{/if}}
+ {{/if}}
+ {{/if}}
+ {{#if (eq @root.rollType 'DualityRoll')}}
+
+
+
+ Hope
+
+ {{selectOptions diceOptions selected=@root.roll.dHope.denomination}}
+
+
+
+
+
+
+ Fear
+
+ {{selectOptions diceOptions selected=@root.roll.dFear.denomination}}
+
+
+
+ {{#if @root.advantage}}
+ {{#if (eq @root.advantage 1)}}
+
+
+
+ Advantage
+
+
+ {{else if (eq @root.advantage -1)}}
+
+
+
+ Disdvantage
+
+
+ {{/if}}
+ {{/if}}
+ {{/if}}
+
+
+
+ Experiences
+ {{#each experiences}}
+ {{#if name}}
+
+ {{#if (includes ../selectedExperiences id)}}
+
+ {{else}}
+
+ {{/if}}
+ {{#if (eq @root.rollType 'D20Roll')}}
+ {{name}} +{{modifier}}
+ {{else}}
+ {{name}} +{{value}}
+ {{/if}}
+
+ {{/if}}
+ {{/each}}
+
+
+ Modifiers
+
+
+ {{#if (eq advantage 1)}}
+
+ {{else}}
+
+ {{/if}}
+ {{localize "DAGGERHEART.General.Advantage.Full"}}
+
+
+ {{#if (eq advantage -1)}}
+
+ {{else}}
+
+ {{/if}}
+ {{localize "DAGGERHEART.General.Disadvantage.Full"}}
+
+ {{#unless (eq @root.rollType 'D20Roll')}}
+
+ {{selectOptions diceOptions selected=@root.roll.dAdvantage.denomination}}
+
+ {{/unless}}
+
+
+
+ {{/unless}}
+
Formula: {{@root.formula}}
+
+
+ Roll
+
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/templates/dialogs/npcRollSelection.hbs b/templates/dialogs/npcRollSelection.hbs
deleted file mode 100644
index 02f5238b..00000000
--- a/templates/dialogs/npcRollSelection.hbs
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
d20
-
-
- {{localize "DAGGERHEART.General.Advantage.Full"}}
- {{localize "DAGGERHEART.General.Disadvantage.Full"}}
-
-
-
- {{#each this.experiences as |experience|}}
- {{experience.name}} {{experience.value}}
- {{/each}}
-
-
-
-
\ No newline at end of file
diff --git a/templates/dialogs/rollSelection.hbs b/templates/dialogs/rollSelection.hbs
deleted file mode 100644
index 98b6c91b..00000000
--- a/templates/dialogs/rollSelection.hbs
+++ /dev/null
@@ -1,81 +0,0 @@
-
- {{#if @root.hasRoll}}
-
-
-
- {{!--
--}}
-
{{@root.formula}}
-
- {{#unless @root.isLite}}
-
- {{#each experiences}}
- {{#if name}}
-
- {{name}}
- +{{value}}
-
- {{/if}}
- {{/each}}
-
-
- {{localize "DAGGERHEART.General.Advantage.Full"}}
- {{localize "DAGGERHEART.General.Disadvantage.Full"}}
-
- {{#if (eq @root.rollType 'D20Roll')}}
-
-
- {{selectOptions diceOptions selected=@root.roll.d20.denomination}}
-
-
- {{/if}}
- {{#if (eq @root.rollType 'DualityRoll')}}
-
-
Hope Dice
-
- {{selectOptions diceOptions selected=@root.roll.dHope.denomination}}
-
-
-
-
Fear Dice
-
- {{selectOptions diceOptions selected=@root.roll.dFear.denomination}}
-
-
- {{#if roll.advantage}}
-
-
Adv/Disadv Dice
-
- {{selectOptions diceOptions selected=@root.roll.dAdvantage.denomination}}
-
-
- {{/if}}
- {{/if}}
-
-
-
- {{/unless}}
- {{!-- {{#if (not isNpc)}} --}}
- {{!--
-
--}}
- {{!-- {{/if}} --}}
-
-
- {{/if}}
-
-
\ No newline at end of file
diff --git a/templates/levelup/tabs/selections.hbs b/templates/levelup/tabs/selections.hbs
index d397fa80..9d1d00b8 100644
--- a/templates/levelup/tabs/selections.hbs
+++ b/templates/levelup/tabs/selections.hbs
@@ -12,7 +12,7 @@
-
{{signedNumber this.modifier}}
+
{{numberFormat this.modifier sign=true}}
{{#if this.name}}
{{/if}}
diff --git a/templates/levelup/tabs/summary.hbs b/templates/levelup/tabs/summary.hbs
index 4ed4438f..dc7e2a47 100644
--- a/templates/levelup/tabs/summary.hbs
+++ b/templates/levelup/tabs/summary.hbs
@@ -48,7 +48,7 @@
{{localize "DAGGERHEART.Application.LevelUp.summary.newExperiences"}}
{{#each this.achievements.experiences.values}}
-
{{this.name}} {{signedNumber this.modifier}}
+
{{this.name}} {{numberFormat this.modifier sign=true}}
{{/each}}
@@ -125,7 +125,7 @@
{{localize "DAGGERHEART.Application.LevelUp.summary.experienceIncreases"}}
{{#each this.advancements.experiences}}
-
{{this.name}} {{signedNumber this.modifier}}
+
{{this.name}} {{numberFormat this.modifier sign=true}}
{{/each}}
diff --git a/templates/sheets/actors/companion/tempMain.hbs b/templates/sheets/actors/companion/tempMain.hbs
index 810d48db..f1f315ed 100644
--- a/templates/sheets/actors/companion/tempMain.hbs
+++ b/templates/sheets/actors/companion/tempMain.hbs
@@ -17,7 +17,7 @@
{{#each source.system.experiences as |experience key|}}
-
{{signedNumber experience.value}}
+
{{numberFormat experience.value sign=true}}
{{/each}}
diff --git a/tools/create-symlink.mjs b/tools/create-symlink.mjs
index 0c8804c6..fd828c73 100644
--- a/tools/create-symlink.mjs
+++ b/tools/create-symlink.mjs
@@ -2,8 +2,6 @@ import fs from 'fs';
import path from 'path';
import readline from 'readline';
-console.log('Reforging Symlinks');
-
const askQuestion = question => {
const rl = readline.createInterface({
input: process.stdin,