Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- on("ready", () => {
- let rechargeTracker = {}; // Tracks recharge needs for each token
- const setupTracker = new Set(); // Tracks tokens that have been initialized
- const nonRechargeTokens = new Set(); // Tokens that have no recharge abilities
- let activeTokenId = null; // Tracks the current token in the turn order
- let combatStarted = false; // Tracks whether combat has started with !startcombat
- // Command: Start combat, resetting tracking for a new encounter and prompting immediately if possible
- on("chat:message", (msg) => {
- if (msg.type === "api" && msg.content.toLowerCase() === "!startcombat") {
- resetCombat(false); // Reset combat settings
- combatStarted = true; // Mark combat as started
- promptFirstTurnRecharge(); // Immediately check the first turn
- }
- if (msg.type === "api" && msg.content.toLowerCase() === "!endcombat") {
- resetCombat(false); // Silently reset on `!endcombat` command
- combatStarted = false; // Mark combat as ended
- }
- });
- // Function: Checks the first turn after `!startcombat` and prompts recharge abilities if present
- function promptFirstTurnRecharge() {
- const turnOrder = JSON.parse(Campaign().get("turnorder") || "[]");
- if (turnOrder.length === 0) return;
- const firstTurn = turnOrder[0];
- const tokenId = firstTurn.id;
- if (!setupTracker.has(tokenId)) setupRechargeAbilities(tokenId); // Setup abilities if not done yet
- // Only prompt if the token has recharge abilities
- if (rechargeTracker[tokenId] && Object.keys(rechargeTracker[tokenId].abilities).length > 0) {
- promptRechargeAbilities(tokenId); // Prompt recharge abilities for the first creature in combat
- }
- }
- // Detects turn changes in the turn order and handles prompts for recharge abilities
- on("change:campaign:turnorder", () => {
- const turnOrder = JSON.parse(Campaign().get("turnorder") || "[]");
- if (turnOrder.length === 0) return; // End early if no active turn order
- const currentTurn = turnOrder[0];
- const tokenId = currentTurn.id;
- const token = getObj("graphic", tokenId);
- if (!token || !token.get("represents")) return; // Skip if no valid token
- activeTokenId = tokenId; // Update the active token ID for recharge detection
- // Initialize the token's abilities if not set up yet
- if (!setupTracker.has(tokenId)) {
- setupRechargeAbilities(tokenId);
- setupTracker.add(tokenId);
- }
- // Only prompt if the token has recharge abilities
- if (rechargeTracker[tokenId] && Object.keys(rechargeTracker[tokenId].abilities).length > 0) {
- if (rechargeTracker[tokenId].needsRechargeRoll) {
- rollRecharge(tokenId);
- } else {
- promptRechargeAbilities(tokenId); // Display available abilities otherwise
- }
- }
- });
- // Sets up recharge abilities for tokens, tracking those without recharge
- function setupRechargeAbilities(tokenId) {
- const characterId = getObj("graphic", tokenId).get("represents");
- if (!characterId) return;
- const abilities = findObjs({ _type: "ability", _characterid: characterId });
- const rechargeAbilities = abilities.filter(ability => /\(r\d(?:-\d)?\)/i.test(ability.get("name")));
- if (rechargeAbilities.length > 0) {
- rechargeTracker[tokenId] = { needsRechargeRoll: false, abilities: {} };
- rechargeAbilities.forEach(action => {
- const actionName = action.get("name").replace(/\(r\d(?:-\d)?\)/, "").trim().replace(/-$/, "");
- const rechargePattern = action.get("name").match(/\(r(\d(?:-\d)?)\)/i)[1];
- rechargeTracker[tokenId].abilities[action.get("_id")] = { name: actionName, rechargePattern: rechargePattern };
- });
- } else {
- nonRechargeTokens.add(tokenId); // Track non-recharge tokens to avoid unnecessary checks
- }
- }
- // Prompt GM with available recharge abilities for a token's turn
- function promptRechargeAbilities(tokenId) {
- if (!rechargeTracker[tokenId] || Object.keys(rechargeTracker[tokenId].abilities).length === 0) return;
- const characterId = getObj("graphic", tokenId).get("represents");
- const character = getObj("character", characterId);
- if (!character) return;
- const characterName = character.get("name");
- let message = `&{template:default} {{name=${characterName} Recharge Abilities}}`;
- for (const actionId in rechargeTracker[tokenId].abilities) {
- const action = rechargeTracker[tokenId].abilities[actionId];
- const formattedActionName = action.name.charAt(0).toUpperCase() + action.name.slice(1);
- message += `{{[${formattedActionName}](~${characterId}|${actionId})}}`;
- }
- sendChat("Recharge Tracker", `/w gm ${message}`);
- }
- // Parses chat messages for ability usage and sets flag for recharge rolls
- on("chat:message", (msg) => {
- if (msg.type === "general" && activeTokenId && msg.who !== "Recharge Tracker") {
- detectRechargeAbilityUsage(msg.content, activeTokenId);
- }
- });
- // Detects and flags used recharge abilities based on chat message content
- function detectRechargeAbilityUsage(content, tokenId) {
- const characterId = getObj("graphic", tokenId).get("represents");
- const rechargeAbilities = rechargeTracker[tokenId]?.abilities || {};
- for (const actionId in rechargeAbilities) {
- const action = rechargeAbilities[actionId];
- const regexSafeActionName = action.name.replace(/[^a-zA-Z0-9\s]/g, "").toLowerCase();
- const cleanedContent = content.replace(/[^a-zA-Z0-9\s]/g, "").toLowerCase();
- if (cleanedContent.includes(regexSafeActionName) && !rechargeTracker[tokenId].needsRechargeRoll) {
- rechargeTracker[tokenId].needsRechargeRoll = true; // Set flag for roll on next turn
- }
- }
- }
- // Rolls for recharge abilities based on their specific pattern
- function rollRecharge(tokenId) {
- const characterId = getObj("graphic", tokenId).get("represents");
- const character = getObj("character", characterId);
- if (!character) return;
- const rechargeRoll = randomInteger(6);
- let rechargeSuccessful = false;
- const rechargedAbilities = [];
- // Determine recharge success based on ability patterns
- for (const actionId in rechargeTracker[tokenId].abilities) {
- const action = rechargeTracker[tokenId].abilities[actionId];
- const rechargePattern = action.rechargePattern;
- if (rechargePattern.includes("-")) {
- const [min, max] = rechargePattern.split("-").map(Number);
- if (rechargeRoll >= min && rechargeRoll <= max) {
- rechargeSuccessful = true;
- rechargedAbilities.push(actionId);
- }
- } else if (parseInt(rechargePattern) === rechargeRoll) {
- rechargeSuccessful = true;
- rechargedAbilities.push(actionId);
- }
- }
- // Display recharge results
- const resultMessage = rechargeSuccessful
- ? `🎉 Success! Recharged abilities are ready to use again.`
- : `❌ Failure. No abilities recharged on a ${rechargeRoll}.`;
- sendChat("Recharge Tracker", `&{template:default} {{name=Recharge Roll for ${character.get("name")}}} {{Roll=${rechargeRoll}}} {{Result=${resultMessage}}}`);
- if (rechargeSuccessful) {
- rechargeTracker[tokenId].needsRechargeRoll = false;
- promptRechargedAbilities(tokenId, rechargedAbilities);
- }
- }
- // Prompts recharged abilities for immediate reuse
- function promptRechargedAbilities(tokenId, rechargedAbilities) {
- const characterId = getObj("graphic", tokenId).get("represents");
- const character = getObj("character", characterId);
- if (!character) return;
- const characterName = character.get("name");
- let message = `&{template:default} {{name=${characterName} Recharged Abilities}}`;
- rechargedAbilities.forEach(actionId => {
- const action = rechargeTracker[tokenId].abilities[actionId];
- message += `{{[${action.name}](~${characterId}|${actionId})}}`;
- });
- sendChat("Recharge Tracker", `/w gm ${message}`);
- }
- // Resets all tracking data for a new combat session
- function resetCombat(showMessage = true) {
- rechargeTracker = {};
- setupTracker.clear();
- nonRechargeTokens.clear();
- activeTokenId = null;
- combatStarted = false;
- }
- });
Add Comment
Please, Sign In to add comment