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 bc388d94..761a369e 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 = "1.0.0"; +const MODULE_VERSION = "1.1.0"; const TRACK_SETTING = "actorSettings"; const FLAG_SCOPE = "world"; const MAX_HISTORY_ROWS = 100; @@ -923,6 +923,29 @@ function buildHistoryContent(actor, tabArg) { { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, ], }, + { + id: "damage", + label: "Damage", + flag: DAMAGE_DEALT_FLAG, + columns: [ + { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, + { label: "Dmg", render: (entry) => entry.amount != null ? `${entry.amount}` : "" }, + { + label: "Details", + render: (entry) => { + const parts = []; + if (entry.source) parts.push(entry.source); + if (entry.breakdown || entry.amount != null) { + parts.push(entry.breakdown ? entry.breakdown : `${entry.amount} damage`); + } + return parts.join(" → "); + }, + getTitle: (entry) => entry.breakdown ?? "", + }, + { label: "Target", render: (entry) => entry.target ?? "Unknown" }, + { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, + ], + }, { id: "xp", label: "XP", @@ -931,7 +954,7 @@ function buildHistoryContent(actor, tabArg) { { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, { label: "XP", render: (entry) => entry.value }, { - label: "Δ", + label: "Details", render: (entry) => entry.diff, getTitle: (entry) => buildXpBreakdownTooltip(actor, entry) }, @@ -946,7 +969,7 @@ function buildHistoryContent(actor, tabArg) { columns: [ { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, { label: "Totals", render: (entry) => entry.value }, - { label: "Δ", render: (entry) => entry.diff }, + { label: "Details", render: (entry) => entry.diff }, { label: "Source", render: (entry) => entry.source ?? "Manual" }, { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, ], @@ -973,22 +996,6 @@ function buildHistoryContent(actor, tabArg) { }, ], }, - { - id: "damage", - label: "Damage", - flag: DAMAGE_DEALT_FLAG, - columns: [ - { label: "Timestamp", render: (entry) => formatDate(entry.timestamp) }, - { label: "Dmg", render: (entry) => entry.amount != null ? `${entry.amount}` : "" }, - { - label: "?", - render: (entry) => entry.source ?? "", - getTitle: (entry) => entry.breakdown ?? "", - }, - { label: "Target", render: (entry) => entry.target ?? "Unknown" }, - { label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" }, - ], - }, ]; const tabs = configs @@ -1212,7 +1219,7 @@ async function recordHistoryEntry(actor, statId, previous, nextValue, userId, op // Also record outgoing damage for the attacker (damage dealt history) try { const metadata = matchedMessage.message?.flags?.pf1?.metadata ?? {}; - const attacker = resolveActorFromMetadata(metadata); + const attacker = resolveActorFromMetadataSafe(metadata); if (attacker) { const dealtEntry = { timestamp: Date.now(), @@ -1494,6 +1501,21 @@ function computeEncounterXp(encounter) { return { monsters, monsterTotalXp, players, playerCount, perActorMonsterXp }; } +function resolveActorFromMetadataSafe(metadata = {}) { + if (!metadata.actor) return null; + try { + if (typeof fromUuidSync === "function") { + const doc = fromUuidSync(metadata.actor); + if (doc instanceof Actor) return doc; + if (doc?.actor instanceof Actor) return doc.actor; + } + } catch (e) { + // ignore + } + const id = String(metadata.actor).split(".").pop(); + return game.actors.get(id) ?? null; +} + async function recordDamageDealt(attacker, entry) { if (!attacker?.id) return; try { @@ -1998,3 +2020,6 @@ function sendChatNotification(statId, actor, previous, nextValue, entry) { speaker: { alias: "Tracking Ledger" }, }).catch((err) => console.error("Tracking Ledger | Failed to post chat notification", err)); } + + +