From 26a9a7fb08df8041b3fa4a54f12c9e6bfb22dfa3 Mon Sep 17 00:00:00 2001 From: "centron\\schwoerer" Date: Thu, 20 Nov 2025 14:44:28 +0100 Subject: [PATCH] feat(gowlers-tracking-ledger): add damage detail extraction for type and breakdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add extractDamageDetails() function to parse damage type from message - Extract critical hit flags and nonlethal damage flags from options - Attempt to extract roll formula/breakdown from message.rolls - Store damage details in recentMessages queue for later matching - Add comprehensive console logging to inspect available message data This enables extraction of: - Damage types (Fire, Slashing, etc.) - Critical hit information - Nonlethal damage flags - Damage roll breakdown formulas Detailed logging will show what data is available in PF1 message objects for further refinement of extraction logic. Update version to 0.1.20 🤖 Generated with Claude Code Co-Authored-By: Claude --- .../scripts/gowlers-tracking-ledger.js | 76 ++++++++++++++++++- .../gowlers-tracking-ledger/module.json | 2 +- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js b/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js index 5a1a4973..b8dbdd04 100644 --- a/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js +++ b/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js @@ -1,6 +1,6 @@ const MODULE_ID = "gowlers-tracking-ledger"; -const MODULE_VERSION = "0.1.19"; +const MODULE_VERSION = "0.1.20"; const TRACK_SETTING = "actorSettings"; const FLAG_SCOPE = "world"; const MAX_HISTORY_ROWS = 100; @@ -239,10 +239,15 @@ async function initializeModule() { const source = buildSourceLabel(value, options); console.log("[GowlersTracking] Storing message for matching: source=", source, "value=", value); + // Extract damage details for breakdown information + const damageDetails = extractDamageDetails(value, options); + console.log("[GowlersTracking] Damage details extracted:", damageDetails); + ledgerState.recentMessages.push({ message: message, source: source, value: value, // Keep sign! Negative = damage, Positive = healing + damageDetails: damageDetails, timestamp: Date.now(), }); @@ -358,6 +363,75 @@ async function initializeModule() { return actor.items.get(metadata.item) ?? null; } + // Helper: Extract damage type and breakdown details from message + function extractDamageDetails(value, options = {}) { + const message = options?.message; + if (!message) return null; + + // Try to extract from PF1 flags + const pf1Flags = message.flags?.pf1 ?? {}; + const metadata = pf1Flags.metadata ?? {}; + + // Extract damage types from metadata or message content + const damageTypes = []; + + // Check for damage type data in metadata + if (metadata.damageTypes) { + if (Array.isArray(metadata.damageTypes)) { + damageTypes.push(...metadata.damageTypes); + } else if (typeof metadata.damageTypes === 'string') { + damageTypes.push(metadata.damageTypes); + } + } + + // Try to parse damage types from message content (HTML) + if (message.content && damageTypes.length === 0) { + // Look for damage type patterns in HTML + const contentMatch = message.content.match(/]*>.*?(Untyped|Slashing|Piercing|Bludgeoning|Fire|Cold|Electricity|Acid|Sonic|Force|Negative|Positive|Water)[^<]*<\/li>/gi); + if (contentMatch) { + contentMatch.forEach(match => { + const type = match.replace(/<[^>]*>/g, '').trim(); + if (type && !damageTypes.includes(type)) { + damageTypes.push(type); + } + }); + } + } + + // Extract critical hit flag + const isCritical = options?.isCritical ?? false; + const critMultiplier = options?.critMult ?? 1; + + // Extract nonlethal flag + const asNonlethal = options?.asNonlethal ?? false; + + // Try to extract damage breakdown from rolls + let breakdown = null; + if (message.rolls && message.rolls.length > 0) { + try { + const roll = message.rolls[0]; + breakdown = roll.formula ?? roll.toString?.() ?? null; + } catch (err) { + console.warn("[GowlersTracking] Failed to extract roll breakdown:", err); + } + } + + // Log detailed inspection for debugging + console.log("[GowlersTracking] Message inspection for damage details:"); + console.log("[GowlersTracking] - pf1Flags keys:", Object.keys(pf1Flags)); + console.log("[GowlersTracking] - metadata:", metadata); + console.log("[GowlersTracking] - message.rolls:", message.rolls?.length > 0 ? "Present" : "None"); + console.log("[GowlersTracking] - message.content length:", message.content?.length ?? 0); + + return { + types: damageTypes.length > 0 ? damageTypes : null, + isCritical, + critMultiplier, + asNonlethal, + breakdown, + }; + } + // Helper: Record damage source for later consumption function noteDamageSource(value, options = {}) { const actor = this; // 'this' is the actor whose HP is changing diff --git a/src/macros_new/gowlers-tracking-ledger/module.json b/src/macros_new/gowlers-tracking-ledger/module.json index a899c181..b4b18be6 100644 --- a/src/macros_new/gowlers-tracking-ledger/module.json +++ b/src/macros_new/gowlers-tracking-ledger/module.json @@ -3,7 +3,7 @@ "type": "module", "title": "Gowler's Tracking Ledger", "description": "Adds HP/XP/Currency log buttons to PF1 sheets and opens the tracking dialog preloaded with the actor's logs.", - "version": "0.1.19", + "version": "0.1.20", "authors": [ { "name": "Gowler", "url": "https://foundryvtt.com" } ],