Add themed Dice So Nice dice: agency / lethal / unnatural
Registers three Delta Green 2 colorsets with Dice So Nice and applies them per roll type so the dice match the moment: - dg2-agency (olive drab, metal, cloudy, bone numerals) -> skill/stat/luck /weapon checks; set as the table default appearance. - dg2-lethality (black + blood red, fire texture) -> damage and lethality. - dg2-unnatural (void violet glass, astral texture, green glow) -> SAN checks, rituals, and sanity damage. Dice are tagged in each toChat() via tagRollDice(); registration runs on the diceSoNiceReady hook and degrades silently when DSN is absent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
rollSkillTestAndDamageForOwnedItem,
|
||||
} from "./other/macro-functions.js";
|
||||
import { handleInlineActions } from "./other/inline.js";
|
||||
import { registerDG2DiceSoNice } from "./integrations/dice-so-nice.js";
|
||||
import DGNPCSheet from "./sheets/npc-sheet.js";
|
||||
import DGUnnaturalSheet from "./sheets/unnatural-sheet.js";
|
||||
import DGVehicleSheet from "./sheets/vehicle-sheet.js";
|
||||
@@ -211,6 +212,15 @@ Hooks.on("createActor", async (actor, options, userId) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Register themed Delta Green 2 dice with Dice So Nice, if present.
|
||||
Hooks.once("diceSoNiceReady", (dice3d) => {
|
||||
try {
|
||||
registerDG2DiceSoNice(dice3d);
|
||||
} catch (ex) {
|
||||
console.warn("Delta Green 2 | Failed to register Dice So Nice theme", ex);
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.on("renderGamePause", function (_, html, options) {
|
||||
if (options.cssClass !== "paused") return;
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Delta Green 2 — Dice So Nice integration.
|
||||
*
|
||||
* Registers three themed colorsets and applies them per roll type:
|
||||
* - dg2-agency: olive drab, bone numerals — skill/stat/luck/weapon checks
|
||||
* - dg2-lethality: black and blood red — lethality and damage rolls
|
||||
* - dg2-unnatural: void violet with a sickly glow — SAN checks, rituals,
|
||||
* and sanity damage
|
||||
*/
|
||||
|
||||
const CATEGORY = "Delta Green 2";
|
||||
|
||||
/**
|
||||
* Register the DG2 dice appearance with Dice So Nice.
|
||||
* Called from the diceSoNiceReady hook.
|
||||
*
|
||||
* @param {Object} dice3d - the Dice So Nice API object.
|
||||
*/
|
||||
export function registerDG2DiceSoNice(dice3d) {
|
||||
// "default" sets this as the table default for users who have not
|
||||
// customized their own dice, so the system looks right out of the box.
|
||||
dice3d.addColorset(
|
||||
{
|
||||
name: "dg2-agency",
|
||||
description: "DG2 — Agency Issue",
|
||||
category: CATEGORY,
|
||||
foreground: "#e8e4d5",
|
||||
background: "#3a4a24",
|
||||
outline: "#151a0d",
|
||||
edge: "#242f16",
|
||||
texture: "cloudy",
|
||||
material: "metal",
|
||||
font: "Special Elite",
|
||||
visibility: "visible",
|
||||
},
|
||||
"default",
|
||||
);
|
||||
|
||||
dice3d.addColorset({
|
||||
name: "dg2-lethality",
|
||||
description: "DG2 — Lethal Force",
|
||||
category: CATEGORY,
|
||||
foreground: "#ff3b30",
|
||||
background: "#0d0d0f",
|
||||
outline: "#000000",
|
||||
edge: "#3d0a06",
|
||||
texture: "fire",
|
||||
material: "metal",
|
||||
font: "Special Elite",
|
||||
visibility: "visible",
|
||||
});
|
||||
|
||||
dice3d.addColorset({
|
||||
name: "dg2-unnatural",
|
||||
description: "DG2 — The Unnatural",
|
||||
category: CATEGORY,
|
||||
foreground: "#8dffb0",
|
||||
background: "#1a0b2e",
|
||||
outline: "#050208",
|
||||
edge: "#2c1150",
|
||||
texture: "astral",
|
||||
material: "glass",
|
||||
font: "Special Elite",
|
||||
emissive: "#2a0a4a",
|
||||
emissiveIntensity: 0.4,
|
||||
visibility: "visible",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag every die in a roll with a DG2 colorset so Dice So Nice renders
|
||||
* the themed dice for this roll regardless of the user's default.
|
||||
*
|
||||
* @param {Roll} roll - an evaluated (or about to be evaluated) roll.
|
||||
* @param {"dg2-agency"|"dg2-lethality"|"dg2-unnatural"} colorset
|
||||
*/
|
||||
export function tagRollDice(roll, colorset) {
|
||||
try {
|
||||
for (const die of roll.dice) {
|
||||
die.options.colorset = colorset;
|
||||
}
|
||||
} catch {
|
||||
// Dice theming must never break the roll itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick the DG2 colorset for a percentile roll based on its type.
|
||||
*
|
||||
* @param {DGPercentileRoll} roll
|
||||
* @returns {string} colorset name
|
||||
*/
|
||||
export function colorsetForPercentileRoll(roll) {
|
||||
if (roll.type === "sanity" || roll.key === "ritual") {
|
||||
return "dg2-unnatural";
|
||||
}
|
||||
return "dg2-agency";
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import DGUtils from "../other/utility-functions.js";
|
||||
import DG from "../config.js";
|
||||
import {
|
||||
tagRollDice,
|
||||
colorsetForPercentileRoll,
|
||||
} from "../integrations/dice-so-nice.js";
|
||||
|
||||
const { renderTemplate } = foundry.applications.handlebars;
|
||||
const { DialogV2 } = foundry.applications.api;
|
||||
@@ -260,6 +264,8 @@ export class DGPercentileRoll extends DGRoll {
|
||||
game.modules.has("dice-so-nice") &&
|
||||
game.modules.get("dice-so-nice").active;
|
||||
|
||||
tagRollDice(this, colorsetForPercentileRoll(this));
|
||||
|
||||
const label = this.createLabel();
|
||||
|
||||
let resultString = "";
|
||||
@@ -642,6 +648,8 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
tagRollDice(this, "dg2-lethality");
|
||||
|
||||
// Note: intentionally target + modifier, not effectiveTarget - a lethality
|
||||
// roll is a property of the weapon, so exhaustion penalties do not apply.
|
||||
const isLethal = this.total <= this.target + this.modifier;
|
||||
@@ -741,6 +749,8 @@ export class DGDamageRoll extends DGRoll {
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
tagRollDice(this, "dg2-lethality");
|
||||
|
||||
let label = this.formula;
|
||||
try {
|
||||
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n
|
||||
@@ -841,6 +851,8 @@ export class DGSanityDamageRoll extends DGRoll {
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
tagRollDice(this, "dg2-unnatural");
|
||||
|
||||
const [lowDie, highDie] = this.terms[0].terms.map((formula) => {
|
||||
return Roll.parse(formula)[0] || { faces: parseInt(formula), number: 1 };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user