import Logger from "./utils/Logger"; import M5CharacterSheet from "./module/sheets/M5CharacterSheet"; import preloadTemplates from "./PreloadTemplates"; import { M5Character } from "./module/actors/M5Character"; import { M5ModOperation, M5TimeUnit } from "./module/M5Base"; import { M5ItemSheet } from "./module/sheets/M5ItemSheet"; import { M5Item } from "./module/items/M5Item"; import { reroll } from "./module/rolls/reroll"; import { loadHelpers } from "./helpers"; import { loadSettings } from "./settings"; Hooks.once("init", async () => { Logger.log("M5 | Initialisierung Midgard 5"); // Load settings into Foundry loadSettings(); // Default Sheet für Items definieren und das Standardsheet deaktivieren Items.unregisterSheet("core", ItemSheet); Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true }); // Default Sheet für Actors definieren und das Standardsheet deaktivieren Actors.unregisterSheet("core", ActorSheet); Actors.registerSheet("midgard5", M5CharacterSheet, { makeDefault: true }); CONFIG.Actor.documentClass = M5Character; CONFIG.Item.documentClass = M5Item; //RegisterSettings(); await preloadTemplates(); loadHelpers(); }); Hooks.once("setup", () => { Logger.log("Template module is being setup."); }); Hooks.on("getChatLogEntryContext", function (html, options) { options.push( { name: "LP & AP Schaden", icon: '', condition: (li) => { const damageRolls = li.find(".damage").length; // All must be true to show the reroll dialogue return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0; }, callback: (li) => applyDamage(li, 2), }, { name: "AP Schaden", icon: '', condition: (li) => { const damageRolls = li.find(".damage").length; // All must be true to show the reroll dialogue return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0; }, callback: (li) => applyDamage(li, 1), }, { name: "LP & AP Heilen", icon: '', condition: (li) => { const damageRolls = li.find(".heal").length; // All must be true to show the reroll dialogue return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0; }, callback: (li) => applyDamage(li, -1), }, { name: "AP Heilen", icon: '', condition: (li) => { const damageRolls = li.find(".heal").length; // All must be true to show the reroll dialogue return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0; }, callback: (li) => applyDamage(li, -2), }, { name: "Redo", icon: '', condition: (li) => { const message = (game as Game).messages.get(li.attr("data-message-id")); // All must be true to show the reroll dialogue return (game["user"].isGM || game["user"].character?.id === (game as Game).actors.get(message["speaker"].actor)?.id) && !message["flags"].rerolled; }, callback: (li) => reroll(li), } ); }); Hooks.on("createCombatant", function () { }); Hooks.on("updateCombat", function (combat: Combat, updateData: { round: number; turn: number }, updateOptions: { advanceTime: number; direction: number }) { if (combat.round % 2 === 0 && combat.turn !== null) { const tokenId = combat.current.tokenId; const actorId = combat.combatant["actorId"]; let currentToken = game["actors"].tokens[tokenId]; if (!currentToken) { currentToken = game["actors"].get(actorId); } let activeEffects = currentToken.items.filter((x) => x.type === "effect" && x.system.equipped) || []; activeEffects.forEach((effect) => { if (effect.system?.duration?.time > 0) { if (effect.system.duration.unit === M5TimeUnit.ROUND) { effect.system.duration.time -= 1; } } if (effect.system?.duration.time === 0 && effect.system.duration.unit !== M5TimeUnit.LIMITLESS) { effect.system.equipped = false; } for (const key in effect.system.mods) { if (effect.system.mods[key].operation === M5ModOperation.SUBTRACT) { switch (effect.system.mods[key].id) { case "lp": currentToken["system"].lp.value -= effect.system.mods[key].value; break; case "ap": currentToken["system"].ap.value -= effect.system.mods[key].value; break; } } else if (effect.system.mods[key].operation === M5ModOperation.ADD) { switch (effect.system.mods[key].id) { case "lp": currentToken["system"].lp.value += limitHeal(effect.system.mods[key].value, currentToken["system"].lp.value, currentToken["system"].lp.max); break; case "ap": currentToken["system"].ap.value += limitHeal(effect.system.mods[key].value, currentToken["system"].ap.value, currentToken["system"].ap.max); break; } } } }); currentToken.render(); } }); Hooks.on("renderCombatTracker", (combatTracker, html, context) => { handleRenderCombatTracker(combatTracker, html, context); }); Hooks.once("ready", () => { Logger.ok("Template module is now ready."); }); async function applyDamage(roll, direction) { const damageValue = Array.from(roll.find(".apply") as HTMLElement[]) .map((x) => Math.max(0, Number(x.innerText))) .reduce((prev, curr) => prev + curr, 0); const controlledTokens = game["canvas"].tokens.controlled; const actor = game["user"].character; if (controlledTokens) { controlledTokens.forEach((controlledToken) => { let token = controlledToken.document.delta.syntheticActor; switch (direction) { case 2: token["system"].lp.value -= Math.max(0, damageValue - token["system"].calc.stats.lpProtection.value); case 1: token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value); break; case -1: token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max); case -2: token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max); } token.render(); }); } else { switch (direction) { case 2: actor["system"].lp.value -= Math.max(0, damageValue - actor["system"].calc.stats.lpProtection.value); case 1: actor["system"].ap.value -= Math.max(0, damageValue - actor["system"].calc.stats.apProtection.value); break; case -1: actor["system"].lp.value += limitHeal(damageValue, actor["system"].lp.value, actor["system"].lp.max); case -2: actor["system"].ap.value += limitHeal(damageValue, actor["system"].ap.value, actor["system"].ap.max); } actor.render(); } } function limitHeal(heal: number, current: number, max: number): number { if (current === max) { return 0; } else if (heal + current > max) { return max - current; } return heal; } function handleRenderCombatTracker(combatTracker, html, context) { let combatPhase = -1; if (context.combat === null) { combatPhase = 0; html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.no-encounter"); } else if (Math.ceil(context.round / 2) === 0) { combatPhase = 1; html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.encounter-not-started"); } else if (context.round % 2 == 1) { combatPhase = 2; html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.phase-movement"); } else { combatPhase = 3; html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.phase-action") + " " + Math.ceil(context.round / 2); } console.log("Combat Phase: ", combatPhase); context.combat?.setFlag('world', 'combatPhase', combatPhase); for (const key in context.combat?.combatants.contents) { let actorId = context.combat?.combatants.contents[key].actorId; let actor = (game as Game).actors.get(actorId); actor.render(); } }