Add Rüstungsschutz to damage calculation

Changes:
 + Add Damage application from chat
 + take token first, if none exist, take actor
 + include damage reduction from equipped armor
 + damage appliaction is only accesible through right click on roll
This commit is contained in:
Byroks 2023-12-04 20:35:30 +01:00
parent 13a67c5b4a
commit 5d72482303
7 changed files with 40 additions and 28 deletions

View File

@ -184,6 +184,8 @@
"midgard5.brawl": "Raufen", "midgard5.brawl": "Raufen",
"midgard5.poisonResistance": "Gifttolleranz", "midgard5.poisonResistance": "Gifttolleranz",
"midgard5.enduranceBonus": "Ausdauerbonus", "midgard5.enduranceBonus": "Ausdauerbonus",
"midgard5.lpProtection": "Rüstungsschutz (LP)",
"midgard5.apProtection": "Rüstungsschutz (AP)",
"midgard5.new-skill": "Neue Fertigkeit", "midgard5.new-skill": "Neue Fertigkeit",
"midgard5.special": "Spezial", "midgard5.special": "Spezial",
@ -279,7 +281,6 @@
"midgard5.mod-operation-multiply": "Multiplizieren", "midgard5.mod-operation-multiply": "Multiplizieren",
"midgard5.mod-operation-division": "Dividieren", "midgard5.mod-operation-division": "Dividieren",
"midgard5.mod-stat-defenseBonus": "Abwehrbonus", "midgard5.mod-stat-defenseBonus": "Abwehrbonus",
"midgard5.mod-stat-attackBonus": "Angriffsbonus", "midgard5.mod-stat-attackBonus": "Angriffsbonus",
"midgard5.mod-stat-damageBonus": "Schadensbonus", "midgard5.mod-stat-damageBonus": "Schadensbonus",
@ -291,6 +292,8 @@
"midgard5.mod-stat-poisonResistance": "Gifttolleranz", "midgard5.mod-stat-poisonResistance": "Gifttolleranz",
"midgard5.mod-stat-lp": "Lebenspunkte", "midgard5.mod-stat-lp": "Lebenspunkte",
"midgard5.mod-stat-ap": "Ausdauerpunkte", "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-type": "Typ der Modifikation",
"midgard5.mod-id": "Was soll modifiziert werden", "midgard5.mod-id": "Was soll modifiziert werden",

View File

@ -100,7 +100,6 @@ Hooks.once("init", async () => {
CONFIG.Actor.documentClass = M5Character; CONFIG.Actor.documentClass = M5Character;
CONFIG.Item.documentClass = M5Item; CONFIG.Item.documentClass = M5Item;
//RegisterSettings(); //RegisterSettings();
await preloadTemplates(); await preloadTemplates();
}); });
@ -119,19 +118,21 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
const damageRolls = li.find(".apply-damage").length; const damageRolls = li.find(".apply-damage").length;
// All must be true to show the reroll dialogue // All must be true to show the reroll dialogue
return damageRolls > 0; // The button doesn't work for the GM right now, so we don't need to show it
return !game["user"].isGm && damageRolls > 0;
}, },
callback: (li) => applyDamage(li, 2), callback: (li) => applyDamage(li, 2),
}, },
{ {
name: "AP Schaden", name: "AP Schaden",
icon: '<i class="fas fa-tint"></i>', icon: '<i class="fas fa-shield-alt"></i>',
condition: (li) => { condition: (li) => {
// Only show this context menu if there are re-rollable dice in the message // Only show this context menu if there are re-rollable dice in the message
const damageRolls = li.find(".apply-damage").length; const damageRolls = li.find(".apply-damage").length;
// All must be true to show the reroll dialogue // All must be true to show the reroll dialogue
return damageRolls > 0; // The button doesn't work for the GM right now, so we don't need to show it
return !game["user"].isGm && damageRolls > 0;
}, },
callback: (li) => applyDamage(li, 1), callback: (li) => applyDamage(li, 1),
}, },
@ -143,19 +144,21 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
const damageRolls = li.find(".apply-damage").length; const damageRolls = li.find(".apply-damage").length;
// All must be true to show the reroll dialogue // All must be true to show the reroll dialogue
return damageRolls > 0; // The button doesn't work for the GM right now, so we don't need to show it
return !game["user"].isGm && damageRolls > 0;
}, },
callback: (li) => applyDamage(li, -1), callback: (li) => applyDamage(li, -1),
}, },
{ {
name: "AP Schaden", name: "AP Heilen",
icon: '<i class="fas fa-heart-o"></i>', icon: '<i class="far fa-heart"></i>',
condition: (li) => { condition: (li) => {
// Only show this context menu if there are re-rollable dice in the message // Only show this context menu if there are re-rollable dice in the message
const damageRolls = li.find(".apply-damage").length; const damageRolls = li.find(".apply-damage").length;
// All must be true to show the reroll dialogue // All must be true to show the reroll dialogue
return damageRolls > 0; // The button doesn't work for the GM right now, so we don't need to show it
return !game["user"].isGm && damageRolls > 0;
}, },
callback: (li) => applyDamage(li, -2), callback: (li) => applyDamage(li, -2),
} }
@ -168,41 +171,38 @@ Hooks.once("ready", () => {
async function applyDamage(roll, direction) { async function applyDamage(roll, direction) {
const damageValue = Array.from(roll.find(".apply-damage") as HTMLElement[]) const damageValue = Array.from(roll.find(".apply-damage") as HTMLElement[])
.map((x) => Number(x.innerText)) .map((x) => Math.max(0, Number(x.innerText)))
.reduce((prev, curr) => prev + curr, 0); .reduce((prev, curr) => prev + curr, 0);
console.log(damageValue);
const userId = game["user"].character.id; const userId = game["user"].character.id;
const viewedSceneId = game["user"].viewedScene; const viewedSceneId = game["user"].viewedScene;
const token = game["actors"].get(userId).getDependentTokens(viewedSceneId)[0]?.delta.syntheticActor; const token = game["actors"].get(userId).getDependentTokens(viewedSceneId)[0]?.delta.syntheticActor;
const actor = game["user"].character; const actor = game["user"].character;
console.log(token);
console.log(actor);
if (token) { if (token) {
switch (direction) { switch (direction) {
case 2: case 2:
token["system"].lp.value -= damageValue; token["system"].lp.value -= Math.max(0, damageValue - token["system"].calc.stats.lpProtection.value);
case 1: case 1:
token["system"].ap.value -= damageValue; token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value);
break; break;
case -1: case -1:
token.delta.system.lp += damageValue; token["system"].lp.value += Math.min(damageValue, token["system"].lp.max - damageValue);
case -2: case -2:
token.delta.system.ap += damageValue; token["system"].ap.value += Math.min(damageValue, token["system"].ap.max - damageValue);
} }
token.render();
} else { } else {
switch (direction) { switch (direction) {
case 2: case 2:
actor["system"].lp.value -= damageValue; actor["system"].lp.value -= Math.max(0, damageValue - actor["system"].calc.stats.lpProtection.value);
case 1: case 1:
actor["system"].ap.value -= damageValue; actor["system"].ap.value -= Math.max(0, damageValue - actor["system"].calc.stats.apProtection.value);
break; break;
case -1: case -1:
actor["system"].lp.value += damageValue; actor["system"].lp.value += Math.min(damageValue, actor["system"].lp.max - damageValue);
case -2: case -2:
actor["system"].ap.value += damageValue; actor["system"].ap.value += Math.min(damageValue, actor["system"].ap.max - damageValue);
} }
}
actor.render(); actor.render();
} }
}

View File

@ -82,6 +82,8 @@ export enum M5Stats {
POISON_RESISTANCE = "poisonResistance", POISON_RESISTANCE = "poisonResistance",
LP = "lp", LP = "lp",
AP = "ap", AP = "ap",
PROTECTION_LP = "lpProtection",
PROTECTION_AP = "apProtection",
} }
export enum M5ModType { export enum M5ModType {
@ -143,7 +145,8 @@ export interface M5CharacterCalculatedData {
stats: { stats: {
lp: M5ModResult; lp: M5ModResult;
ap: M5ModResult; ap: M5ModResult;
armor: number; lpProtection: M5ModResult;
apProtection: M5ModResult;
defense: M5ModResult; defense: M5ModResult;
damageBonus: M5ModResult; damageBonus: M5ModResult;
attackBonus: M5ModResult; attackBonus: M5ModResult;

View File

@ -53,7 +53,8 @@ export class M5Character extends Actor {
stats: { stats: {
lp: { value: 0, mods: [] }, lp: { value: 0, mods: [] },
ap: { value: 0, mods: [] }, ap: { value: 0, mods: [] },
armor: 0, lpProtection: { value: 0, mods: [] },
apProtection: { value: 0, mods: [] },
defense: { value: 0, mods: [] }, defense: { value: 0, mods: [] },
damageBonus: { value: 0, mods: [] }, damageBonus: { value: 0, mods: [] },
attackBonus: { 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.lp = this.modResult(data.lp);
ret.stats.ap = this.modResult(data.ap); 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.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.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); ret.stats.attackBonus = this.modResult(ret.attributes.gs.bonus);

View File

@ -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.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.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.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) { push(mod: M5ItemMod, source: string) {

View File

@ -111,6 +111,8 @@ export class M5Item extends Item {
itemData.mods[1] = { type: "stat", id: "attackBonus", operation: "add", value: itemData.stats.attackBonus }; 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[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[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") { } else if (itemType === "spell") {
calc.fw = 0; calc.fw = 0;
if (actor) { if (actor) {

View File

@ -22,10 +22,10 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>{{localize "midgard5.actor-lp"}}</td> <td>{{localize "midgard5.lpProtection"}}</td>
<td><input name="data.lpProtection" type="text" value="{{data.lpProtection}}" data-dtype="Number" /></td> <td><input name="data.lpProtection" type="text" value="{{data.lpProtection}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.actor-ap"}}</td> <td>{{localize "midgard5.apProtection"}}</td>
<td><input name="data.apProtection" type="text" value="{{data.apProtection}}" data-dtype="Number" /></td> <td><input name="data.apProtection" type="text" value="{{data.apProtection}}" data-dtype="Number" /></td>
</tr> </tr>