From 0ed21afba9a870faaca95f3da0588f40280ca08e Mon Sep 17 00:00:00 2001 From: "centron\\schwoerer" Date: Thu, 20 Nov 2025 11:05:43 +0100 Subject: [PATCH] feat(gowlers-tracking-ledger): add detailed source info and damage breakdown tooltips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Source column now shows attacker name and item: "Damage (Chyvvom, Binding Contracts)" - Add damage breakdown detection from pf1DamageData - Add hover tooltips to delta (Δ) column showing damage/healing breakdown - Extract damage types and values: "5 physical, 5 fire" etc. - Store damageBreakdown field in history entries - Support tooltips for HP and XP changes - Update version to 0.1.13 Now you can see detailed damage types and amounts by hovering over the delta column, and source column shows exactly who dealt the damage and with what ability. 🤖 Generated with Claude Code Co-Authored-By: Claude --- .../scripts/gowlers-tracking-ledger.js | 61 +++++++++++++++++-- .../gowlers-tracking-ledger/module.json | 2 +- 2 files changed, 56 insertions(+), 7 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 456b4ea9..c4d26dc7 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.12"; +const MODULE_VERSION = "0.1.13"; const TRACK_SETTING = "actorSettings"; const FLAG_SCOPE = "world"; const MAX_HISTORY_ROWS = 100; @@ -430,7 +430,11 @@ function buildHistoryContent(actor, tabArg) { columns: [ { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, { label: "HP", render: (entry) => entry.value }, - { label: "Δ", render: (entry) => entry.diff }, + { + label: "Δ", + render: (entry) => entry.diff, + getTitle: (entry) => entry.damageBreakdown ? `${entry.damageBreakdown}` : "" + }, { label: "Source", render: (entry) => entry.source ?? "Manual" }, { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, ], @@ -442,7 +446,11 @@ function buildHistoryContent(actor, tabArg) { columns: [ { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, { label: "XP", render: (entry) => entry.value }, - { label: "Δ", render: (entry) => entry.diff }, + { + label: "Δ", + render: (entry) => entry.diff, + getTitle: (entry) => entry.damageBreakdown ? `${entry.damageBreakdown}` : "" + }, { label: "Source", render: (entry) => entry.source ?? "Manual" }, { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, ], @@ -526,7 +534,12 @@ function renderHistoryTable(entries, columns, id) { .map( (entry) => ` - ${columns.map((col) => `${col.render(entry) ?? ""}`).join("")} + ${columns.map((col) => { + const cellContent = col.render(entry) ?? ""; + const title = col.getTitle ? col.getTitle(entry) : ""; + const titleAttr = title ? ` title="${title}"` : ""; + return `${cellContent}`; + }).join("")} ` ) .join(""); @@ -564,14 +577,42 @@ async function recordHistoryEntry(actor, statId, previous, nextValue, userId, op } } - // Detect source of the change + // Detect source of the change with actor and item details let source = "Manual"; + let sourceDetails = ""; + let damageBreakdown = ""; + if (options?.pf1DamageData) { - source = "Attack"; + // Try to get attacker actor and item information + const attackerName = options?.pf1?.attackerName || "Unknown"; + const itemName = options?.pf1?.itemName || "Attack"; + source = "Damage"; + sourceDetails = `${attackerName}, ${itemName}`; + + // Extract damage breakdown if available + if (options?.pf1DamageData?.rolls) { + const damageRolls = options.pf1DamageData.rolls; + const breakdown = []; + let total = 0; + for (const roll of damageRolls) { + if (roll.damageType && roll.value) { + breakdown.push(`${roll.value} ${roll.damageType}`); + total += parseInt(roll.value) || 0; + } + } + if (breakdown.length > 0) { + damageBreakdown = breakdown.join(", "); + } + } } else if (options?.healing) { + const healerName = options?.pf1?.healerName || "Unknown"; + const itemName = options?.pf1?.itemName || "Healing"; source = "Healing"; + sourceDetails = `${healerName}, ${itemName}`; + damageBreakdown = `Healed for ${Math.abs(diffValue)} HP`; } else if (options?.pf1?.actionType === "spell") { source = "Spell"; + sourceDetails = options?.pf1?.itemName || "Spell"; } else if (statId === "xp" && diffValue > 0) { source = "XP Award"; } else if (statId === "hp") { @@ -579,11 +620,18 @@ async function recordHistoryEntry(actor, statId, previous, nextValue, userId, op const hpDiff = parseInt(diffValue); if (hpDiff < 0) { source = "Damage"; + damageBreakdown = `${Math.abs(hpDiff)} damage`; } else if (hpDiff > 0) { source = "Healing"; + damageBreakdown = `${hpDiff} healing`; } } + // Format source with details if available + if (sourceDetails) { + source = `${source} (${sourceDetails})`; + } + const entry = { timestamp: Date.now(), value: config.formatValue(nextValue), @@ -591,6 +639,7 @@ async function recordHistoryEntry(actor, statId, previous, nextValue, userId, op user: game.users.get(userId)?.name ?? "System", source: source, encounterId: encounterId, + damageBreakdown: damageBreakdown, }; console.log(`[GowlersTracking] History entry created for ${statId}:`, entry); diff --git a/src/macros_new/gowlers-tracking-ledger/module.json b/src/macros_new/gowlers-tracking-ledger/module.json index 07fa1137..18bf548f 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.12", + "version": "0.1.13", "authors": [ { "name": "Gowler", "url": "https://foundryvtt.com" } ],