From d5e62e08a7c0ada22ac8be7662622bc8a88d3923 Mon Sep 17 00:00:00 2001 From: Tim Evans Date: Wed, 15 Jul 2026 21:08:39 +0100 Subject: [PATCH] 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 --- README.md | 3 + css/deltagreen.css | 184 ++++++++++++++++++++++++++ lang/en.json | 7 +- module/deltagreen.js | 6 + module/roll/roll.js | 114 +++++++++++----- packs/field-equipment/000004.log | 0 packs/field-equipment/000005.ldb | Bin 0 -> 13451 bytes packs/field-equipment/CURRENT | 1 + packs/field-equipment/LOCK | 0 packs/field-equipment/LOG | 5 + packs/field-equipment/MANIFEST-000002 | Bin 0 -> 134 bytes system.json | 13 ++ templates/roll/damage-roll.hbs | 64 +++++---- templates/roll/lethality-roll.hbs | 101 +++++++------- templates/roll/percentile-roll.hbs | 82 +++++++----- templates/roll/sanity-damage-roll.hbs | 88 ++++++------ 16 files changed, 487 insertions(+), 181 deletions(-) create mode 100644 packs/field-equipment/000004.log create mode 100644 packs/field-equipment/000005.ldb create mode 100644 packs/field-equipment/CURRENT create mode 100644 packs/field-equipment/LOCK create mode 100644 packs/field-equipment/LOG create mode 100644 packs/field-equipment/MANIFEST-000002 diff --git a/README.md b/README.md index 52370f8..b7aff58 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/css/deltagreen.css b/css/deltagreen.css index 82e31b1..c8ca2f8 100644 --- a/css/deltagreen.css +++ b/css/deltagreen.css @@ -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; +} diff --git a/lang/en.json b/lang/en.json index 76fc1ca..ffcd4e4 100644 --- a/lang/en.json +++ b/lang/en.json @@ -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" } \ No newline at end of file diff --git a/module/deltagreen.js b/module/deltagreen.js index 5acf05c..ce6029e 100644 --- a/module/deltagreen.js +++ b/module/deltagreen.js @@ -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); diff --git a/module/roll/roll.js b/module/roll/roll.js index 20f68c2..3fcd609 100644 --- a/module/roll/roll.js +++ b/module/roll/roll.js @@ -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")} ${game.i18n - .localize("DG.Roll.Lethality") - .toUpperCase()} ${game.i18n.localize( - "DG.Roll.For", - )} ${this.item.name.toUpperCase()} ${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")} ${game.i18n - .localize("DG.Roll.Damage") - .toUpperCase()} ${game.i18n.localize("DG.Roll.For")} ${ - this.item.name - } (${ - this.item.system.armorPiercing - } armor penetration)`; - } catch (ex) { - // console.log(ex); - label = `Rolling DAMAGE for ${label.toUpperCase()}`; - } - 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 ${DGUtils.localizeWithFallback( - "DG.Generic.SanDamage", - "SAN DAMAGE", - )} For ${lowDie.formula} / ${highDie.formula}`; - 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 }); } /** diff --git a/packs/field-equipment/000004.log b/packs/field-equipment/000004.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/field-equipment/000005.ldb b/packs/field-equipment/000005.ldb new file mode 100644 index 0000000000000000000000000000000000000000..cd5cf7322b50a3b6983a7f7a00a69202d486a791 GIT binary patch literal 13451 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 literal 0 HcmV?d00001 diff --git a/system.json b/system.json index 3769f93..5ea51b0 100644 --- a/system.json +++ b/system.json @@ -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", diff --git a/templates/roll/damage-roll.hbs b/templates/roll/damage-roll.hbs index bf5301a..0e96bfd 100644 --- a/templates/roll/damage-roll.hbs +++ b/templates/roll/damage-roll.hbs @@ -1,31 +1,41 @@ -
-
-
{{formula}}
-
-
-
-
-
- {{formula}} - {{total}} -
-
    - {{#each dice}} -
  1. {{this.result}}
  2. - {{/each}} -
-
-
+
+
+ {{typeLabel}} + {{localize 'DG2.Chat.EyesOnly'}} +
+
+ {{rollName}} + {{targetText}} {{formula}}{{#if ap}} · AP {{ap}}{{/if}} +
+ +
+
+
+
+
+
+
+ {{formula}} + {{total}} +
+
    + {{#each dice}} +
  1. {{this.result}}
  2. + {{/each}} +
+
+
+
+
+

{{total}}

+
+
-
-

{{total}}

-
-
diff --git a/templates/roll/lethality-roll.hbs b/templates/roll/lethality-roll.hbs index 3de81e0..b3d3f4e 100644 --- a/templates/roll/lethality-roll.hbs +++ b/templates/roll/lethality-roll.hbs @@ -1,49 +1,60 @@ -
-
-
- - {{resultString}} -
-
-
-
-
-
- d100 - {{total}} -
-
    -
  1. {{total}}
  2. -
-
-
- 2d10 (d10 + d10) - {{nonLethal.total}} -
-
    -
  1. {{nonLethal.die1}}
  2. -
  3. {{nonLethal.die2}}
  4. -
-
-
+
+
+ {{typeLabel}} + {{localize 'DG2.Chat.EyesOnly'}} +
+
+ {{rollName}} + {{targetText}} +
+ +
+
+
+ + {{resultString}} +
+
+
+
+
+
+ d100 + {{total}} +
+
    +
  1. {{total}}
  2. +
+
+
+ 2d10 (d10 + d10) + {{nonLethal.total}} +
+
    +
  1. {{nonLethal.die1}}
  2. +
  3. {{nonLethal.die2}}
  4. +
+
+
+
+
+

{{total}} ({{nonLethal.total}} {{localize 'DG.Roll.Damage'}})

+
+ {{#if isLethal}} + + {{else}} + + {{/if}}
-
-

{{total}} ({{nonLethal.total}} {{localize 'DG.Roll.Damage'}})

-
- {{#if isLethal}} - - {{else}} - - {{/if}}
diff --git a/templates/roll/percentile-roll.hbs b/templates/roll/percentile-roll.hbs index ff7cdf5..4e6b5c5 100644 --- a/templates/roll/percentile-roll.hbs +++ b/templates/roll/percentile-roll.hbs @@ -1,41 +1,53 @@ -
-
-
- - {{resultString}} - {{#if marginText}}{{marginText}}{{/if}} -
-
-
-
-
-
- {{formula}} - {{total}} -
-
    -
  1. {{total}}
  2. -
-
-
-
-
-

{{total}}

- {{#if ammoLine}} -
- {{ammoLine}} -
+
+
+ {{typeLabel}} + {{localize 'DG2.Chat.EyesOnly'}} +
+
+ {{rollName}} + {{#if targetText}} + {{targetText}} {{/if}}
- {{#if failureMark}} -
- - - +
+
+
+ + {{resultString}} + {{#if marginText}}{{marginText}}{{/if}} +
+
+
+
+
+
+ {{formula}} + {{total}} +
+
    +
  1. {{total}}
  2. +
+
+
+
+
+

{{total}}

+ {{#if ammoLine}} +
+ {{ammoLine}} +
+ {{/if}}
- {{/if}} + {{#if failureMark}} +
+ + + +
+ {{/if}} +
diff --git a/templates/roll/sanity-damage-roll.hbs b/templates/roll/sanity-damage-roll.hbs index 763befe..3ae551b 100644 --- a/templates/roll/sanity-damage-roll.hbs +++ b/templates/roll/sanity-damage-roll.hbs @@ -1,43 +1,53 @@ -
-
-
{{lowFormula}} / {{highFormula}}
-
-
-
-
-
- {{lowFormula}} - {{lowResult}} -
-
    -
  1. {{lowResult}}
  2. -
-
-
- {{highFormula}} - {{highResult}} -
-
    -
  1. {{highResult}}
  2. -
-
-
+
+
+ {{typeLabel}} + {{localize 'DG2.Chat.EyesOnly'}} +
+
+ {{rollName}} + {{targetText}} +
+ +
+
+
+
+
+
+
+ {{lowFormula}} + {{lowResult}} +
+
    +
  1. {{lowResult}}
  2. +
+
+
+ {{highFormula}} + {{highResult}} +
+
    +
  1. {{highResult}}
  2. +
+
+
+
+
+

{{lowResult}} / {{highResult}}

+
+ +
-
-

{{lowResult}} / {{highResult}}

-
- -