mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Embedding Duality Rolls (#52)
* Added DualityRoll direct rolls in chat * Added button render to renderJournalEntryPageProseMirrorSheet and renderHandlebarsApplication * Hope and Fear dice totals are now properly added together * Added Colorful/Normal DualityRoll color settings
This commit is contained in:
parent
cf51153432
commit
d1a0a9ab24
19 changed files with 1192 additions and 1264 deletions
137
daggerheart.mjs
137
daggerheart.mjs
|
|
@ -10,6 +10,9 @@ import DhpChatLog from './module/ui/chatLog.mjs';
|
|||
import DhpPlayers from './module/ui/players.mjs';
|
||||
import DhpRuler from './module/ui/ruler.mjs';
|
||||
import DhpTokenRuler from './module/ui/tokenRuler.mjs';
|
||||
import { dualityRollEnricher, getDualityMessage } from './module/enrichers/DualityRollEnricher.mjs';
|
||||
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
||||
import { abilities } from './module/config/actorConfig.mjs';
|
||||
|
||||
globalThis.SYSTEM = SYSTEM;
|
||||
|
||||
|
|
@ -21,6 +24,11 @@ Hooks.once('init', () => {
|
|||
documents
|
||||
};
|
||||
|
||||
CONFIG.TextEditor.enrichers.push({
|
||||
pattern: /\[\[\/dr\s?(.*?)\]\]/g,
|
||||
enricher: dualityRollEnricher
|
||||
});
|
||||
|
||||
CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({
|
||||
...x,
|
||||
name: game.i18n.localize(x.name)
|
||||
|
|
@ -90,7 +98,6 @@ Hooks.once('init', () => {
|
|||
game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent);
|
||||
|
||||
registerDHPSettings();
|
||||
|
||||
RegisterHandlebarsHelpers.registerHelpers();
|
||||
|
||||
return preloadHandlebarsTemplates();
|
||||
|
|
@ -122,6 +129,134 @@ Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => {
|
|||
}
|
||||
});
|
||||
|
||||
const renderDualityButton = async event => {
|
||||
const button = event.currentTarget;
|
||||
const attributeValue = button.dataset.attribute?.toLowerCase();
|
||||
|
||||
const target = getCommandTarget();
|
||||
if (!target) return;
|
||||
|
||||
const rollModifier = attributeValue ? target.system.attributes[attributeValue].data.value : null;
|
||||
const { roll, hope, fear, advantage, disadvantage, modifiers } = await target.diceRoll({
|
||||
title: button.dataset.label,
|
||||
value: rollModifier
|
||||
});
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const msgData = {
|
||||
type: 'dualityRoll',
|
||||
sound: CONFIG.sounds.dice,
|
||||
system: {
|
||||
title: button.dataset.label,
|
||||
origin: target.id,
|
||||
roll: roll._formula,
|
||||
modifiers: modifiers,
|
||||
hope: hope,
|
||||
fear: fear,
|
||||
advantage: advantage,
|
||||
disadvantage: disadvantage
|
||||
},
|
||||
user: game.user.id,
|
||||
content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
|
||||
rolls: [roll]
|
||||
};
|
||||
|
||||
await cls.create(msgData);
|
||||
};
|
||||
|
||||
Hooks.on('renderChatMessageHTML', (_, element) => {
|
||||
element
|
||||
.querySelectorAll('.duality-roll-button')
|
||||
.forEach(element => element.addEventListener('click', renderDualityButton));
|
||||
});
|
||||
|
||||
Hooks.on('renderJournalEntryPageProseMirrorSheet', (_, element) => {
|
||||
element
|
||||
.querySelectorAll('.duality-roll-button')
|
||||
.forEach(element => element.addEventListener('click', renderDualityButton));
|
||||
});
|
||||
|
||||
Hooks.on('renderHandlebarsApplication', (_, element) => {
|
||||
element
|
||||
.querySelectorAll('.duality-roll-button')
|
||||
.forEach(element => element.addEventListener('click', renderDualityButton));
|
||||
});
|
||||
|
||||
Hooks.on('chatMessage', (_, message) => {
|
||||
if (message.startsWith('/dr')) {
|
||||
const rollCommand = rollCommandToJSON(message.replace(/\/dr\s?/, ''));
|
||||
if (!rollCommand) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.DualityParsing'));
|
||||
return false;
|
||||
}
|
||||
|
||||
const attributeValue = rollCommand.attribute?.toLowerCase();
|
||||
|
||||
// Target not required if an attribute is not used.
|
||||
const target = attributeValue ? getCommandTarget() : undefined;
|
||||
if (target || !attributeValue) {
|
||||
new Promise(async (resolve, reject) => {
|
||||
const attribute = target ? target.system.attributes[attributeValue] : undefined;
|
||||
if (attributeValue && !attribute) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.AttributeFaulty'));
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const title = attributeValue
|
||||
? game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
|
||||
ability: game.i18n.localize(abilities[attributeValue].label)
|
||||
})
|
||||
: game.i18n.localize('DAGGERHEART.General.Duality');
|
||||
|
||||
const hopeAndFearRoll = `1${rollCommand.hope ?? 'd12'}+1${rollCommand.fear ?? 'd12'}`;
|
||||
const advantageRoll = `${rollCommand.advantage && !rollCommand.disadvantage ? '+d6' : rollCommand.disadvantage && !rollCommand.advantage ? '-d6' : ''}`;
|
||||
const attributeRoll = `${attribute?.data?.value ? `${attribute.data.value > 0 ? `+${attribute.data.value}` : `${attribute.data.value}`}` : ''}`;
|
||||
const roll = new Roll(`${hopeAndFearRoll}${advantageRoll}${attributeRoll}`);
|
||||
await roll.evaluate();
|
||||
resolve({
|
||||
roll,
|
||||
attribute: attribute
|
||||
? {
|
||||
value: attribute.data.value,
|
||||
label: `${game.i18n.localize(abilities[attributeValue].label)} ${attribute.data.value >= 0 ? `+` : `-`}${attribute.data.value}`
|
||||
}
|
||||
: undefined,
|
||||
title
|
||||
});
|
||||
}).then(({ roll, attribute, title }) => {
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const msgData = {
|
||||
type: 'dualityRoll',
|
||||
sound: CONFIG.sounds.dice,
|
||||
system: {
|
||||
title: title,
|
||||
origin: target?.id,
|
||||
roll: roll._formula,
|
||||
modifiers: attribute ? [attribute] : [],
|
||||
hope: { dice: rollCommand.hope ?? 'd12', value: roll.dice[0].total },
|
||||
fear: { dice: rollCommand.fear ?? 'd12', value: roll.dice[1].total },
|
||||
advantage:
|
||||
rollCommand.advantage && !rollCommand.disadvantage
|
||||
? { dice: 'd6', value: roll.dice[2].total }
|
||||
: undefined,
|
||||
disadvantage:
|
||||
rollCommand.disadvantage && !rollCommand.advantage
|
||||
? { dice: 'd6', value: roll.dice[2].total }
|
||||
: undefined
|
||||
},
|
||||
user: game.user.id,
|
||||
content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
|
||||
rolls: [roll]
|
||||
};
|
||||
|
||||
cls.create(msgData);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
const preloadHandlebarsTemplates = async function () {
|
||||
return foundry.applications.handlebars.loadTemplates([
|
||||
'systems/daggerheart/templates/sheets/parts/attributes.hbs',
|
||||
|
|
|
|||
18
lang/en.json
18
lang/en.json
|
|
@ -77,6 +77,14 @@
|
|||
"Name": "Enable Range Measurement",
|
||||
"Hint": "Enable measuring of ranges with the ruler according to set distances."
|
||||
}
|
||||
},
|
||||
"DualityRollColor": {
|
||||
"Name": "Duality Roll Colour Scheme",
|
||||
"Hint": "The display type for Duality Rolls",
|
||||
"Options": {
|
||||
"Colorful": "Colorful",
|
||||
"Normal": "Normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Notification": {
|
||||
|
|
@ -92,13 +100,19 @@
|
|||
"LacksDomain": "Your character doesn't have the domain of the card!",
|
||||
"MaxLoadoutReached": "You can't have any more domain cards at this level!",
|
||||
"DuplicateDomainCard": "You already have a domain card with that name!",
|
||||
"ActionRequiresTarget": "The action requires at least one target"
|
||||
"ActionRequiresTarget": "The action requires at least one target",
|
||||
"NoAssignedPlayerCharacter": "You have no assigned character.",
|
||||
"NoSelectedToken": "You have no selected token",
|
||||
"OnlyUseableByPC": "This can only be used with a PC token",
|
||||
"DualityParsing": "Duality roll not properly formated",
|
||||
"AttributeFaulty": "The supplied Attribute doesn't exist"
|
||||
}
|
||||
},
|
||||
"General": {
|
||||
"OpenBetaDisclaimer": "Daggerheart Open Beta {version}",
|
||||
"Hope": "Hope",
|
||||
"Fear": "Fear",
|
||||
"Duality": "Duality",
|
||||
"Check": "{check} Check",
|
||||
"CriticalSuccess": "Critical Success",
|
||||
"Advantage": {
|
||||
"Full": "Advantage",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import { DualityRollColor } from '../config/settingsConfig.mjs';
|
||||
import DhpDualityRoll from '../data/dualityRoll.mjs';
|
||||
|
||||
export default class DhpChatMesssage extends ChatMessage {
|
||||
async renderHTML() {
|
||||
if (
|
||||
|
|
@ -9,6 +12,20 @@ export default class DhpChatMesssage extends ChatMessage {
|
|||
this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
|
||||
}
|
||||
|
||||
return super.renderHTML();
|
||||
/* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */
|
||||
const html = await super.renderHTML();
|
||||
if (
|
||||
this.type === 'dualityRoll' &&
|
||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.DualityRollColor) ===
|
||||
DualityRollColor.colorful.value
|
||||
) {
|
||||
html.classList.add('duality');
|
||||
const dualityResult = this.system.dualityResult;
|
||||
if (dualityResult === DhpDualityRoll.dualityResult.hope) html.classList.add('hope');
|
||||
else if (dualityResult === DhpDualityRoll.dualityResult.fear) html.classList.add('fear');
|
||||
else html.classList.add('critical');
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,9 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
}
|
||||
|
||||
static rollDamage() {
|
||||
static rollDamage(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.resolve({
|
||||
rollString: this.getRollString(),
|
||||
bonusDamage: this.data.bonusDamage,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { DualityRollColor } from '../config/settingsConfig.mjs';
|
||||
|
||||
class DhpAutomationSettings extends FormApplication {
|
||||
constructor(object = {}, options = {}) {
|
||||
super(object, options);
|
||||
|
|
@ -213,6 +215,16 @@ export const registerDHPSettings = () => {
|
|||
}
|
||||
});
|
||||
|
||||
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.DualityRollColor, {
|
||||
name: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Name'),
|
||||
hint: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Hint'),
|
||||
scope: 'world',
|
||||
config: true,
|
||||
type: Number,
|
||||
choices: Object.values(DualityRollColor),
|
||||
default: DualityRollColor.colorful.value
|
||||
});
|
||||
|
||||
game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, {
|
||||
name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'),
|
||||
label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,5 +24,17 @@ export const gameSettings = {
|
|||
General: {
|
||||
AbilityArray: 'AbilityArray',
|
||||
RangeMeasurement: 'RangeMeasurement'
|
||||
},
|
||||
DualityRollColor: 'DualityRollColor'
|
||||
};
|
||||
|
||||
export const DualityRollColor = {
|
||||
colorful: {
|
||||
value: 0,
|
||||
label: 'DAGGERHEART.Settings.DualityRollColor.Options.Colorful'
|
||||
},
|
||||
normal: {
|
||||
value: 1,
|
||||
label: 'DAGGERHEART.Settings.DualityRollColor.Options.Normal'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { DualityRollColor } from '../config/settingsConfig.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
const diceField = () =>
|
||||
new fields.SchemaField({
|
||||
|
|
@ -6,6 +8,12 @@ const diceField = () =>
|
|||
});
|
||||
|
||||
export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
||||
static dualityResult = {
|
||||
hope: 1,
|
||||
fear: 2,
|
||||
critical: 3
|
||||
};
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
|
|
@ -57,17 +65,32 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
}
|
||||
|
||||
get total() {
|
||||
const modifiers = this.modifiers.reduce((acc, x) => acc + x.value, 0);
|
||||
const advantage = this.advantage.value
|
||||
? this.advantage.value
|
||||
: this.disadvantage.value
|
||||
? -this.disadvantage.value
|
||||
: 0;
|
||||
return this.highestRoll + advantage + modifiers;
|
||||
return this.diceTotal + advantage + this.modifierTotal.value;
|
||||
}
|
||||
|
||||
get highestRoll() {
|
||||
return Math.max(this.hope.value, this.fear.value);
|
||||
get diceTotal() {
|
||||
return this.hope.value + this.fear.value;
|
||||
}
|
||||
|
||||
get modifierTotal() {
|
||||
const total = this.modifiers.reduce((acc, x) => acc + x.value, 0);
|
||||
return {
|
||||
value: total,
|
||||
label: total > 0 ? `+${total}` : total < 0 ? `-${total}` : ''
|
||||
};
|
||||
}
|
||||
|
||||
get dualityResult() {
|
||||
return this.hope.value > this.fear.value
|
||||
? this.constructor.dualityResult.hope
|
||||
: this.fear.value > this.hope.value
|
||||
? this.constructor.dualityResult.fear
|
||||
: this.constructor.dualityResult.critical;
|
||||
}
|
||||
|
||||
get totalLabel() {
|
||||
|
|
@ -81,6 +104,13 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
return game.i18n.localize(label);
|
||||
}
|
||||
|
||||
get colorful() {
|
||||
return (
|
||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.DualityRollColor) ===
|
||||
DualityRollColor.colorful.value
|
||||
);
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const total = this.total;
|
||||
|
||||
|
|
@ -92,89 +122,3 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
//V1.3
|
||||
// const fields = foundry.data.fields;
|
||||
// const diceField = () => new fields.SchemaField({
|
||||
// dice: new fields.StringField({}),
|
||||
// value: new fields.NumberField({ integer: true}),
|
||||
// });
|
||||
|
||||
// export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
||||
// static defineSchema() {
|
||||
|
||||
// return {
|
||||
// roll: new fields.StringField({}),
|
||||
// modifiers: new fields.ArrayField(new fields.SchemaField({
|
||||
// value: new fields.NumberField({ integer: true }),
|
||||
// label: new fields.StringField({}),
|
||||
// title: new fields.StringField({}),
|
||||
// })),
|
||||
// hope: diceField(),
|
||||
// fear: diceField(),
|
||||
// advantage: diceField(),
|
||||
// disadvantage: diceField(),
|
||||
// advantageSelected: new fields.NumberField({ initial: 0 }),
|
||||
// targets: new fields.ArrayField(new fields.SchemaField({
|
||||
// id: new fields.StringField({}),
|
||||
// name: new fields.StringField({}),
|
||||
// img: new fields.StringField({}),
|
||||
// difficulty: new fields.NumberField({ integer: true, nullable: true }),
|
||||
// evasion: new fields.NumberField({ integer: true }),
|
||||
// hit: new fields.BooleanField({ initial: false }),
|
||||
// })),
|
||||
// damage: new fields.SchemaField({
|
||||
// value: new fields.StringField({}),
|
||||
// type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
|
||||
// bonusDamage: new fields.ArrayField(new fields.SchemaField({
|
||||
// value: new fields.StringField({}),
|
||||
// type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
|
||||
// initiallySelected: new fields.BooleanField(),
|
||||
// appliesOn: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.applyLocations) }, { nullable: true, initial: null }),
|
||||
// description: new fields.StringField({}),
|
||||
// hopeIncrease: new fields.StringField({ nullable: true })
|
||||
// }), { nullable: true, initial: null })
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// get total() {
|
||||
// const modifiers = this.modifiers.reduce((acc, x) => acc+x.value, 0);
|
||||
// const regular = {
|
||||
// normal: this.disadvantage.value ? Math.min(this.disadvantage.value, this.hope.value) + this.fear.value + modifiers : this.hope.value + this.fear.value + modifiers,
|
||||
// alternate: this.advantage.value ? this.advantage.value + this.fear.value + modifiers : null,
|
||||
// };
|
||||
|
||||
// const advantageSolve = this.advantageSelected === 0 ? null : {
|
||||
// normal: this.advantageSelected === 1 ? this.hope.value + this.fear.value + modifiers : this.advantage.value + this.fear.value + modifiers,
|
||||
// alternate: null,
|
||||
// };
|
||||
|
||||
// return advantageSolve ?? regular;
|
||||
// }
|
||||
|
||||
// get totalLabel() {
|
||||
// if(this.advantage.value && this.advantageSelected === 0) return game.i18n.localize("DAGGERHEART.Chat.DualityRoll.AdvantageChooseTitle");
|
||||
|
||||
// const hope = !this.advantage.value || this.advantageSelected === 1 ? this.hope.value : this.advantage.value;
|
||||
// const label = hope > this.fear.value ? "DAGGERHEART.General.Hope" : this.fear.value > hope ? "DAGGERHEART.General.Fear" : "DAGGERHEART.General.CriticalSuccess";
|
||||
|
||||
// return game.i18n.localize(label);
|
||||
// }
|
||||
|
||||
// get dualityDiceStates() {
|
||||
// return {
|
||||
// hope: this.hope.value > this.fear.value ? 'hope' : this.fear.value > this.hope.value ? 'fear' : 'critical',
|
||||
// alternate: this.advantage.value > this.fear.value ? 'hope' : this.fear.value > this.advantage.value ? 'fear' : 'critical',
|
||||
// }
|
||||
// }
|
||||
|
||||
// prepareDerivedData(){
|
||||
// const total = this.total;
|
||||
// if(total.alternate) return false;
|
||||
|
||||
// this.targets.forEach(target => {
|
||||
// target.hit = target.difficulty ? total.normal >= target.difficulty : total.normal >= target.evasion;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -119,7 +119,10 @@ export default class DhpActor extends Actor {
|
|||
const modifiers = [
|
||||
{
|
||||
value: modifier.value ? Number.parseInt(modifier.value) : 0,
|
||||
label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`,
|
||||
label:
|
||||
modifier.value >= 0
|
||||
? `${modifier.title} +${modifier.value}`
|
||||
: `${modifier.title} -${modifier.value}`,
|
||||
title: modifier.title
|
||||
}
|
||||
];
|
||||
|
|
|
|||
36
module/enrichers/DualityRollEnricher.mjs
Normal file
36
module/enrichers/DualityRollEnricher.mjs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { abilities } from '../config/actorConfig.mjs';
|
||||
import { rollCommandToJSON } from '../helpers/utils.mjs';
|
||||
|
||||
export function dualityRollEnricher(match, _options) {
|
||||
const roll = rollCommandToJSON(match[1]);
|
||||
if (!roll) return match[0];
|
||||
|
||||
return getDualityMessage(roll);
|
||||
}
|
||||
|
||||
export function getDualityMessage(roll) {
|
||||
const attributeLabel =
|
||||
roll.attribute && abilities[roll.attribute]
|
||||
? game.i18n.format('DAGGERHEART.General.Check', {
|
||||
check: game.i18n.localize(abilities[roll.attribute].label)
|
||||
})
|
||||
: null;
|
||||
const label = attributeLabel ?? game.i18n.localize('DAGGERHEART.General.Duality');
|
||||
|
||||
const dualityElement = document.createElement('span');
|
||||
dualityElement.innerHTML = `
|
||||
<button class="duality-roll-button"
|
||||
data-label="${label}"
|
||||
data-hope="${roll.hope ?? 'd12'}"
|
||||
data-fear="${roll.fear ?? 'd12'}"
|
||||
${roll.attribute && abilities[roll.attribute] ? `data-attribute="${roll.attribute}"` : ''}
|
||||
${roll.advantage ? 'data-advantage="true"' : ''}
|
||||
${roll.disadvantage ? 'data-disadvantage="true"' : ''}
|
||||
>
|
||||
<i class="fa-solid fa-circle-half-stroke"></i>
|
||||
${label}
|
||||
</button>
|
||||
`;
|
||||
|
||||
return dualityElement;
|
||||
}
|
||||
|
|
@ -22,17 +22,6 @@ const getCompendiumOptions = async compendium => {
|
|||
};
|
||||
|
||||
export const getWidthOfText = (txt, fontsize, allCaps, bold) => {
|
||||
// if(getWidthOfText.e === undefined){
|
||||
// getWidthOfText.e = document.createElement('span');
|
||||
// getWidthOfText.e.style.display = "none";
|
||||
// document.body.appendChild(getWidthOfText.e);
|
||||
// }
|
||||
// if(getWidthOfText.e.style.fontSize !== fontsize)
|
||||
// getWidthOfText.e.style.fontSize = fontsize;
|
||||
// if(getWidthOfText.e.style.fontFamily !== 'Signika, sans-serif')
|
||||
// getWidthOfText.e.style.fontFamily = 'Signika, sans-serif';
|
||||
// getWidthOfText.e.innerText = txt;
|
||||
// return getWidthOfText.e.offsetWidth;
|
||||
const text = allCaps ? txt.toUpperCase() : txt;
|
||||
if (getWidthOfText.c === undefined) {
|
||||
getWidthOfText.c = document.createElement('canvas');
|
||||
|
|
@ -82,3 +71,50 @@ export const generateId = (title, length) => {
|
|||
.join('');
|
||||
return Number.isNumeric(length) ? id.slice(0, length).padEnd(length, '0') : id;
|
||||
};
|
||||
|
||||
export function rollCommandToJSON(text) {
|
||||
if (!text) return {};
|
||||
|
||||
// Match key="quoted string" OR key=unquotedValue
|
||||
const PAIR_RE = /(\w+)=("(?:[^"\\]|\\.)*"|\S+)/g;
|
||||
const result = {};
|
||||
for (const [, key, raw] of text.matchAll(PAIR_RE)) {
|
||||
let value;
|
||||
if (raw.startsWith('"') && raw.endsWith('"')) {
|
||||
// Strip the surrounding quotes, un-escape any \" sequences
|
||||
value = raw.slice(1, -1).replace(/\\"/g, '"');
|
||||
} else if (/^(true|false)$/i.test(raw)) {
|
||||
// Boolean
|
||||
value = raw.toLowerCase() === 'true';
|
||||
} else if (!Number.isNaN(Number(raw))) {
|
||||
// Numeric
|
||||
value = Number(raw);
|
||||
} else {
|
||||
// Fallback to string
|
||||
value = raw;
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
return Object.keys(result).length > 0 ? result : null;
|
||||
}
|
||||
|
||||
export const getCommandTarget = () => {
|
||||
let target = game.canvas.tokens.controlled.length > 0 ? game.canvas.tokens.controlled[0].actor : null;
|
||||
if (!game.user.isGM) {
|
||||
target = game.user.character;
|
||||
if (!target) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.NoAssignedPlayerCharacter'));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!target) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.NoSelectedToken'));
|
||||
return null;
|
||||
}
|
||||
if (target.type !== 'pc') {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.OnlyUseableByPC'));
|
||||
return null;
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
}
|
||||
|
||||
addChatListeners = async (app, html, data) => {
|
||||
html.querySelectorAll('.roll-damage-button').forEach(element =>
|
||||
html.querySelectorAll('.duality-action').forEach(element =>
|
||||
element.addEventListener('click', event => this.onRollDamage(event, data.message))
|
||||
);
|
||||
html.querySelectorAll('.target-container').forEach(element => {
|
||||
|
|
|
|||
318
styles/chat.less
318
styles/chat.less
|
|
@ -1,3 +1,303 @@
|
|||
.chat-message {
|
||||
&.duality {
|
||||
border-color: black;
|
||||
padding: 8px 0 0 0;
|
||||
|
||||
.message-header {
|
||||
color: var(--color-light-3);
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.duality-data {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.duality-title {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
border-bottom: 1px solid;
|
||||
margin-bottom: 2px;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
|
||||
.duality-result-value {
|
||||
border: 1px solid var(--color-dark-5);
|
||||
padding: 2px;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.duality-modifiers {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
margin-bottom: 4px;
|
||||
padding: 0 8px;
|
||||
|
||||
.duality-modifier {
|
||||
padding: 2px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid;
|
||||
background: var(--color-dark-6);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.duality-line {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
|
||||
&.simple {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.dice-outer-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.dice-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
|
||||
.dice-title {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
}
|
||||
|
||||
.dice-inner-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
.dice-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
clip-path: polygon(
|
||||
50% 0%,
|
||||
80% 10%,
|
||||
100% 35%,
|
||||
100% 70%,
|
||||
80% 90%,
|
||||
50% 100%,
|
||||
20% 90%,
|
||||
0% 70%,
|
||||
0% 35%,
|
||||
20% 10%
|
||||
);
|
||||
|
||||
.dice {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
max-width: unset;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.dice-value {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.hope {
|
||||
.dice-wrapper {
|
||||
background: black;
|
||||
|
||||
.dice {
|
||||
filter: brightness(0) saturate(100%) invert(79%) sepia(79%) saturate(333%)
|
||||
hue-rotate(352deg) brightness(102%) contrast(103%);
|
||||
}
|
||||
}
|
||||
|
||||
.dice-value {
|
||||
color: var(--color-dark-1);
|
||||
text-shadow: 0 0 4px white;
|
||||
}
|
||||
}
|
||||
|
||||
&.fear {
|
||||
.dice-wrapper {
|
||||
background: white;
|
||||
|
||||
.dice {
|
||||
filter: brightness(0) saturate(100%) invert(12%) sepia(88%) saturate(4321%)
|
||||
hue-rotate(221deg) brightness(92%) contrast(110%);
|
||||
}
|
||||
}
|
||||
|
||||
.dice-value {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 4px black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advantage-container {
|
||||
padding-top: 21px;
|
||||
|
||||
.dice-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.dice {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
max-width: unset;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.dice-value {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.advantage {
|
||||
.dice-wrapper {
|
||||
.dice {
|
||||
filter: brightness(0) saturate(100%) invert(18%) sepia(92%) saturate(4133%)
|
||||
hue-rotate(96deg) brightness(104%) contrast(107%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.disadvantage {
|
||||
.dice-wrapper {
|
||||
.dice {
|
||||
filter: brightness(0) saturate(100%) invert(9%) sepia(78%) saturate(6903%)
|
||||
hue-rotate(11deg) brightness(93%) contrast(117%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.duality-modifier {
|
||||
padding-top: 21px;
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.duality-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
padding: 4px;
|
||||
border-radius: 6px 0 0 0;
|
||||
}
|
||||
|
||||
.duality-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.duality-action {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
padding: 4px;
|
||||
border-radius: 0 6px 0 0;
|
||||
border-color: black;
|
||||
min-height: unset;
|
||||
height: 26px;
|
||||
|
||||
&:hover {
|
||||
background: var(--button-hover-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.target-section {
|
||||
margin: 4px 4px;
|
||||
border: 2px solid;
|
||||
|
||||
.target-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
filter: drop-shadow(0 0 3px @secondaryShadow);
|
||||
border-color: gold;
|
||||
}
|
||||
|
||||
&.hit {
|
||||
background: @hit;
|
||||
}
|
||||
|
||||
&.miss {
|
||||
background: @miss;
|
||||
}
|
||||
|
||||
img {
|
||||
flex: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: 8px;
|
||||
align-self: center;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.target-inner-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: @hugeMargin;
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hope {
|
||||
background: linear-gradient(0, @hopeBackgroundEnd 40px, @hopeBackgroundStart);
|
||||
}
|
||||
&.fear {
|
||||
background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart);
|
||||
}
|
||||
&.critical {
|
||||
background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart);
|
||||
}
|
||||
|
||||
.dice-roll {
|
||||
color: var(--color-dark-1);
|
||||
|
||||
.dice-flavor {
|
||||
color: var(--color-light-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.daggerheart.chat {
|
||||
&.downtime {
|
||||
display: flex;
|
||||
|
|
@ -110,6 +410,24 @@
|
|||
}
|
||||
|
||||
.dice-total {
|
||||
&.duality {
|
||||
&.hope {
|
||||
border-color: @hope;
|
||||
border-width: 3px;
|
||||
background: rgba(@hope, 0.5);
|
||||
}
|
||||
&.fear {
|
||||
border-color: @fear;
|
||||
border-width: 3px;
|
||||
background: rgba(@fear, 0.5);
|
||||
}
|
||||
&.critical {
|
||||
border-color: @critical;
|
||||
border-width: 3px;
|
||||
background: rgba(@critical, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.dice-total-value {
|
||||
.hope {
|
||||
color: @hope;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
/* General */
|
||||
/* Drop Shadows */
|
||||
/* Background */
|
||||
/* Base Value */
|
||||
/* Margins */
|
||||
/* Borders */
|
||||
/* Padding */
|
||||
/* Inputs */
|
||||
/* General */
|
||||
/* Drop Shadows */
|
||||
/* Background */
|
||||
/* Duality */
|
||||
@import '../node_modules/@yaireo/tagify/dist/tagify.css';
|
||||
.daggerheart.sheet.class .editor {
|
||||
height: 500px;
|
||||
|
|
@ -1346,6 +1347,234 @@
|
|||
cursor: pointer;
|
||||
filter: drop-shadow(0 0 3px red);
|
||||
}
|
||||
.chat-message.duality {
|
||||
border-color: black;
|
||||
padding: 8px 0 0 0;
|
||||
}
|
||||
.chat-message.duality .message-header {
|
||||
color: var(--color-light-3);
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chat-message.duality .duality-data {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-title {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
border-bottom: 1px solid;
|
||||
margin-bottom: 2px;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-title .duality-result-value {
|
||||
border: 1px solid var(--color-dark-5);
|
||||
padding: 2px;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-modifiers {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
margin-bottom: 4px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-modifiers .duality-modifier {
|
||||
padding: 2px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid;
|
||||
background: var(--color-dark-6);
|
||||
font-size: 12px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line.simple {
|
||||
padding-right: 0;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-title {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container .dice-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%);
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container .dice-wrapper .dice {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
max-width: unset;
|
||||
position: absolute;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container .dice-value {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.hope .dice-wrapper {
|
||||
background: black;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.hope .dice-wrapper .dice {
|
||||
filter: brightness(0) saturate(100%) invert(79%) sepia(79%) saturate(333%) hue-rotate(352deg) brightness(102%) contrast(103%);
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.hope .dice-value {
|
||||
color: var(--color-dark-1);
|
||||
text-shadow: 0 0 4px white;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.fear .dice-wrapper {
|
||||
background: white;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.fear .dice-wrapper .dice {
|
||||
filter: brightness(0) saturate(100%) invert(12%) sepia(88%) saturate(4321%) hue-rotate(221deg) brightness(92%) contrast(110%);
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .dice-container .dice-inner-container.fear .dice-value {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 4px black;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container {
|
||||
padding-top: 21px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container .dice-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container .dice-wrapper .dice {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
max-width: unset;
|
||||
position: absolute;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container .dice-wrapper .dice-value {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container.advantage .dice-wrapper .dice {
|
||||
filter: brightness(0) saturate(100%) invert(18%) sepia(92%) saturate(4133%) hue-rotate(96deg) brightness(104%) contrast(107%);
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .advantage-container.disadvantage .dice-wrapper .dice {
|
||||
filter: brightness(0) saturate(100%) invert(9%) sepia(78%) saturate(6903%) hue-rotate(11deg) brightness(93%) contrast(117%);
|
||||
}
|
||||
.chat-message.duality .duality-data .duality-line .dice-outer-container .duality-modifier {
|
||||
padding-top: 21px;
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-size: 16px;
|
||||
}
|
||||
.chat-message.duality .duality-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
padding: 4px;
|
||||
border-radius: 6px 0 0 0;
|
||||
}
|
||||
.chat-message.duality .duality-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.chat-message.duality .duality-actions .duality-action {
|
||||
color: var(--color-light-1);
|
||||
text-shadow: 0 0 1px black;
|
||||
font-weight: bold;
|
||||
background: var(--color-dark-1);
|
||||
padding: 4px;
|
||||
border-radius: 0 6px 0 0;
|
||||
border-color: black;
|
||||
min-height: unset;
|
||||
height: 26px;
|
||||
}
|
||||
.chat-message.duality .duality-actions .duality-action:hover {
|
||||
background: var(--button-hover-background-color);
|
||||
}
|
||||
.chat-message.duality .target-section {
|
||||
margin: 4px 4px;
|
||||
border: 2px solid;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container:hover {
|
||||
filter: drop-shadow(0 0 3px gold);
|
||||
border-color: gold;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container.hit {
|
||||
background: #008000;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container.miss {
|
||||
background: #ff0000;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container img {
|
||||
flex: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: 8px;
|
||||
align-self: center;
|
||||
border-color: transparent;
|
||||
}
|
||||
.chat-message.duality .target-section .target-container .target-inner-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 32px;
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
}
|
||||
.chat-message.duality.hope {
|
||||
background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6));
|
||||
}
|
||||
.chat-message.duality.fear {
|
||||
background: linear-gradient(0, rgba(0, 0, 255, 0.6), rgba(15, 15, 97, 0.6));
|
||||
}
|
||||
.chat-message.duality.critical {
|
||||
background: linear-gradient(0, rgba(128, 0, 128, 0.6), rgba(37, 8, 37, 0.6));
|
||||
}
|
||||
.chat-message.duality .dice-roll {
|
||||
color: var(--color-dark-1);
|
||||
}
|
||||
.chat-message.duality .dice-roll .dice-flavor {
|
||||
color: var(--color-light-1);
|
||||
}
|
||||
.daggerheart.chat.downtime {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -1391,7 +1620,7 @@
|
|||
}
|
||||
.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality .roll.die.hope {
|
||||
color: white;
|
||||
-webkit-text-stroke-color: #008080;
|
||||
-webkit-text-stroke-color: #ffe760;
|
||||
-webkit-text-stroke-width: 1.5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
|
@ -1400,7 +1629,7 @@
|
|||
}
|
||||
.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality .roll.die.fear {
|
||||
color: white;
|
||||
-webkit-text-stroke-color: #430070;
|
||||
-webkit-text-stroke-color: #0032b1;
|
||||
-webkit-text-stroke-width: 1.5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
|
@ -1415,7 +1644,7 @@
|
|||
}
|
||||
.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality .roll.die.advantage {
|
||||
color: white;
|
||||
-webkit-text-stroke-color: green;
|
||||
-webkit-text-stroke-color: #008000;
|
||||
-webkit-text-stroke-width: 1.5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
|
@ -1431,14 +1660,29 @@
|
|||
text-align: end;
|
||||
font-weight: bold;
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total.duality.hope {
|
||||
border-color: #ffe760;
|
||||
border-width: 3px;
|
||||
background: rgba(255, 231, 96, 0.5);
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total.duality.fear {
|
||||
border-color: #0032b1;
|
||||
border-width: 3px;
|
||||
background: rgba(0, 50, 177, 0.5);
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total.duality.critical {
|
||||
border-color: #430070;
|
||||
border-width: 3px;
|
||||
background: rgba(67, 0, 112, 0.5);
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total .dice-total-value .hope {
|
||||
color: #008080;
|
||||
color: #ffe760;
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total .dice-total-value .fear {
|
||||
color: #430070;
|
||||
color: #0032b1;
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total .dice-total-value .critical {
|
||||
color: #ffd700;
|
||||
color: #430070;
|
||||
}
|
||||
.daggerheart.chat.roll .dice-total-label {
|
||||
font-size: 12px;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import './variables/variables.less';
|
||||
@import './variables/colors.less';
|
||||
@import './class.less';
|
||||
@import './pc.less';
|
||||
@import './ui.less';
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
/* General */
|
||||
@hope: #008080;
|
||||
@fear: #430070;
|
||||
@critical: #ffd700;
|
||||
@advantage: green;
|
||||
@advantage: #008000;
|
||||
@disadvantage: #b30000;
|
||||
@miss: rgb(255, 0, 0);
|
||||
@hit: rgb(0, 128, 0);
|
||||
|
|
@ -22,3 +19,16 @@
|
|||
@secondaryAccent: #708090;
|
||||
@formBackground: #782e22;
|
||||
@hoverBackground: #2f4f4f40;
|
||||
|
||||
/* Duality */
|
||||
@hope: #ffe760;
|
||||
@hopeBackgroundStart: rgba(0, 0, 0, 0.6);
|
||||
@hopeBackgroundEnd: rgba(165, 42, 42, 0.6);
|
||||
@fear: #0032b1;
|
||||
@fearAccent: #2555cd;
|
||||
@fearBackgroundStart: rgba(15, 15, 97, 0.6);
|
||||
@fearBackgroundEnd: rgba(0, 0, 255, 0.6);
|
||||
@critical: #430070;
|
||||
@criticalAccent: #66159c;
|
||||
@criticalBackgroundStart: rgba(37, 8, 37, 0.6);
|
||||
@criticalBackgroundEnd: rgba(128, 0, 128, 0.6);
|
||||
|
|
|
|||
|
|
@ -1,70 +1,76 @@
|
|||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{localize "DAGGERHEART.Chat.AttackRoll.Title" attack=this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{this.highestRoll}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{#if advantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
<div class="daggerheart chat roll" data-action="expandRoll">
|
||||
{{#if this.colorful}}
|
||||
<div class="duality-data">
|
||||
<div class="duality-title">
|
||||
<div>{{localize "DAGGERHEART.Chat.AttackRoll.Title" attack=this.title}}</div>
|
||||
<div class="duality-result-value">{{this.total}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{this.total}}
|
||||
<div class="duality-modifiers">
|
||||
{{#each this.modifiers}}
|
||||
<div class="duality-modifier">
|
||||
{{this.label}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#if this.advantage.value}}
|
||||
<div class="duality-modifier">
|
||||
{{localize "DAGGERHEART.General.Advantage.Full"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.disadvantage.value}}
|
||||
<div class="duality-modifier">
|
||||
{{localize "DAGGERHEART.General.Disadvantage.Full"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="duality-line {{#if (not this.damage.value)}}simple{{/if}}">
|
||||
<div class="dice-outer-container">
|
||||
<div class="dice-container">
|
||||
<div class="dice-title">{{localize "DAGGERHEART.General.Hope"}}</div>
|
||||
<div class="dice-inner-container hope" title="{{localize "DAGGERHEART.General.Hope"}}">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d12-grey.svg"/>
|
||||
</div>
|
||||
<div class="dice-value">{{hope.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-container">
|
||||
<div class="dice-title">{{localize "DAGGERHEART.General.Fear"}}</div>
|
||||
<div class="dice-inner-container fear" title="{{localize "DAGGERHEART.General.Fear"}}">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d12-grey.svg"/>
|
||||
</div>
|
||||
<div class="dice-value">{{fear.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.advantage.value}}
|
||||
<div class="advantage-container advantage">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d6-grey.svg"/>
|
||||
<div class="dice-value">{{this.advantage.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.disadvantage.value}}
|
||||
<div class="advantage-container disadvantage">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d6-grey.svg"/>
|
||||
<div class="dice-value">{{this.disadvantage.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.modifierTotal.value}}<div class="duality-modifier">{{this.modifierTotal.label}}</div>{{/if}}
|
||||
</div>
|
||||
{{#if (not this.damage.value)}}
|
||||
<div class="duality-result">
|
||||
<div>{{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if (gt targets.length 0)}}
|
||||
<div class="target-section">
|
||||
{{#each targets as |target|}}
|
||||
<div class="dice-total target-container {{#if target.hit}}hit{{else}}{{#if (not ../total.alternate)}}miss{{/if}}{{/if}}" data-token="{{target.id}}">
|
||||
<div class="target-container {{#if target.hit}}hit{{else}}{{#if (not ../total.alternate)}}miss{{/if}}{{/if}}" data-token="{{target.id}}">
|
||||
<img src="{{target.img}}" />
|
||||
<div class="target-inner-container">
|
||||
{{#if target.hit}}{{localize "Hit"}}{{else}}{{#if (not ../total.alternate)}}{{localize "Miss"}}{{else}}?{{/if}}{{/if}}
|
||||
|
|
@ -73,8 +79,94 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="flexrow">
|
||||
<button class="roll-damage-button" data-value="{{this.total}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
{{#if this.damage.value}}
|
||||
<div class="duality-actions">
|
||||
<button class="duality-action" data-value="{{this.total}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
<div class="duality-result">
|
||||
<div>{{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{localize "DAGGERHEART.Chat.AttackRoll.Title" attack=this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{this.diceTotal}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{#if advantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total duality {{#if fear.discarded}}hope{{else}}{{#if hope.discarded}}fear{{else}}critical{{/if}}{{/if}}">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{this.total}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if (gt targets.length 0)}}
|
||||
<div class="target-section">
|
||||
{{#each targets as |target|}}
|
||||
<div class="dice-total target-container {{#if target.hit}}hit{{else}}{{#if (not ../total.alternate)}}miss{{/if}}{{/if}}" data-token="{{target.id}}">
|
||||
<img src="{{target.img}}" />
|
||||
<div class="target-inner-container">
|
||||
{{#if target.hit}}{{localize "Hit"}}{{else}}{{#if (not ../total.alternate)}}{{localize "Miss"}}{{else}}?{{/if}}{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="flexrow">
|
||||
<button class="roll-damage-button" data-value="{{this.total}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
@ -1,64 +1,142 @@
|
|||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{this.highestRoll}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="daggerheart chat roll" data-action="expandRoll">
|
||||
{{#if this.colorful}}
|
||||
<div class="duality-data">
|
||||
<div class="duality-title">
|
||||
<div>{{this.title}}</div>
|
||||
<div class="duality-result-value">{{this.total}}</div>
|
||||
</div>
|
||||
<div class="duality-modifiers">
|
||||
{{#each this.modifiers}}
|
||||
<div class="duality-modifier">
|
||||
{{this.label}}
|
||||
</div>
|
||||
{{#if advantage.value}}
|
||||
{{/each}}
|
||||
{{#if this.advantage.value}}
|
||||
<div class="duality-modifier">
|
||||
{{localize "DAGGERHEART.General.Advantage.Full"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.disadvantage.value}}
|
||||
<div class="duality-modifier">
|
||||
{{localize "DAGGERHEART.General.Disadvantage.Full"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="duality-line {{#if (not this.damage.value)}}simple{{/if}}">
|
||||
<div class="dice-outer-container">
|
||||
<div class="dice-container">
|
||||
<div class="dice-title">{{localize "DAGGERHEART.General.Hope"}}</div>
|
||||
<div class="dice-inner-container hope" title="{{localize "DAGGERHEART.General.Hope"}}">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d12-grey.svg"/>
|
||||
</div>
|
||||
<div class="dice-value">{{hope.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-container">
|
||||
<div class="dice-title">{{localize "DAGGERHEART.General.Fear"}}</div>
|
||||
<div class="dice-inner-container fear" title="{{localize "DAGGERHEART.General.Fear"}}">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d12-grey.svg"/>
|
||||
</div>
|
||||
<div class="dice-value">{{fear.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.advantage.value}}
|
||||
<div class="advantage-container advantage">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d6-grey.svg"/>
|
||||
<div class="dice-value">{{this.advantage.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.disadvantage.value}}
|
||||
<div class="advantage-container disadvantage">
|
||||
<div class="dice-wrapper">
|
||||
<img class="dice" src="../icons/svg/d6-grey.svg"/>
|
||||
<div class="dice-value">{{this.disadvantage.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.modifierTotal.value}}<div class="duality-modifier">{{this.modifierTotal.label}}</div>{{/if}}
|
||||
</div>
|
||||
{{#if (not this.damage.value)}}
|
||||
<div class="duality-result">
|
||||
<div>{{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.damage.value}}
|
||||
<div class="duality-actions">
|
||||
<div></div>
|
||||
<div class="duality-result">
|
||||
<div>{{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="dice-flavor">{{this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
<span class="part-total">{{this.diceTotal}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
{{#if advantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total duality {{#if fear.discarded}}hope{{else}}{{#if hope.discarded}}fear{{else}}critical{{/if}}{{/if}}">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{total}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{total}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
@ -76,7 +76,6 @@
|
|||
<div class="tab features {{this.tabs.primary.features.cssClass}}" data-group="primary" data-tab="features">
|
||||
<div class="tab-container">
|
||||
<div class="flexcol tab-inner-container">
|
||||
<div class="system-info">{{localize "DAGGERHEART.General.OpenBetaDisclaimer" version="V1.4"}}</div>
|
||||
<div class="feature-sheet-body flexrow">
|
||||
<div class="body-section flex2">
|
||||
{{> "systems/daggerheart/templates/sheets/parts/defense.hbs" }}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue