diff --git a/lang/de.json b/lang/de.json index c4c7749..9840f07 100644 --- a/lang/de.json +++ b/lang/de.json @@ -184,6 +184,8 @@ "midgard5.brawl": "Raufen", "midgard5.poisonResistance": "Gifttolleranz", "midgard5.enduranceBonus": "Ausdauerbonus", + "midgard5.lpProtection": "Rüstungsschutz (LP)", + "midgard5.apProtection": "Rüstungsschutz (AP)", "midgard5.new-skill": "Neue Fertigkeit", "midgard5.special": "Spezial", @@ -279,7 +281,6 @@ "midgard5.mod-operation-multiply": "Multiplizieren", "midgard5.mod-operation-division": "Dividieren", - "midgard5.mod-stat-defenseBonus": "Abwehrbonus", "midgard5.mod-stat-attackBonus": "Angriffsbonus", "midgard5.mod-stat-damageBonus": "Schadensbonus", @@ -291,6 +292,8 @@ "midgard5.mod-stat-poisonResistance": "Gifttolleranz", "midgard5.mod-stat-lp": "Lebenspunkte", "midgard5.mod-stat-ap": "Ausdauerpunkte", + "midgard5.mod-stat-lpProtection": "Rüstungsschutz (LP)", + "midgard5.mod-stat-apProtection": "Rüstungsschutz (AP)", "midgard5.mod-type": "Typ der Modifikation", "midgard5.mod-id": "Was soll modifiziert werden", diff --git a/source/index.ts b/source/index.ts index b048aa7..cd856ed 100644 --- a/source/index.ts +++ b/source/index.ts @@ -86,6 +86,10 @@ Hooks.once("init", async () => { return param.replace(regex, ""); }); + Handlebars.registerHelper("contains", (label: string, contains: string) => { + return label.toLowerCase().includes(contains.toLowerCase()); + }); + // Default Sheet für Items definieren und das Standardsheet deaktivieren Items.unregisterSheet("core", ItemSheet); Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true }); @@ -96,7 +100,6 @@ Hooks.once("init", async () => { CONFIG.Actor.documentClass = M5Character; CONFIG.Item.documentClass = M5Item; - //RegisterSettings(); await preloadTemplates(); }); @@ -105,6 +108,102 @@ 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) => { + // 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 + return game["user"].character && damageRolls > 0; + }, + callback: (li) => applyDamage(li, 2), + }, + { + name: "AP Schaden", + icon: '', + condition: (li) => { + // Only show this context menu if there are re-rollable dice in the message + const damageRolls = li.find(".apply-damage").length; + + // 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 + return game["user"].character && damageRolls > 0; + }, + callback: (li) => applyDamage(li, 1), + }, + { + name: "LP & AP Heilen", + icon: '', + condition: (li) => { + // Only show this context menu if there are re-rollable dice in the message + const damageRolls = li.find(".apply-damage").length; + + // 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 + return game["user"].character && damageRolls > 0; + }, + callback: (li) => applyDamage(li, -1), + }, + { + name: "AP Heilen", + icon: '', + condition: (li) => { + // Only show this context menu if there are re-rollable dice in the message + const damageRolls = li.find(".apply-damage").length; + + // 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 + return game["user"].character && damageRolls > 0; + }, + callback: (li) => applyDamage(li, -2), + } + ); +}); + Hooks.once("ready", () => { Logger.ok("Template module is now ready."); }); + +async function applyDamage(roll, direction) { + const damageValue = Array.from(roll.find(".apply-damage") as HTMLElement[]) + .map((x) => Math.max(0, Number(x.innerText))) + .reduce((prev, curr) => prev + curr, 0); + const userId = game["user"].character.id; + const viewedSceneId = game["user"].viewedScene; + const token = game["actors"].get(userId).getDependentTokens(viewedSceneId)[0]?.delta.syntheticActor; + const actor = game["user"].character; + + if (token) { + 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 += Math.min(damageValue, token["system"].lp.max - damageValue); + case -2: + token["system"].ap.value += Math.min(damageValue, token["system"].ap.max - damageValue); + } + 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 += Math.min(damageValue, actor["system"].lp.max - damageValue); + case -2: + actor["system"].ap.value += Math.min(damageValue, actor["system"].ap.max - damageValue); + } + actor.render(); + } +} diff --git a/source/module/M5Base.ts b/source/module/M5Base.ts index a0d5c57..3090e92 100644 --- a/source/module/M5Base.ts +++ b/source/module/M5Base.ts @@ -82,6 +82,8 @@ export enum M5Stats { POISON_RESISTANCE = "poisonResistance", LP = "lp", AP = "ap", + PROTECTION_LP = "lpProtection", + PROTECTION_AP = "apProtection", } export enum M5ModType { @@ -143,7 +145,8 @@ export interface M5CharacterCalculatedData { stats: { lp: M5ModResult; ap: M5ModResult; - armor: number; + lpProtection: M5ModResult; + apProtection: M5ModResult; defense: M5ModResult; damageBonus: M5ModResult; attackBonus: M5ModResult; diff --git a/source/module/actors/M5Character.ts b/source/module/actors/M5Character.ts index cfbc6cc..6ed0c31 100644 --- a/source/module/actors/M5Character.ts +++ b/source/module/actors/M5Character.ts @@ -53,7 +53,8 @@ export class M5Character extends Actor { stats: { lp: { value: 0, mods: [] }, ap: { value: 0, mods: [] }, - armor: 0, + lpProtection: { value: 0, mods: [] }, + apProtection: { value: 0, mods: [] }, defense: { value: 0, mods: [] }, damageBonus: { value: 0, mods: [] }, attackBonus: { value: 0, mods: [] }, @@ -116,7 +117,8 @@ export class M5Character extends Actor { ret.stats.lp = this.modResult(data.lp); ret.stats.ap = this.modResult(data.ap); - ret.stats.armor = 0; + ret.stats.lpProtection = this.modResult(0); + ret.stats.apProtection = this.modResult(0); ret.stats.defense = this.modResult(M5Character.defenseFromLevel(ret.level)); ret.stats.damageBonus = this.modResult(Math.floor(ret.attributes.st.value / 20) + Math.floor(ret.attributes.gs.value / 30) - 3); ret.stats.attackBonus = this.modResult(ret.attributes.gs.bonus); diff --git a/source/module/actors/M5ModAggregate.ts b/source/module/actors/M5ModAggregate.ts index a943bc5..cd492ed 100644 --- a/source/module/actors/M5ModAggregate.ts +++ b/source/module/actors/M5ModAggregate.ts @@ -39,6 +39,8 @@ export default class M5ModAggregate { this.push({ type: M5ModType.STAT, id: M5Stats.POISON_RESISTANCE, operation: M5ModOperation.SET, value: calc.stats.poisonResistance.value }, characterString); this.push({ type: M5ModType.STAT, id: M5Stats.LP, operation: M5ModOperation.SET, value: calc.stats.lp.value }, characterString); this.push({ type: M5ModType.STAT, id: M5Stats.AP, operation: M5ModOperation.SET, value: calc.stats.ap.value }, characterString); + this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_LP, operation: M5ModOperation.SET, value: calc.stats.lpProtection.value }, characterString); + this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_AP, operation: M5ModOperation.SET, value: calc.stats.apProtection.value }, characterString); } push(mod: M5ItemMod, source: string) { diff --git a/source/module/items/M5Item.ts b/source/module/items/M5Item.ts index da2344e..7421e50 100644 --- a/source/module/items/M5Item.ts +++ b/source/module/items/M5Item.ts @@ -111,6 +111,8 @@ export class M5Item extends Item { itemData.mods[1] = { type: "stat", id: "attackBonus", operation: "add", value: itemData.stats.attackBonus }; itemData.mods[2] = { type: "stat", id: "movement", operation: "add", value: itemData.stats.movementBonus }; itemData.mods[3] = { type: "attribute", id: "gw", operation: "add100", value: itemData.attributeMod.gw }; + itemData.mods[4] = { type: "stat", id: "lpProtection", operation: "set", value: itemData.lpProtection }; + itemData.mods[5] = { type: "stat", id: "apProtection", operation: "set", value: itemData.apProtection }; } else if (itemType === "spell") { calc.fw = 0; if (actor) { diff --git a/templates/chat/roll-m5.hbs b/templates/chat/roll-m5.hbs index c7e816d..856e72b 100644 --- a/templates/chat/roll-m5.hbs +++ b/templates/chat/roll-m5.hbs @@ -82,7 +82,7 @@