feat(gowlers-tracking-ledger): add source detection and change user to source column
- Replace 'User' column with 'Source' column in HP, XP, and Currency tabs - Add automatic source detection: Attack, Spell, Healing, Damage, XP Award, Manual - Pass options and change data to recordHistoryEntry for source detection - Detects source based on pf1DamageData, healing flag, spell action type, and value changes - Defaults to 'Manual' for direct edits - Update version to 0.1.12 Now you can see what caused each stat change (attack, spell, healing, etc) in the tracking ledger instead of just the user who made the change. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
const MODULE_ID = "gowlers-tracking-ledger";
|
const MODULE_ID = "gowlers-tracking-ledger";
|
||||||
const MODULE_VERSION = "0.1.11";
|
const MODULE_VERSION = "0.1.12";
|
||||||
const TRACK_SETTING = "actorSettings";
|
const TRACK_SETTING = "actorSettings";
|
||||||
const FLAG_SCOPE = "world";
|
const FLAG_SCOPE = "world";
|
||||||
const MAX_HISTORY_ROWS = 100;
|
const MAX_HISTORY_ROWS = 100;
|
||||||
@@ -214,7 +214,7 @@ function handleActorUpdate(actor, change, options, userId) {
|
|||||||
const previous = baselines[statId];
|
const previous = baselines[statId];
|
||||||
baselines[statId] = config.clone(nextValue);
|
baselines[statId] = config.clone(nextValue);
|
||||||
changed = true;
|
changed = true;
|
||||||
recordHistoryEntry(actor, statId, previous, nextValue, userId).catch((err) =>
|
recordHistoryEntry(actor, statId, previous, nextValue, userId, options, change).catch((err) =>
|
||||||
console.error(`Tracking Ledger | Failed to append ${statId} entry`, err)
|
console.error(`Tracking Ledger | Failed to append ${statId} entry`, err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -431,7 +431,7 @@ function buildHistoryContent(actor, tabArg) {
|
|||||||
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
||||||
{ label: "HP", render: (entry) => entry.value },
|
{ label: "HP", render: (entry) => entry.value },
|
||||||
{ label: "Δ", render: (entry) => entry.diff },
|
{ label: "Δ", render: (entry) => entry.diff },
|
||||||
{ label: "User", render: (entry) => entry.user ?? "" },
|
{ label: "Source", render: (entry) => entry.source ?? "Manual" },
|
||||||
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -443,7 +443,7 @@ function buildHistoryContent(actor, tabArg) {
|
|||||||
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
||||||
{ label: "XP", render: (entry) => entry.value },
|
{ label: "XP", render: (entry) => entry.value },
|
||||||
{ label: "Δ", render: (entry) => entry.diff },
|
{ label: "Δ", render: (entry) => entry.diff },
|
||||||
{ label: "User", render: (entry) => entry.user ?? "" },
|
{ label: "Source", render: (entry) => entry.source ?? "Manual" },
|
||||||
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -455,7 +455,7 @@ function buildHistoryContent(actor, tabArg) {
|
|||||||
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
{ label: "Timestamp", render: (entry) => formatDate(entry.timestamp) },
|
||||||
{ label: "Totals", render: (entry) => entry.value },
|
{ label: "Totals", render: (entry) => entry.value },
|
||||||
{ label: "Δ", render: (entry) => entry.diff },
|
{ label: "Δ", render: (entry) => entry.diff },
|
||||||
{ label: "User", render: (entry) => entry.user ?? "" },
|
{ label: "Source", render: (entry) => entry.source ?? "Manual" },
|
||||||
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
{ label: "Encounter", render: (entry) => entry.encounterId ? entry.encounterId.slice(0, 8) : "N/A" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -542,7 +542,7 @@ function renderHistoryTable(entries, columns, id) {
|
|||||||
</table>`;
|
</table>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function recordHistoryEntry(actor, statId, previous, nextValue, userId) {
|
async function recordHistoryEntry(actor, statId, previous, nextValue, userId, options = {}, change = {}) {
|
||||||
const config = STAT_CONFIGS[statId];
|
const config = STAT_CONFIGS[statId];
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
|
|
||||||
@@ -564,12 +564,32 @@ async function recordHistoryEntry(actor, statId, previous, nextValue, userId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect source of the change
|
||||||
|
let source = "Manual";
|
||||||
|
if (options?.pf1DamageData) {
|
||||||
|
source = "Attack";
|
||||||
|
} else if (options?.healing) {
|
||||||
|
source = "Healing";
|
||||||
|
} else if (options?.pf1?.actionType === "spell") {
|
||||||
|
source = "Spell";
|
||||||
|
} else if (statId === "xp" && diffValue > 0) {
|
||||||
|
source = "XP Award";
|
||||||
|
} else if (statId === "hp") {
|
||||||
|
// Check if it's damage or healing based on the diff
|
||||||
|
const hpDiff = parseInt(diffValue);
|
||||||
|
if (hpDiff < 0) {
|
||||||
|
source = "Damage";
|
||||||
|
} else if (hpDiff > 0) {
|
||||||
|
source = "Healing";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
value: config.formatValue(nextValue),
|
value: config.formatValue(nextValue),
|
||||||
diff: config.formatDiff(diffValue),
|
diff: config.formatDiff(diffValue),
|
||||||
user: game.users.get(userId)?.name ?? "System",
|
user: game.users.get(userId)?.name ?? "System",
|
||||||
source: "",
|
source: source,
|
||||||
encounterId: encounterId,
|
encounterId: encounterId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"title": "Gowler's Tracking Ledger",
|
"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.",
|
"description": "Adds HP/XP/Currency log buttons to PF1 sheets and opens the tracking dialog preloaded with the actor's logs.",
|
||||||
"version": "0.1.11",
|
"version": "0.1.12",
|
||||||
"authors": [
|
"authors": [
|
||||||
{ "name": "Gowler", "url": "https://foundryvtt.com" }
|
{ "name": "Gowler", "url": "https://foundryvtt.com" }
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user