Guest User

RechargeTracker

a guest
Oct 29th, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.89 KB | None | 0 0
  1. on("ready", () => {
  2. let rechargeTracker = {}; // Tracks recharge needs for each token
  3. const setupTracker = new Set(); // Tracks tokens that have been initialized
  4. const nonRechargeTokens = new Set(); // Tokens that have no recharge abilities
  5. let activeTokenId = null; // Tracks the current token in the turn order
  6. let combatStarted = false; // Tracks whether combat has started with !startcombat
  7.  
  8. // Command: Start combat, resetting tracking for a new encounter and prompting immediately if possible
  9. on("chat:message", (msg) => {
  10. if (msg.type === "api" && msg.content.toLowerCase() === "!startcombat") {
  11. resetCombat(false); // Reset combat settings
  12. combatStarted = true; // Mark combat as started
  13. promptFirstTurnRecharge(); // Immediately check the first turn
  14. }
  15.  
  16. if (msg.type === "api" && msg.content.toLowerCase() === "!endcombat") {
  17. resetCombat(false); // Silently reset on `!endcombat` command
  18. combatStarted = false; // Mark combat as ended
  19. }
  20. });
  21.  
  22. // Function: Checks the first turn after `!startcombat` and prompts recharge abilities if present
  23. function promptFirstTurnRecharge() {
  24. const turnOrder = JSON.parse(Campaign().get("turnorder") || "[]");
  25. if (turnOrder.length === 0) return;
  26.  
  27. const firstTurn = turnOrder[0];
  28. const tokenId = firstTurn.id;
  29.  
  30. if (!setupTracker.has(tokenId)) setupRechargeAbilities(tokenId); // Setup abilities if not done yet
  31.  
  32. // Only prompt if the token has recharge abilities
  33. if (rechargeTracker[tokenId] && Object.keys(rechargeTracker[tokenId].abilities).length > 0) {
  34. promptRechargeAbilities(tokenId); // Prompt recharge abilities for the first creature in combat
  35. }
  36. }
  37.  
  38. // Detects turn changes in the turn order and handles prompts for recharge abilities
  39. on("change:campaign:turnorder", () => {
  40. const turnOrder = JSON.parse(Campaign().get("turnorder") || "[]");
  41. if (turnOrder.length === 0) return; // End early if no active turn order
  42.  
  43. const currentTurn = turnOrder[0];
  44. const tokenId = currentTurn.id;
  45.  
  46. const token = getObj("graphic", tokenId);
  47. if (!token || !token.get("represents")) return; // Skip if no valid token
  48.  
  49. activeTokenId = tokenId; // Update the active token ID for recharge detection
  50.  
  51. // Initialize the token's abilities if not set up yet
  52. if (!setupTracker.has(tokenId)) {
  53. setupRechargeAbilities(tokenId);
  54. setupTracker.add(tokenId);
  55. }
  56.  
  57. // Only prompt if the token has recharge abilities
  58. if (rechargeTracker[tokenId] && Object.keys(rechargeTracker[tokenId].abilities).length > 0) {
  59. if (rechargeTracker[tokenId].needsRechargeRoll) {
  60. rollRecharge(tokenId);
  61. } else {
  62. promptRechargeAbilities(tokenId); // Display available abilities otherwise
  63. }
  64. }
  65. });
  66.  
  67. // Sets up recharge abilities for tokens, tracking those without recharge
  68. function setupRechargeAbilities(tokenId) {
  69. const characterId = getObj("graphic", tokenId).get("represents");
  70. if (!characterId) return;
  71.  
  72. const abilities = findObjs({ _type: "ability", _characterid: characterId });
  73. const rechargeAbilities = abilities.filter(ability => /\(r\d(?:-\d)?\)/i.test(ability.get("name")));
  74.  
  75. if (rechargeAbilities.length > 0) {
  76. rechargeTracker[tokenId] = { needsRechargeRoll: false, abilities: {} };
  77. rechargeAbilities.forEach(action => {
  78. const actionName = action.get("name").replace(/\(r\d(?:-\d)?\)/, "").trim().replace(/-$/, "");
  79. const rechargePattern = action.get("name").match(/\(r(\d(?:-\d)?)\)/i)[1];
  80. rechargeTracker[tokenId].abilities[action.get("_id")] = { name: actionName, rechargePattern: rechargePattern };
  81. });
  82. } else {
  83. nonRechargeTokens.add(tokenId); // Track non-recharge tokens to avoid unnecessary checks
  84. }
  85. }
  86.  
  87. // Prompt GM with available recharge abilities for a token's turn
  88. function promptRechargeAbilities(tokenId) {
  89. if (!rechargeTracker[tokenId] || Object.keys(rechargeTracker[tokenId].abilities).length === 0) return;
  90.  
  91. const characterId = getObj("graphic", tokenId).get("represents");
  92. const character = getObj("character", characterId);
  93. if (!character) return;
  94.  
  95. const characterName = character.get("name");
  96. let message = `&{template:default} {{name=${characterName} Recharge Abilities}}`;
  97.  
  98. for (const actionId in rechargeTracker[tokenId].abilities) {
  99. const action = rechargeTracker[tokenId].abilities[actionId];
  100. const formattedActionName = action.name.charAt(0).toUpperCase() + action.name.slice(1);
  101. message += `{{[${formattedActionName}](~${characterId}|${actionId})}}`;
  102. }
  103.  
  104. sendChat("Recharge Tracker", `/w gm ${message}`);
  105. }
  106.  
  107. // Parses chat messages for ability usage and sets flag for recharge rolls
  108. on("chat:message", (msg) => {
  109. if (msg.type === "general" && activeTokenId && msg.who !== "Recharge Tracker") {
  110. detectRechargeAbilityUsage(msg.content, activeTokenId);
  111. }
  112. });
  113.  
  114. // Detects and flags used recharge abilities based on chat message content
  115. function detectRechargeAbilityUsage(content, tokenId) {
  116. const characterId = getObj("graphic", tokenId).get("represents");
  117. const rechargeAbilities = rechargeTracker[tokenId]?.abilities || {};
  118.  
  119. for (const actionId in rechargeAbilities) {
  120. const action = rechargeAbilities[actionId];
  121. const regexSafeActionName = action.name.replace(/[^a-zA-Z0-9\s]/g, "").toLowerCase();
  122. const cleanedContent = content.replace(/[^a-zA-Z0-9\s]/g, "").toLowerCase();
  123.  
  124. if (cleanedContent.includes(regexSafeActionName) && !rechargeTracker[tokenId].needsRechargeRoll) {
  125. rechargeTracker[tokenId].needsRechargeRoll = true; // Set flag for roll on next turn
  126. }
  127. }
  128. }
  129.  
  130. // Rolls for recharge abilities based on their specific pattern
  131. function rollRecharge(tokenId) {
  132. const characterId = getObj("graphic", tokenId).get("represents");
  133. const character = getObj("character", characterId);
  134. if (!character) return;
  135.  
  136. const rechargeRoll = randomInteger(6);
  137. let rechargeSuccessful = false;
  138. const rechargedAbilities = [];
  139.  
  140. // Determine recharge success based on ability patterns
  141. for (const actionId in rechargeTracker[tokenId].abilities) {
  142. const action = rechargeTracker[tokenId].abilities[actionId];
  143. const rechargePattern = action.rechargePattern;
  144.  
  145. if (rechargePattern.includes("-")) {
  146. const [min, max] = rechargePattern.split("-").map(Number);
  147. if (rechargeRoll >= min && rechargeRoll <= max) {
  148. rechargeSuccessful = true;
  149. rechargedAbilities.push(actionId);
  150. }
  151. } else if (parseInt(rechargePattern) === rechargeRoll) {
  152. rechargeSuccessful = true;
  153. rechargedAbilities.push(actionId);
  154. }
  155. }
  156.  
  157. // Display recharge results
  158. const resultMessage = rechargeSuccessful
  159. ? `🎉 Success! Recharged abilities are ready to use again.`
  160. : `❌ Failure. No abilities recharged on a ${rechargeRoll}.`;
  161.  
  162. sendChat("Recharge Tracker", `&{template:default} {{name=Recharge Roll for ${character.get("name")}}} {{Roll=${rechargeRoll}}} {{Result=${resultMessage}}}`);
  163.  
  164. if (rechargeSuccessful) {
  165. rechargeTracker[tokenId].needsRechargeRoll = false;
  166. promptRechargedAbilities(tokenId, rechargedAbilities);
  167. }
  168. }
  169.  
  170. // Prompts recharged abilities for immediate reuse
  171. function promptRechargedAbilities(tokenId, rechargedAbilities) {
  172. const characterId = getObj("graphic", tokenId).get("represents");
  173. const character = getObj("character", characterId);
  174. if (!character) return;
  175.  
  176. const characterName = character.get("name");
  177. let message = `&{template:default} {{name=${characterName} Recharged Abilities}}`;
  178.  
  179. rechargedAbilities.forEach(actionId => {
  180. const action = rechargeTracker[tokenId].abilities[actionId];
  181. message += `{{[${action.name}](~${characterId}|${actionId})}}`;
  182. });
  183.  
  184. sendChat("Recharge Tracker", `/w gm ${message}`);
  185. }
  186.  
  187. // Resets all tracking data for a new combat session
  188. function resetCombat(showMessage = true) {
  189. rechargeTracker = {};
  190. setupTracker.clear();
  191. nonRechargeTokens.clear();
  192. activeTokenId = null;
  193. combatStarted = false;
  194. }
  195. });
  196.  
Add Comment
Please, Sign In to add comment