diff --git a/lang/de.json b/lang/de.json index 0a69c85..25cb5e3 100644 --- a/lang/de.json +++ b/lang/de.json @@ -5,11 +5,22 @@ "TYPES.Item.item": "Gegenstand", "TYPES.Item.weapon": "Waffe", - "ITEM.TypeDefensiveWeapon": "Verteidigungswaffe", + "TYPES.Item.defensiveWeapon": "Verteidigungswaffe", "TYPES.Item.armor": "Rüstung", "TYPES.Item.spell": "Zauber", "TYPES.Item.effect": "Aktive Effekte", - "ITEM.type.kampfkunst": "Kampfkünste", + "TYPES.Item.kampfkunst": "Kampfkünste", + + "midgard5.phase-action": "Handlungsphase", + "midgard5.phase-movement": "Bewegungsphase", + "midgard5.no-encounter": "Kein Kampf", + "midgard5.encounter-not-started": "Kein aktiver Kampf", + + "midgard5.time-duration": "Dauer", + "midgard5.time-round": "Runde(n)", + "midgard5.time-minute": "Minute(n)", + "midgard5.time-hour": "Stunde(n)", + "midgard5.time-limitless": "Unbegrenzt", "midgard5.doRoll": "Würfeln", "midgard5.learn": "Lernen", diff --git a/packs/items/zauberwirkungen/Bärenwut.json b/packs/items/zauberwirkungen/Bärenwut.json index d842ebb..087b440 100644 --- a/packs/items/zauberwirkungen/Bärenwut.json +++ b/packs/items/zauberwirkungen/Bärenwut.json @@ -6,6 +6,7 @@ "description": "
ARK S. 144
", "equippable": false, "equipped": true, + "duration": { "time": 12, "unit": "round" }, "value": 0, "magic": true, "rolls": { "formulas": {}, "output": "" }, diff --git a/source/index.ts b/source/index.ts index cd856ed..42b83d9 100644 --- a/source/index.ts +++ b/source/index.ts @@ -2,7 +2,7 @@ import Logger from "./utils/Logger"; import M5CharacterSheet from "./module/sheets/M5CharacterSheet"; import preloadTemplates from "./PreloadTemplates"; import { M5Character } from "./module/actors/M5Character"; -import { M5Skill } from "./module/M5Base"; +import { M5ItemMod, M5ModOperation, M5Skill, M5TimeUnit } from "./module/M5Base"; import { M5ItemSheet } from "./module/sheets/M5ItemSheet"; import { M5Item } from "./module/items/M5Item"; @@ -58,10 +58,10 @@ Hooks.once("init", async () => { return `${obj}`; }); - Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string) => { + Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string, token?: boolean) => { //console.log("actorItemValue", actorId, itemId, path) const actor = (game as Game).actors.get(actorId); - let obj = actor.items.get(itemId).system; + let obj = actor.items.get(itemId)?.system; path.split(".").forEach((p) => { if (obj) obj = obj[p]; }); @@ -116,7 +116,6 @@ Hooks.on("getChatLogEntryContext", function (html, options) { condition: (li) => { // Only show this context menu if there are re-rollable dice in the message const damageRolls = li.find(".apply-damage").length; - console.log(game["user"].isGm); // All must be true to show the reroll dialogue // The button doesn't work for the GM right now, so we don't need to show it @@ -166,6 +165,70 @@ Hooks.on("getChatLogEntryContext", function (html, options) { ); }); +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(); + } +}); + +function limitHeal(heal: number, current: number, max: number): number { + if (current === max) { + return 0; + } else if (heal + current > max) { + return max - current; + } + return heal; +} + +Hooks.on("renderCombatTracker", (combatTracker, html, context) => { + if (context.combat === null) { + html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.no-encounter"); + } else if (Math.ceil(context.round / 2) === 0) { + html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.encounter-not-started"); + } else { + html.find("h3.encounter-title")[0].innerHTML = + (context.round % 2 == 1 ? game["i18n"].localize("midgard5.phase-movement") : game["i18n"].localize("midgard5.phase-action")) + " " + Math.ceil(context.round / 2); + } +}); + Hooks.once("ready", () => { Logger.ok("Template module is now ready."); }); @@ -187,9 +250,9 @@ async function applyDamage(roll, direction) { token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value); break; case -1: - token["system"].lp.value += Math.min(damageValue, token["system"].lp.max - damageValue); + token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max); case -2: - token["system"].ap.value += Math.min(damageValue, token["system"].ap.max - damageValue); + token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max); } token.render(); } else { @@ -200,9 +263,9 @@ async function applyDamage(roll, direction) { actor["system"].ap.value -= Math.max(0, damageValue - actor["system"].calc.stats.apProtection.value); break; case -1: - actor["system"].lp.value += Math.min(damageValue, actor["system"].lp.max - damageValue); + actor["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max); case -2: - actor["system"].ap.value += Math.min(damageValue, actor["system"].ap.max - damageValue); + actor["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max); } actor.render(); } diff --git a/source/module/M5Base.ts b/source/module/M5Base.ts index 3090e92..60c64fa 100644 --- a/source/module/M5Base.ts +++ b/source/module/M5Base.ts @@ -102,6 +102,13 @@ export enum M5ModOperation { DIVISION = "division", } +export enum M5TimeUnit { + ROUND = "round", + MINUTE = "minute", + HOUR = "hour", + LIMITLESS = "limitless", +} + export interface M5ItemMod { type: M5ModType; id: string; diff --git a/source/module/actors/M5Character.ts b/source/module/actors/M5Character.ts index 6ed0c31..91e2543 100644 --- a/source/module/actors/M5Character.ts +++ b/source/module/actors/M5Character.ts @@ -188,7 +188,8 @@ export class M5Character extends Actor { label: label, magic: item.system.magic, calc: item.system.calc, - equipped: item.system?.equipped, + equipped: item.system?.equipped || false, + duration: item.system?.duration || { time: 0, unit: "" }, }; }); } diff --git a/source/template.json b/source/template.json index 6741d15..180f4ba 100644 --- a/source/template.json +++ b/source/template.json @@ -201,6 +201,14 @@ "value": 0, "magic": false }, + "durationSelection": { + "durationSelection": { + "round": "midgard5.time-round", + "minute": "midgard5.time-minute", + "hour": "midgard5.time-hour", + "limitless": "midgard5.time-limitless" + } + }, "spellSelection": { "spellProcessSelection": { "none": "midgard5.spell-process-none", @@ -295,7 +303,7 @@ "calc": {} }, "effect": { - "templates": ["itemDescription", "equippable", "physical"], + "templates": ["itemDescription", "equippable", "physical", "durationSelection"], "rolls": { "formulas": {}, "output": "" diff --git a/templates/sheets/character/effects.hbs b/templates/sheets/character/effects.hbs index 3666f93..986629d 100644 --- a/templates/sheets/character/effects.hbs +++ b/templates/sheets/character/effects.hbs @@ -12,6 +12,9 @@ {{item.label}} {{#if item.equipped}} {{localize "midgard5.active"}} + {{#unless (or (eq item.duration.unit "") (eq item.duration.unit "limitless"))}} + {{item.duration.time}} {{localize (concat "midgard5.time-" item.duration.unit)}} + {{/unless}} {{/if}}| {{localize "ITEM.TypeDefensiveWeapon"}} | +{{localize "TYPES.Item.defensiveWeapon"}} | {{localize "midgard5.ew"}} | @@ -90,7 +90,7 @@ {{localize "midgard5.equipped"}} {{/if}} - | {{actorItemValue ../actor._id itemId "lpProtection"}} | +{{actorItemValue ../actor._id itemId "lpProtection" ../actor.isToken}} | {{actorItemValue ../actor._id itemId "apProtection"}} | {{actorItemValue ../actor._id itemId "stats.attackBonus"}} | {{actorItemValue ../actor._id itemId "stats.defenseBonus"}} | diff --git a/templates/sheets/character/kampfkuenste.hbs b/templates/sheets/character/kampfkuenste.hbs index e2b9ce0..4662b34 100644 --- a/templates/sheets/character/kampfkuenste.hbs +++ b/templates/sheets/character/kampfkuenste.hbs @@ -1,7 +1,7 @@
|---|
| {{localize "ITEM.type.kampfkunst"}} | +{{localize "TYPES.Item.kampfkunst"}} | {{localize "midgard5.ew"}} | diff --git a/templates/sheets/item/effect.hbs b/templates/sheets/item/effect.hbs index 7a5cc1b..6c3dd17 100644 --- a/templates/sheets/item/effect.hbs +++ b/templates/sheets/item/effect.hbs @@ -22,8 +22,17 @@ | |
|---|---|---|---|---|
|
- {{localize "midgard5.item-value"}}
-
+ {{localize "midgard5.time-duration"}}
+
+
|