roll string generated

main
Matt Huntington 1 month ago
parent 894bf79945
commit 95a4f51fdb

@ -21,8 +21,96 @@ Hooks.on("createChatMessage", async (chatData, options, userId) => {
if (chatData.speaker?.alias === 'AI DM') return if (chatData.speaker?.alias === 'AI DM') return
if(chatData.isRoll){ if(chatData.isRoll){
console.log(chatData); console.log(chatData);
const parts = [];
const speaker = chatData.speaker?.alias || "Someone";
const flavor = chatData.flavor || "";
const pf2eFlags = chatData.flags?.pf2e || {};
const pf2eContext = pf2eFlags.context || {};
// Who rolled
parts.push(`${speaker}`);
// What type of roll (PF2E-specific context)
// pf2eContext.type can be: "skill-check", "attack-roll", "damage-roll",
// "saving-throw", "perception-check", "flat-check", "initiative", etc.
if (pf2eContext.type) {
parts.push(`made a ${pf2eContext.type.replace(/-/g, " ")}`);
} else if (flavor) {
parts.push(`rolled ${flavor.replace(/<[^>]*>/g, "")}`); // strip HTML tags
} else {
parts.push("rolled");
}
// What action/item triggered the roll (e.g. "Longsword", "Perception", "Fireball")
const origin = pf2eFlags.origin;
if (origin?.type && origin?.sourceId) {
parts.push(`using ${origin.type}`);
}
// The strike info if it's an attack
if (pf2eFlags.strike) {
const strike = pf2eFlags.strike;
if (strike.name) parts.push(`(${strike.name})`);
}
// Outcome for checks (PF2E stores degree of success)
// pf2eContext.outcome can be: "criticalSuccess", "success", "failure", "criticalFailure"
if (pf2eContext.outcome) {
const outcomeMap = {
criticalSuccess: "Critical Success",
success: "Success",
failure: "Failure",
criticalFailure: "Critical Failure"
};
parts.push(`${outcomeMap[pf2eContext.outcome] || pf2eContext.outcome}`);
}
// The actual roll numbers
const rollDetails = chatData.rolls.map(r => {
let detail = `${r.formula} = ${r.total}`;
// For damage rolls, try to extract damage types from the terms
if (pf2eContext.type === "damage-roll" && r.options?.damage?.categories) {
// Damage categories might be available
}
return detail;
}).join("; ");
parts.push(`[${rollDetails}]`);
// DC if present (PF2E often includes the target DC)
if (pf2eContext.dc !== undefined && pf2eContext.dc !== null) {
const dc = typeof pf2eContext.dc === "object" ? pf2eContext.dc.value : pf2eContext.dc;
if (dc) parts.push(`against DC ${dc}`);
}
// Target info
if (pf2eContext.target) {
const targetName = pf2eContext.target?.token?.name
|| pf2eContext.target?.actor?.name
|| null;
if (targetName) parts.push(`targeting ${targetName}`);
}
// Traits (e.g. "fire", "mental", "incapacitation")
if (pf2eContext.traits?.length > 0) {
parts.push(`(traits: ${pf2eContext.traits.join(", ")})`);
}
// Modifiers/notes from the flavor text (often contains the breakdown)
// The flavor field in PF2E often has rich HTML with modifier breakdowns
// We'll grab a clean text version as supplemental info
if (flavor) {
const cleanFlavor = flavor.replace(/<[^>]*>/g, " ").replace(/\s{2,}/g, '. ').trim();
if (cleanFlavor && !parts.some(p => p.includes(cleanFlavor))) {
parts.push(`| ${cleanFlavor}`);
}
}
const rollString = `[ROLL] ${parts.join(" ")}`;
console.log(rollString);
} }
}) })
Hooks.on("chatMessage", async (chatLog, message, chatData) => { Hooks.on("chatMessage", async (chatLog, message, chatData) => {
const formattedContent = chatData.speaker.actor ? `${chatData.speaker.alias} says, "${message}"` : message const formattedContent = chatData.speaker.actor ? `${chatData.speaker.alias} says, "${message}"` : message

Loading…
Cancel
Save