Advertisement
ms_63f9f5eaabed15e

Untitled

Aug 16th, 2024
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. // Define the fire damage effect
  2. const fireEffect = {
  3. label: "Fire",
  4. icon: "icons/svg/fire.svg",
  5. origin: null,
  6. disabled: false,
  7. duration: { rounds: 9999, startRound: game.combat?.round, startTime: game.time.worldTime },
  8. flags: {
  9. custom: { fireDamageHookId: null }
  10. },
  11. changes: []
  12. };
  13.  
  14. // Function to apply/remove the fire damage effect and hook
  15. async function toggleFireEffect() {
  16. const token = canvas.tokens.controlled[0];
  17. if (!token) {
  18. ui.notifications.warn("Please select a token first.");
  19. return;
  20. }
  21.  
  22. const actor = token.actor;
  23.  
  24. // Check if the fire effect is already applied
  25. let existingEffect = actor.effects.find(e => e.label === fireEffect.label);
  26.  
  27. if (existingEffect) {
  28. console.log(`Removing ongoing effect: ${fireEffect.label}`);
  29.  
  30. // Remove the combat hook
  31. try {
  32. const hookId = existingEffect.flags.custom?.fireDamageHookId;
  33. if (hookId) {
  34. Hooks.off("updateCombat", hookId);
  35. console.log(`Removed combat hook with ID: ${hookId}`);
  36. }
  37. } catch (error) {
  38. console.error("Failed to get flag 'custom' or flag does not exist.", error);
  39. }
  40.  
  41. // Remove the effect from the actor
  42. await actor.deleteEmbeddedDocuments("ActiveEffect", [existingEffect.id]);
  43. } else {
  44. console.log(`Applying ongoing effect: ${fireEffect.label}`);
  45. fireEffect.origin = actor.uuid; // Set the origin to the actor's UUID
  46.  
  47. // Create the effect on the actor
  48. const createdEffect = await actor.createEmbeddedDocuments("ActiveEffect", [fireEffect]);
  49. const effectId = createdEffect[0].id;
  50.  
  51. // Set up a hook to apply fire damage at the start of the affected token's turn
  52. const hookId = Hooks.on("updateCombat", (combat, update, options, userId) => {
  53. const combatant = combat.combatants.find(c => c.tokenId === token.id);
  54.  
  55. // If it's the start of the token's turn
  56. if (combatant && combatant.tokenId === combat.current.tokenId && combat.turns[combat.turn].tokenId === token.id) {
  57. console.log(`Applying fire damage to ${token.name}`);
  58.  
  59. // Apply fire damage to armor and weapons
  60. applyFireDamageToEquippedItems(actor, 5);
  61.  
  62. // Calculate total damage considering unprotected locations
  63. const totalDamage = calculateTotalDamage(actor, 5);
  64. // Apply total damage to HP
  65. const newHp = Math.max(actor.system.derivedStats.hp.value - totalDamage, 0);
  66. actor.update({"system.derivedStats.hp.value": newHp});
  67. ui.notifications.info(`${token.name} takes ${totalDamage} fire damage!`, { permanent: false, delay: 1000 });
  68. }
  69. });
  70.  
  71. console.log(`Created combat hook with ID: ${hookId}`);
  72.  
  73. // Store the hook ID in the effect so we can remove it later
  74. try {
  75. await actor.updateEmbeddedDocuments("ActiveEffect", [{
  76. _id: effectId,
  77. "flags.custom.fireDamageHookId": hookId
  78. }]);
  79. } catch (error) {
  80. console.error("Failed to update flag 'custom' with hookId.", error);
  81. }
  82. }
  83. }
  84.  
  85. // Function to apply fire damage to equipped armor and weapons
  86. async function applyFireDamageToEquippedItems(actor, baseDamage) {
  87. // Damage to equipped armor
  88. for (const item of actor.items.filter(i => i.type === 'armor' && i.system.equipped)) {
  89. const stoppingValues = [
  90. 'headStopping', 'torsoStopping', 'leftArmStopping', 'rightArmStopping',
  91. 'leftLegStopping', 'rightLegStopping'
  92. ];
  93.  
  94. for (const field of stoppingValues) {
  95. // Get the stopping power from the item
  96. const stoppingPower = item.system[field] ?? 0;
  97.  
  98. // Apply damage to the armor
  99. const newStoppingPower = Math.max(stoppingPower - 1, 0);
  100. await item.update({ [`system.${field}`]: newStoppingPower });
  101.  
  102. // Show notification
  103. ui.notifications.info(`${item.name} loses 1 stopping power in ${field}!`, { permanent: false, delay: 1000 });
  104. }
  105. }
  106.  
  107. // Damage to equipped weapons
  108. for (const item of actor.items.filter(i => i.type === 'weapon' && i.system.equipped)) {
  109. const reliabilityValue = item.system?.reliable ?? 0;
  110.  
  111. // Apply damage
  112. const newReliability = Math.max(reliabilityValue - 1, 0);
  113. await item.update({ "system.reliable": newReliability });
  114.  
  115. // Show notification
  116. ui.notifications.info(`${item.name} loses 1 reliability!`, { permanent: false, delay: 1000 });
  117. }
  118. }
  119.  
  120. // Function to calculate total damage applied to the actor based on stopping power
  121. function calculateTotalDamage(actor, baseDamage) {
  122. // Initialize stopping power for each body location
  123. const totalStoppingPower = {
  124. head: 0,
  125. torso: 0,
  126. leftArm: 0,
  127. rightArm: 0,
  128. leftLeg: 0,
  129. rightLeg: 0
  130. };
  131.  
  132. // Aggregate stopping power from all equipped armor pieces
  133. for (const item of actor.items.filter(i => i.type === 'armor' && i.system.equipped)) {
  134. for (const [key, value] of Object.entries(totalStoppingPower)) {
  135. if (item.system[`${key}Stopping`] !== undefined) {
  136. totalStoppingPower[key] += item.system[`${key}Stopping`];
  137. }
  138. }
  139. }
  140.  
  141. // Calculate total damage based on stopping power
  142. let totalDamage = 0;
  143. for (const [part, stopping] of Object.entries(totalStoppingPower)) {
  144. const damage = Math.max(baseDamage - stopping, 0);
  145. totalDamage += damage;
  146. }
  147.  
  148. return totalDamage;
  149. }
  150.  
  151. // Run the toggle function
  152. toggleFireEffect();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement