Advertisement
Guest User

Untitled

a guest
Aug 16th, 2024
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.93 KB | None | 0 0
  1. // Function to apply regeneration
  2. async function applyRegeneration(actor, amount) {
  3. // Get the current and max HP values
  4. const currentHP = actor.system.derivedStats.hp.value;
  5. const maxHP = actor.system.derivedStats.hp.max;
  6.  
  7. // Calculate the new HP value
  8. const newHP = Math.min(currentHP + amount, maxHP);
  9.  
  10. // Update the actor's HP
  11. await actor.update({
  12. 'system.derivedStats.hp.value': newHP
  13. });
  14.  
  15. // Inform the user
  16. ChatMessage.create({
  17. content: `${actor.name} regenerates ${amount} HP!`,
  18. speaker: ChatMessage.getSpeaker({ actor: actor })
  19. });
  20. }
  21.  
  22. // Function to create and display the dialog
  23. function showRegenerationDialog() {
  24. new Dialog({
  25. title: "Apply Regeneration Effect",
  26. content: `
  27. <form>
  28. <div class="form-group">
  29. <label for="rounds">Number of Rounds:</label>
  30. <input id="rounds" name="rounds" type="number" min="1" step="1" value="1" />
  31. </div>
  32. <div class="form-group">
  33. <label for="amount">Regeneration Amount:</label>
  34. <input id="amount" name="amount" type="number" min="1" step="1" value="3" />
  35. </div>
  36. </form>
  37. `,
  38. buttons: {
  39. apply: {
  40. label: "Apply",
  41. callback: async (html) => {
  42. const rounds = parseInt(html.find('#rounds').val(), 10);
  43. const amount = parseInt(html.find('#amount').val(), 10);
  44.  
  45. if (isNaN(rounds) || isNaN(amount) || rounds <= 0 || amount <= 0) {
  46. ui.notifications.error("Invalid input values.");
  47. return;
  48. }
  49.  
  50. const token = canvas.tokens.controlled[0];
  51. if (!token) {
  52. ui.notifications.warn("Please select a token first.");
  53. return;
  54. }
  55.  
  56. const actor = token.actor;
  57.  
  58. // Define the regeneration effect
  59. const regenerationEffect = {
  60. name: "Regeneration",
  61. icon: "icons/svg/regen.svg",
  62. origin: actor.uuid,
  63. disabled: false,
  64. duration: { rounds: rounds, startRound: game.combat?.round, startTime: game.time.worldTime },
  65. flags: {
  66. custom: { regenDamageHookId: null }
  67. },
  68. changes: []
  69. };
  70.  
  71. // Check if the regeneration effect is already applied
  72. let existingEffect = actor.effects.find(e => e.name === regenerationEffect.name);
  73.  
  74. if (existingEffect) {
  75. console.log(`Removing ongoing effect: ${regenerationEffect.name}`);
  76.  
  77. // Remove the combat hook
  78. try {
  79. const hookId = existingEffect.flags.custom?.regenDamageHookId;
  80. if (hookId) {
  81. Hooks.off("updateCombat", hookId);
  82. console.log(`Removed combat hook with ID: ${hookId}`);
  83. }
  84. } catch (error) {
  85. console.error("Failed to get flag 'custom' or flag does not exist.", error);
  86. }
  87.  
  88. // Remove the effect from the actor
  89. await actor.deleteEmbeddedDocuments("ActiveEffect", [existingEffect.id]);
  90. } else {
  91. console.log(`Applying ongoing effect: ${regenerationEffect.name}`);
  92. regenerationEffect.origin = actor.uuid; // Set the origin to the actor's UUID
  93.  
  94. // Create the effect on the actor
  95. const createdEffect = await actor.createEmbeddedDocuments("ActiveEffect", [regenerationEffect]);
  96. const effectId = createdEffect[0].id;
  97.  
  98. // Set up a hook to apply regeneration at the start of the affected token's turn
  99. const hookId = Hooks.on("updateCombat", (combat, update, options, userId) => {
  100. const combatant = combat.combatants.find(c => c.tokenId === token.id);
  101.  
  102. // If it's the start of the token's turn
  103. if (combatant && combatant.tokenId === combat.current.tokenId && combat.turns[combat.turn].tokenId === token.id) {
  104. // Apply regeneration
  105. applyRegeneration(actor, amount);
  106. console.log(`Applying regeneration to ${token.name}`);
  107. }
  108. });
  109.  
  110. console.log(`Created combat hook with ID: ${hookId}`);
  111.  
  112. // Store the hook ID in the effect so we can remove it later
  113. try {
  114. await actor.updateEmbeddedDocuments("ActiveEffect", [{
  115. _id: effectId,
  116. "flags.custom.regenDamageHookId": hookId
  117. }]);
  118. } catch (error) {
  119. console.error("Failed to update flag 'custom' with hookId.", error);
  120. }
  121. }
  122. }
  123. },
  124. cancel: {
  125. label: "Cancel"
  126. }
  127. },
  128. default: "apply"
  129. }).render(true);
  130. }
  131.  
  132. // Function to remove expired regeneration effects
  133. async function removeExpiredRegenerationEffects(actor) {
  134. const currentRound = game.combat?.round || 0;
  135.  
  136. const effects = actor.effects.filter(effect => effect.name === "Regeneration");
  137. for (const effect of effects) {
  138. const endRound = effect.duration.startRound + effect.duration.rounds;
  139. if (currentRound >= endRound) {
  140. console.log(`Removing expired effect: ${effect.name}`);
  141. // Remove the combat hook if it exists
  142. const hookId = effect.flags.custom?.regenDamageHookId;
  143. if (hookId) {
  144. Hooks.off("updateCombat", hookId);
  145. console.log(`Removed combat hook with ID: ${hookId}`);
  146. }
  147. // Remove the effect from the actor
  148. await actor.deleteEmbeddedDocuments("ActiveEffect", [effect.id]);
  149. }
  150. }
  151. }
  152.  
  153. // Run the dialog function
  154. showRegenerationDialog();
  155.  
  156. // Periodically remove expired effects (for example, at the start of each round)
  157. Hooks.on("updateCombat", (combat) => {
  158. const tokens = canvas.tokens.placeables.filter(t => t.actor);
  159. for (const token of tokens) {
  160. removeExpiredRegenerationEffects(token.actor);
  161. }
  162. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement