Dossier chat cards + 60-item Field Equipment compendium

Chat rework:
- Roll cards are now dark 'Eyes Only' dossier cards with a classification
  strip (FIELD OPERATION / THE UNNATURAL / LETHAL FORCE), roll name, and a
  target chip. Message frame is colour-accented per roll variant via a
  deltagreen2.variant flag set in DGRoll.toMessage and styled on
  renderChatMessageHTML. Flavor lines dropped in favour of the card header.

Field Equipment compendium:
- New packs/field-equipment with 60 modern DG gear items across
  surveillance, counter-surveillance, forensics, hazmat/protective,
  breaching/restraint, non-lethal, and support. Each uses a bundled
  white-on-black icon, carries flavourful descriptions with mechanical
  bonus notes, and an Agent's Handbook expense tier. Registered in the
  Delta Green pack folder.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 21:08:39 +01:00
co-authored by Claude Fable 5
parent 7ac9357964
commit d5e62e08a7
16 changed files with 487 additions and 181 deletions
+3
View File
@@ -9,6 +9,9 @@ A modified fork of the official _Delta Green: The Role-Playing Game_ Foundry VTT
- **Apply Lethality** — a successful lethality roll offers a one-click "reduce target to 0 HP" button.
- **Sanity application** — SAN damage cards offer success/failure apply buttons. The GM is whispered alerts for temporary insanity (5+ SAN in one hit), breaking-point crossings, and 0 SAN.
- **Ammo tracking** — weapon ammo is numeric with a magazine capacity; attack rolls expend a round, the Equipment tab shows an ammo column with a reload control, and the chat card shows remaining rounds / out-of-ammo warnings. Toggleable via the Automation settings (on by default).
- **Dossier chat cards** — every roll posts as a dark "Eyes Only" case card with a classification strip (FIELD OPERATION / THE UNNATURAL / LETHAL FORCE), the roll name, and a target chip, colour-accented to match the roll type.
- **Themed 3D dice** — three Dice So Nice colorsets applied per roll type: olive Agency dice for skills/stats, blood-red Lethal Force dice for damage and lethality, and violet-glass Unnatural dice for Sanity.
- **Field Equipment compendium** — 60 modern investigation and support items (surveillance, forensics, hazmat, breaching, comms, medical) with white-on-black icon art, mechanical bonus notes, and Agent's Handbook expense tiers.
- **Offline reliability** — the live Google Fonts imports were removed; the system now uses only bundled fonts.
Install by pointing Foundry at this repo, or copy the folder into `Data/systems/deltagreen2`. The system id is `deltagreen2`, so it installs alongside the original without conflict.
+184
View File
@@ -1597,3 +1597,187 @@ button.dg2-apply-button.dg2-san-fail:hover {
width: 55px;
text-align: center;
}
/* ------------------------------------------------------------------ */
/* Delta Green 2 - dossier chat cards */
/* ------------------------------------------------------------------ */
.chat-message.dg2-msg {
background: linear-gradient(160deg, #1b1e24 0%, #16181d 100%);
color: #e6e8ea;
border: 1px solid #2c313a;
border-left: 3px solid #8aa353;
border-radius: 4px;
}
.chat-message.dg2-msg-lethality {
border-left-color: #d4553c;
}
.chat-message.dg2-msg-unnatural {
border-left-color: #9d7bd8;
}
.chat-message.dg2-msg .message-header {
color: #8f98a3;
border-bottom: 1px solid #272b32;
padding-bottom: 2px;
}
.chat-message.dg2-msg .message-header .message-sender {
color: #e6e8ea;
font-family: "PublicSans", sans-serif;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
font-size: 0.85rem;
}
.chat-message.dg2-msg .message-header .message-metadata {
color: #5c6572;
font-size: 0.7rem;
}
.dg2-card {
font-family: "PublicSans", sans-serif;
}
.dg2-card-strip {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 0.62rem;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
margin: 2px 0 4px;
}
.dg2-card-strip .dg2-card-type {
color: #8aa353;
}
.dg2-msg-lethality .dg2-card-strip .dg2-card-type {
color: #d4553c;
}
.dg2-msg-unnatural .dg2-card-strip .dg2-card-type {
color: #9d7bd8;
}
.dg2-card-strip .dg2-card-org {
color: #5c6572;
letter-spacing: 1.5px;
}
.dg2-card-title {
display: flex;
justify-content: space-between;
align-items: center;
gap: 6px;
margin-bottom: 4px;
}
.dg2-card-title .dg2-card-name {
font-size: 1rem;
font-weight: 800;
letter-spacing: 0.5px;
text-transform: uppercase;
color: #e6e8ea;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dg2-chip {
flex: 0 0 auto;
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 1px;
color: #a9c46a;
background: rgba(138, 163, 83, 0.12);
border: 1px solid rgba(138, 163, 83, 0.45);
border-radius: 3px;
padding: 1px 6px;
white-space: nowrap;
}
.dg2-msg-lethality .dg2-chip {
color: #e08a7a;
background: rgba(212, 85, 60, 0.12);
border-color: rgba(212, 85, 60, 0.45);
}
.dg2-msg-unnatural .dg2-chip {
color: #bda4e8;
background: rgba(157, 123, 216, 0.12);
border-color: rgba(157, 123, 216, 0.45);
}
/* Dice internals on the dark card */
.chat-message.dg2-msg .dice-total {
background: #12141a;
border: 1px solid #2c313a;
border-radius: 4px;
color: #e6e8ea;
font-family: "PublicSans", sans-serif;
font-weight: 800;
}
.chat-message.dg2-msg .dice-tooltip .part-formula,
.chat-message.dg2-msg .dice-tooltip .part-total {
color: #8f98a3;
}
.chat-message.dg2-msg .dice-rolls .roll {
filter: invert(0.9) hue-rotate(180deg);
}
/* Banner tuning on dark cards */
.chat-message.dg2-msg .dg2-success {
color: #a9c46a;
background: rgba(138, 163, 83, 0.12);
}
.chat-message.dg2-msg .dg2-crit-success {
color: #c9e59a;
background: rgba(138, 163, 83, 0.28);
}
.chat-message.dg2-msg .dg2-failure {
color: #e08a7a;
background: rgba(212, 85, 60, 0.1);
}
.chat-message.dg2-msg .dg2-crit-failure,
.chat-message.dg2-msg .dg2-lethal {
color: #ff9d8a;
background: rgba(212, 85, 60, 0.25);
}
.chat-message.dg2-msg button.dg2-apply-button {
background: rgba(138, 163, 83, 0.14);
border: 1px solid #3d434e;
color: #e6e8ea;
}
.chat-message.dg2-msg button.dg2-apply-button:hover {
border-color: #8aa353;
background: rgba(138, 163, 83, 0.3);
}
.chat-message.dg2-msg button.dg2-apply-button.dg2-lethal,
.chat-message.dg2-msg button.dg2-apply-button.dg2-san-fail {
background: rgba(212, 85, 60, 0.12);
}
.chat-message.dg2-msg button.dg2-apply-button.dg2-lethal:hover,
.chat-message.dg2-msg button.dg2-apply-button.dg2-san-fail:hover {
border-color: #d4553c;
background: rgba(212, 85, 60, 0.3);
}
.chat-message.dg2-msg .rollback-section label {
color: #8f98a3;
}
+6 -1
View File
@@ -397,5 +397,10 @@
"DG2.Apply.SanFailTooltip": "Apply the higher SAN loss (the SAN test failed).",
"DG2.Apply.NoTarget": "Target or select a token first.",
"DG2.Apply.NoSanTarget": "No valid target with a Sanity score.",
"DG.Settings.charactersheet.tactical": "Tactical (Delta Green 2 modern)"
"DG.Settings.charactersheet.tactical": "Tactical (Delta Green 2 modern)",
"DG2.Chat.FieldOperation": "Field Operation",
"DG2.Chat.LethalForce": "Lethal Force",
"DG2.Chat.TheUnnatural": "The Unnatural",
"DG2.Chat.EyesOnly": "Delta Green // Eyes Only",
"DG2.Chat.Target": "Target"
}
+6
View File
@@ -255,6 +255,12 @@ Hooks.on("renderChatLog", async (app, element) => {
});
Hooks.on("renderChatMessageHTML", async (app, element, context) => {
// Style DG2 roll messages as dossier cards (variant set in DGRoll.toMessage).
const variant = app.getFlag?.("deltagreen2", "variant");
if (variant) {
element.classList.add("dg2-msg", `dg2-msg-${variant}`);
}
// ignore non chat card notifications
if (!context.canClose) return;
addEventListenerToChatMessage(element);
+80 -34
View File
@@ -51,6 +51,19 @@ export class DGRoll extends Roll {
async toMessage(messageData = {}, { rollMode, create = true } = {}) {
// eslint-disable-next-line no-param-reassign
messageData.speaker = ChatMessage.getSpeaker({ actor: this.actor });
// Tag the message with its DG2 variant (agency/lethality/unnatural),
// derived from the Dice So Nice colorset set in toChat. The chat
// renderer uses this to style the card.
const colorset = this.dice[0]?.options?.colorset;
if (colorset?.startsWith("dg2-")) {
// eslint-disable-next-line no-param-reassign
messageData.flags = foundry.utils.mergeObject(
{ deltagreen2: { variant: colorset.replace("dg2-", "") } },
messageData.flags ?? {},
);
}
return super.toMessage(messageData, {
rollMode: this.options.rollMode || rollMode,
create,
@@ -264,9 +277,39 @@ export class DGPercentileRoll extends DGRoll {
game.modules.has("dice-so-nice") &&
game.modules.get("dice-so-nice").active;
tagRollDice(this, colorsetForPercentileRoll(this));
const colorset = colorsetForPercentileRoll(this);
tagRollDice(this, colorset);
const label = this.createLabel();
// Structured card header data.
const typeLabel =
colorset === "dg2-unnatural"
? DGUtils.localizeWithFallback("DG2.Chat.TheUnnatural", "THE UNNATURAL")
: DGUtils.localizeWithFallback(
"DG2.Chat.FieldOperation",
"FIELD OPERATION",
);
let rollName = this.localizedKey ?? this.formula;
if (this.isInhuman) {
rollName += ` [${game.i18n.localize("DG.Roll.Inhuman").toUpperCase()}]`;
}
const targetText = `${DGUtils.localizeWithFallback(
"DG2.Chat.Target",
"TARGET",
)} ${this.effectiveTarget}%`;
// Show the math when the effective target differs from the base value.
let chipDetail = "";
const { isExhausted, exhaustedCheckPenalty } = this.exhausted;
if (this.modifier || isExhausted) {
chipDetail = `${this.target}%`;
if (this.modifier) {
chipDetail += `${DGUtils.formatStringWithLeadingPlus(this.modifier)}%`;
}
if (isExhausted) {
chipDetail += `${DGUtils.formatStringWithLeadingPlus(
exhaustedCheckPenalty,
)}%`;
}
}
let resultString = "";
let outcomeClass = "";
@@ -327,6 +370,10 @@ export class DGPercentileRoll extends DGRoll {
const html = await renderTemplate(
"systems/deltagreen2/templates/roll/percentile-roll.hbs",
{
typeLabel,
rollName,
targetText,
chipDetail,
outcomeClass,
outcomeIcon,
marginText,
@@ -352,7 +399,6 @@ export class DGPercentileRoll extends DGRoll {
},
},
content: html,
flavor: label,
});
if (diceSoNice) {
@@ -367,7 +413,7 @@ export class DGPercentileRoll extends DGRoll {
return message;
}
return this.toMessage({ content: html, flavor: label });
return this.toMessage({ content: html });
}
/**
@@ -668,20 +714,22 @@ export class DGLethalityRoll extends DGPercentileRoll {
}
const { nonLethalDamage } = this;
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n
.localize("DG.Roll.Lethality")
.toUpperCase()}</b> ${game.i18n.localize(
"DG.Roll.For",
)} <b>${this.item.name.toUpperCase()}</b> ${game.i18n.localize(
"DG.Roll.Target",
)} ${this.target + this.modifier}`;
let targetText = `${game.i18n.localize("DG.Roll.Lethality").toUpperCase()} ${
this.target + this.modifier
}%`;
if (this.modifier) {
label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`;
targetText += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`;
}
const html = await renderTemplate(
"systems/deltagreen2/templates/roll/lethality-roll.hbs",
{
typeLabel: DGUtils.localizeWithFallback(
"DG2.Chat.LethalForce",
"LETHAL FORCE",
),
rollName: this.item.name,
targetText,
resultString,
outcomeClass,
outcomeIcon,
@@ -692,7 +740,7 @@ export class DGLethalityRoll extends DGPercentileRoll {
},
);
return this.toMessage({ content: html, flavor: label });
return this.toMessage({ content: html });
}
/**
@@ -751,23 +799,17 @@ export class DGDamageRoll extends DGRoll {
async toChat() {
tagRollDice(this, "dg2-lethality");
let label = this.formula;
try {
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n
.localize("DG.Roll.Damage")
.toUpperCase()}</b> ${game.i18n.localize("DG.Roll.For")} ${
this.item.name
} (<b>${
this.item.system.armorPiercing
} </b><img class="armor-piercing-chat-card-img" src="systems/deltagreen2/assets/icons/supersonic-bullet.svg" alt="armor penetration"/>)`;
} catch (ex) {
// console.log(ex);
label = `Rolling <b>DAMAGE</b> for <b>${label.toUpperCase()}</b>`;
}
const html = await renderTemplate(
"systems/deltagreen2/templates/roll/damage-roll.hbs",
{
typeLabel: DGUtils.localizeWithFallback(
"DG2.Chat.LethalForce",
"LETHAL FORCE",
),
rollName:
this.item?.name ??
game.i18n.localize("DG.Roll.Damage").toUpperCase(),
targetText: game.i18n.localize("DG.Roll.Damage").toUpperCase(),
formula: this.formula,
total: this.total,
dice: this.dice.flatMap((die) =>
@@ -777,7 +819,7 @@ export class DGDamageRoll extends DGRoll {
},
);
return this.toMessage({ content: html, flavor: label });
return this.toMessage({ content: html });
}
async showDialog() {
@@ -859,14 +901,18 @@ export class DGSanityDamageRoll extends DGRoll {
const [lowResult, highResult] = this.damageResults;
const flavor = `Rolling <b>${DGUtils.localizeWithFallback(
"DG.Generic.SanDamage",
"SAN DAMAGE",
)}</b> For <b>${lowDie.formula} / ${highDie.formula}</b>`;
const html = await renderTemplate(
"systems/deltagreen2/templates/roll/sanity-damage-roll.hbs",
{
typeLabel: DGUtils.localizeWithFallback(
"DG2.Chat.TheUnnatural",
"THE UNNATURAL",
),
rollName: DGUtils.localizeWithFallback(
"DG.Generic.SanDamage",
"SAN DAMAGE",
),
targetText: `${lowDie.formula} / ${highDie.formula}`,
lowFormula: lowDie.formula,
highFormula: highDie.formula,
lowFaces: lowDie.faces,
@@ -876,7 +922,7 @@ export class DGSanityDamageRoll extends DGRoll {
},
);
return this.toMessage({ content: html, flavor });
return this.toMessage({ content: html });
}
/**
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
MANIFEST-000002
View File
+5
View File
@@ -0,0 +1,5 @@
2026/07/15-21:04:44.645310 17171b000 Delete type=3 #1
2026/07/15-21:04:44.647621 1717a7000 Level-0 table #5: started
2026/07/15-21:04:44.648040 1717a7000 Level-0 table #5: 13451 bytes OK
2026/07/15-21:04:44.648151 1717a7000 Delete type=0 #3
2026/07/15-21:04:44.648243 1717a7000 Manual compaction at level-0 from '!items!0ggfh90orzn6ldrf' @ 72057594037927935 : 1 .. '!items!zzorhwhnj04fox00' @ 0 : 0; will stop at (end)
Binary file not shown.
+13
View File
@@ -107,6 +107,7 @@
"firearms",
"armor",
"hand-to-hand-weapons",
"field-equipment",
"agent-pregens",
"operation-code-name-generator-tables"
],
@@ -159,6 +160,18 @@
"ASSISTANT": "OWNER"
}
},
{
"name": "field-equipment",
"label": "Field Equipment (DG2)",
"system": "deltagreen2",
"path": "packs/field-equipment",
"type": "Item",
"flags": {},
"ownership": {
"PLAYER": "OBSERVER",
"ASSISTANT": "OWNER"
}
},
{
"name": "agent-pregens",
"label": "Agent Pregens",
+37 -27
View File
@@ -1,31 +1,41 @@
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dice-formula">{{formula}}</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
{{#each dice}}
<li class="roll die d{{this.faces}}">{{this.result}}</li>
{{/each}}
</ol>
</div>
</section>
<div class="dg2-card">
<div class="dg2-card-strip">
<span class="dg2-card-type">{{typeLabel}}</span>
<span class="dg2-card-org">{{localize 'DG2.Chat.EyesOnly'}}</span>
</div>
<div class="dg2-card-title">
<span class="dg2-card-name">{{rollName}}</span>
<span class="dg2-chip">{{targetText}} {{formula}}{{#if ap}} &middot; AP {{ap}}{{/if}}</span>
</div>
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
{{#each dice}}
<li class="roll die d{{this.faces}}">{{this.result}}</li>
{{/each}}
</ol>
</div>
</section>
</div>
</div>
<h4 class="dice-total">{{total}}</h4>
<div class="dg2-apply-row">
<button type="button" class="dg2-apply-button" data-action="dg2-apply-damage"
data-damage="{{total}}" data-ap="{{ap}}"
data-tooltip="{{localize 'DG2.Apply.DamageTooltip'}}">
<i class="fas fa-heart-crack" aria-hidden="true"></i>
{{localize 'DG2.Apply.Damage'}} ({{total}}{{#if ap}}, AP {{ap}}{{/if}})
</button>
</div>
</div>
<h4 class="dice-total">{{total}}</h4>
<div class="dg2-apply-row">
<button type="button" class="dg2-apply-button" data-action="dg2-apply-damage"
data-damage="{{total}}" data-ap="{{ap}}"
data-tooltip="{{localize 'DG2.Apply.DamageTooltip'}}">
<i class="fas fa-heart-crack" aria-hidden="true"></i>
{{localize 'DG2.Apply.Damage'}} ({{total}}{{#if ap}}, AP {{ap}}{{/if}})
</button>
</div>
</div>
</div>
+56 -45
View File
@@ -1,49 +1,60 @@
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dg2-outcome {{outcomeClass}}">
<i class="fas {{outcomeIcon}}" aria-hidden="true"></i>
<span class="dg2-outcome-text">{{resultString}}</span>
</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">d100</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d100">{{total}}</li>
</ol>
<hr>
<header class="part-header flexrow">
<span class="part-formula">2d10 (d10 + d10)</span>
<span class="part-total">{{nonLethal.total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d10">{{nonLethal.die1}}</li>
<li class="roll die d10">{{nonLethal.die2}}</li>
</ol>
</div>
</section>
<div class="dg2-card">
<div class="dg2-card-strip">
<span class="dg2-card-type">{{typeLabel}}</span>
<span class="dg2-card-org">{{localize 'DG2.Chat.EyesOnly'}}</span>
</div>
<div class="dg2-card-title">
<span class="dg2-card-name">{{rollName}}</span>
<span class="dg2-chip">{{targetText}}</span>
</div>
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dg2-outcome {{outcomeClass}}">
<i class="fas {{outcomeIcon}}" aria-hidden="true"></i>
<span class="dg2-outcome-text">{{resultString}}</span>
</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">d100</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d100">{{total}}</li>
</ol>
<hr>
<header class="part-header flexrow">
<span class="part-formula">2d10 (d10 + d10)</span>
<span class="part-total">{{nonLethal.total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d10">{{nonLethal.die1}}</li>
<li class="roll die d10">{{nonLethal.die2}}</li>
</ol>
</div>
</section>
</div>
</div>
<h4 class="dice-total">{{total}} ({{nonLethal.total}} {{localize 'DG.Roll.Damage'}})</h4>
<div class="dg2-apply-row">
{{#if isLethal}}
<button type="button" class="dg2-apply-button dg2-lethal" data-action="dg2-apply-lethality"
data-tooltip="{{localize 'DG2.Apply.LethalityTooltip'}}">
<i class="fas fa-skull-crossbones" aria-hidden="true"></i>
{{localize 'DG2.Apply.Lethality'}}
</button>
{{else}}
<button type="button" class="dg2-apply-button" data-action="dg2-apply-damage"
data-damage="{{nonLethal.total}}" data-ap="{{ap}}"
data-tooltip="{{localize 'DG2.Apply.DamageTooltip'}}">
<i class="fas fa-heart-crack" aria-hidden="true"></i>
{{localize 'DG2.Apply.Damage'}} ({{nonLethal.total}}{{#if ap}}, AP {{ap}}{{/if}})
</button>
{{/if}}
</div>
</div>
<h4 class="dice-total">{{total}} ({{nonLethal.total}} {{localize 'DG.Roll.Damage'}})</h4>
<div class="dg2-apply-row">
{{#if isLethal}}
<button type="button" class="dg2-apply-button dg2-lethal" data-action="dg2-apply-lethality"
data-tooltip="{{localize 'DG2.Apply.LethalityTooltip'}}">
<i class="fas fa-skull-crossbones" aria-hidden="true"></i>
{{localize 'DG2.Apply.Lethality'}}
</button>
{{else}}
<button type="button" class="dg2-apply-button" data-action="dg2-apply-damage"
data-damage="{{nonLethal.total}}" data-ap="{{ap}}"
data-tooltip="{{localize 'DG2.Apply.DamageTooltip'}}">
<i class="fas fa-heart-crack" aria-hidden="true"></i>
{{localize 'DG2.Apply.Damage'}} ({{nonLethal.total}}{{#if ap}}, AP {{ap}}{{/if}})
</button>
{{/if}}
</div>
</div>
</div>
+47 -35
View File
@@ -1,41 +1,53 @@
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dg2-outcome {{outcomeClass}}">
<i class="fas {{outcomeIcon}}" aria-hidden="true"></i>
<span class="dg2-outcome-text">{{resultString}}</span>
{{#if marginText}}<span class="dg2-margin">{{marginText}}</span>{{/if}}
</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die {{formula}}">{{total}}</li>
</ol>
</div>
</section>
</div>
</div>
<h4 class="dice-total">{{total}}</h4>
{{#if ammoLine}}
<div class="dg2-ammo-line {{#if outOfAmmo}}dg2-out-of-ammo{{/if}}">
<i class="fas fa-crosshairs" aria-hidden="true"></i> {{ammoLine}}
</div>
<div class="dg2-card">
<div class="dg2-card-strip">
<span class="dg2-card-type">{{typeLabel}}</span>
<span class="dg2-card-org">{{localize 'DG2.Chat.EyesOnly'}}</span>
</div>
<div class="dg2-card-title">
<span class="dg2-card-name">{{rollName}}</span>
{{#if targetText}}
<span class="dg2-chip" {{#if chipDetail}}data-tooltip="{{chipDetail}}"{{/if}}>{{targetText}}</span>
{{/if}}
</div>
{{#if failureMark}}
<div class="rollback-section">
<label>{{localize 'DG.Messages.Skillsmark.Marked'}}</label>
<i class="fa fa-book" aria-hidden="true" data-tooltip="<p>{{localize 'DG.Messages.Skillsmark.Tooltip'}}</p>"></i>
<button type="button" data-action="rollback-skill-failure-state">
<i class="fa fa-undo" aria-hidden="true"></i>
</button>
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dg2-outcome {{outcomeClass}}">
<i class="fas {{outcomeIcon}}" aria-hidden="true"></i>
<span class="dg2-outcome-text">{{resultString}}</span>
{{#if marginText}}<span class="dg2-margin">{{marginText}}</span>{{/if}}
</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die {{formula}}">{{total}}</li>
</ol>
</div>
</section>
</div>
</div>
<h4 class="dice-total">{{total}}</h4>
{{#if ammoLine}}
<div class="dg2-ammo-line {{#if outOfAmmo}}dg2-out-of-ammo{{/if}}">
<i class="fas fa-crosshairs" aria-hidden="true"></i> {{ammoLine}}
</div>
{{/if}}
</div>
{{/if}}
{{#if failureMark}}
<div class="rollback-section">
<label>{{localize 'DG.Messages.Skillsmark.Marked'}}</label>
<i class="fa fa-book" aria-hidden="true" data-tooltip="<p>{{localize 'DG.Messages.Skillsmark.Tooltip'}}</p>"></i>
<button type="button" data-action="rollback-skill-failure-state">
<i class="fa fa-undo" aria-hidden="true"></i>
</button>
</div>
{{/if}}
</div>
</div>
+49 -39
View File
@@ -1,43 +1,53 @@
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dice-formula">{{lowFormula}} / {{highFormula}}</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{lowFormula}}</span>
<span class="part-total">{{lowResult}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d{{lowFaces}}">{{lowResult}}</li>
</ol>
<hr>
<header class="part-header flexrow">
<span class="part-formula">{{highFormula}}</span>
<span class="part-total">{{highResult}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d{{highFaces}}">{{highResult}}</li>
</ol>
</div>
</section>
<div class="dg2-card">
<div class="dg2-card-strip">
<span class="dg2-card-type">{{typeLabel}}</span>
<span class="dg2-card-org">{{localize 'DG2.Chat.EyesOnly'}}</span>
</div>
<div class="dg2-card-title">
<span class="dg2-card-name">{{rollName}}</span>
<span class="dg2-chip">{{targetText}}</span>
</div>
<div class="dice-roll" data-action="expandRoll">
<div class="dice-result">
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{lowFormula}}</span>
<span class="part-total">{{lowResult}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d{{lowFaces}}">{{lowResult}}</li>
</ol>
<hr>
<header class="part-header flexrow">
<span class="part-formula">{{highFormula}}</span>
<span class="part-total">{{highResult}}</span>
</header>
<ol class="dice-rolls">
<li class="roll die d{{highFaces}}">{{highResult}}</li>
</ol>
</div>
</section>
</div>
</div>
<h4 class="dice-total">{{lowResult}} / {{highResult}}</h4>
<div class="dg2-apply-row">
<button type="button" class="dg2-apply-button" data-action="dg2-apply-san"
data-san="{{lowResult}}"
data-tooltip="{{localize 'DG2.Apply.SanSuccessTooltip'}}">
<i class="fas fa-brain" aria-hidden="true"></i>
{{localize 'DG.Roll.Success'}}: &minus;{{lowResult}} SAN
</button>
<button type="button" class="dg2-apply-button dg2-san-fail" data-action="dg2-apply-san"
data-san="{{highResult}}"
data-tooltip="{{localize 'DG2.Apply.SanFailTooltip'}}">
<i class="fas fa-brain" aria-hidden="true"></i>
{{localize 'DG.Roll.Failure'}}: &minus;{{highResult}} SAN
</button>
</div>
</div>
<h4 class="dice-total">{{lowResult}} / {{highResult}}</h4>
<div class="dg2-apply-row">
<button type="button" class="dg2-apply-button" data-action="dg2-apply-san"
data-san="{{lowResult}}"
data-tooltip="{{localize 'DG2.Apply.SanSuccessTooltip'}}">
<i class="fas fa-brain" aria-hidden="true"></i>
{{localize 'DG.Roll.Success'}}: &minus;{{lowResult}} SAN
</button>
<button type="button" class="dg2-apply-button dg2-san-fail" data-action="dg2-apply-san"
data-san="{{highResult}}"
data-tooltip="{{localize 'DG2.Apply.SanFailTooltip'}}">
<i class="fas fa-brain" aria-hidden="true"></i>
{{localize 'DG.Roll.Failure'}}: &minus;{{highResult}} SAN
</button>
</div>
</div>
</div>