Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Define the fire damage effect
- const fireEffect = {
- label: "Fire",
- icon: "icons/svg/fire.svg",
- origin: null,
- disabled: false,
- duration: { rounds: 9999, startRound: game.combat?.round, startTime: game.time.worldTime },
- flags: {
- custom: { fireDamageHookId: null }
- },
- changes: []
- };
- // Function to apply/remove the fire damage effect and hook
- async function toggleFireEffect() {
- const token = canvas.tokens.controlled[0];
- if (!token) {
- ui.notifications.warn("Please select a token first.");
- return;
- }
- const actor = token.actor;
- // Check if the fire effect is already applied
- let existingEffect = actor.effects.find(e => e.label === fireEffect.label);
- if (existingEffect) {
- console.log(`Removing ongoing effect: ${fireEffect.label}`);
- // Remove the combat hook
- try {
- const hookId = existingEffect.flags.custom?.fireDamageHookId;
- if (hookId) {
- Hooks.off("updateCombat", hookId);
- console.log(`Removed combat hook with ID: ${hookId}`);
- }
- } catch (error) {
- console.error("Failed to get flag 'custom' or flag does not exist.", error);
- }
- // Remove the effect from the actor
- await actor.deleteEmbeddedDocuments("ActiveEffect", [existingEffect.id]);
- } else {
- console.log(`Applying ongoing effect: ${fireEffect.label}`);
- fireEffect.origin = actor.uuid; // Set the origin to the actor's UUID
- // Create the effect on the actor
- const createdEffect = await actor.createEmbeddedDocuments("ActiveEffect", [fireEffect]);
- const effectId = createdEffect[0].id;
- // Set up a hook to apply fire damage at the start of the affected token's turn
- const hookId = Hooks.on("updateCombat", (combat, update, options, userId) => {
- const combatant = combat.combatants.find(c => c.tokenId === token.id);
- // If it's the start of the token's turn
- if (combatant && combatant.tokenId === combat.current.tokenId && combat.turns[combat.turn].tokenId === token.id) {
- console.log(`Applying fire damage to ${token.name}`);
- // Apply fire damage to armor and weapons
- applyFireDamageToEquippedItems(actor, 5);
- // Calculate total damage considering unprotected locations
- const totalDamage = calculateTotalDamage(actor, 5);
- // Apply total damage to HP
- const newHp = Math.max(actor.system.derivedStats.hp.value - totalDamage, 0);
- actor.update({"system.derivedStats.hp.value": newHp});
- ui.notifications.info(`${token.name} takes ${totalDamage} fire damage!`, { permanent: false, delay: 1000 });
- }
- });
- console.log(`Created combat hook with ID: ${hookId}`);
- // Store the hook ID in the effect so we can remove it later
- try {
- await actor.updateEmbeddedDocuments("ActiveEffect", [{
- _id: effectId,
- "flags.custom.fireDamageHookId": hookId
- }]);
- } catch (error) {
- console.error("Failed to update flag 'custom' with hookId.", error);
- }
- }
- }
- // Function to apply fire damage to equipped armor and weapons
- async function applyFireDamageToEquippedItems(actor, baseDamage) {
- // Damage to equipped armor
- for (const item of actor.items.filter(i => i.type === 'armor' && i.system.equipped)) {
- const stoppingValues = [
- 'headStopping', 'torsoStopping', 'leftArmStopping', 'rightArmStopping',
- 'leftLegStopping', 'rightLegStopping'
- ];
- for (const field of stoppingValues) {
- // Get the stopping power from the item
- const stoppingPower = item.system[field] ?? 0;
- // Apply damage to the armor
- const newStoppingPower = Math.max(stoppingPower - 1, 0);
- await item.update({ [`system.${field}`]: newStoppingPower });
- // Show notification
- ui.notifications.info(`${item.name} loses 1 stopping power in ${field}!`, { permanent: false, delay: 1000 });
- }
- }
- // Damage to equipped weapons
- for (const item of actor.items.filter(i => i.type === 'weapon' && i.system.equipped)) {
- const reliabilityValue = item.system?.reliable ?? 0;
- // Apply damage
- const newReliability = Math.max(reliabilityValue - 1, 0);
- await item.update({ "system.reliable": newReliability });
- // Show notification
- ui.notifications.info(`${item.name} loses 1 reliability!`, { permanent: false, delay: 1000 });
- }
- }
- // Function to calculate total damage applied to the actor based on stopping power
- function calculateTotalDamage(actor, baseDamage) {
- // Initialize stopping power for each body location
- const totalStoppingPower = {
- head: 0,
- torso: 0,
- leftArm: 0,
- rightArm: 0,
- leftLeg: 0,
- rightLeg: 0
- };
- // Aggregate stopping power from all equipped armor pieces
- for (const item of actor.items.filter(i => i.type === 'armor' && i.system.equipped)) {
- for (const [key, value] of Object.entries(totalStoppingPower)) {
- if (item.system[`${key}Stopping`] !== undefined) {
- totalStoppingPower[key] += item.system[`${key}Stopping`];
- }
- }
- }
- // Calculate total damage based on stopping power
- let totalDamage = 0;
- for (const [part, stopping] of Object.entries(totalStoppingPower)) {
- const damage = Math.max(baseDamage - stopping, 0);
- totalDamage += damage;
- }
- return totalDamage;
- }
- // Run the toggle function
- toggleFireEffect();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement