From 416830a56e9ab8a932a4be1d814a6ac02c6e6a7e Mon Sep 17 00:00:00 2001 From: macniel Date: Mon, 13 Oct 2025 23:40:07 +0200 Subject: [PATCH] adds wound threshold and actor based action to takeDamage by a certain amount to a specific zone (or non which is only allowed when play with zones is active) --- src/main.mjs | 7 +- src/module/data/Trefferzone.js | 30 +++++++++ src/module/data/character.mjs | 6 +- src/module/documents/character.mjs | 66 ++++++++++++++++++- src/templates/actor/actor-character-sheet.hbs | 14 ++-- 5 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 src/module/data/Trefferzone.js diff --git a/src/main.mjs b/src/main.mjs index d2e4b714..3c52c844 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -20,6 +20,7 @@ import {SpecialAbilityDataModel} from "./module/data/specialAbility.mjs"; import {SpecialAbilitySheet} from "./module/sheets/specialAbilitySheet.mjs"; import {ActiveEffectSheet} from "./module/sheets/ActiveEffectSheet.mjs"; import {ActiveEffectDataModel} from "./module/data/activeeffect.mjs"; +import {Trefferzone, Wunde, Zonenruestung, Zonenwunde} from "./module/data/Trefferzone.js"; async function preloadHandlebarsTemplates() { return loadTemplates([ @@ -42,7 +43,11 @@ async function preloadHandlebarsTemplates() { Hooks.once("init", () => { game.DSA41 = { - rollItemMacro + rollItemMacro, + Zonenruestung, + Zonenwunde, + Trefferzone, + Wunde } // Configure custom Document implementations. diff --git a/src/module/data/Trefferzone.js b/src/module/data/Trefferzone.js new file mode 100644 index 00000000..6a305685 --- /dev/null +++ b/src/module/data/Trefferzone.js @@ -0,0 +1,30 @@ +export const Trefferzone = { + ARM_LINKS: "armlinks", + ARM_RECHTS: "armrechts", + BEIN_LINKS: "beinlinks", + BEIN_RECHTS: "beinrechts", + BAUCH: "bauch", + KOPF: "kopf", + BRUST: "brust" +} + +export const Zonenruestung = { + ...Trefferzone, + WAFFE_LINKS: "links", + WAFFE_RECHTS: "rechts", + FERNKAMPF: "fernkampf", + MUNITION: "munition", + RUECKEN: "ruecken", +} + +export const Zonenwunde = { + ARM_LINKS: "Wunde linker Arm", + ARM_RECHTS: "Wunde rechter Arm", + BEIN_LINKS: "Wunde rechtes Bein", + BEIN_RECHTS: "Wunde rechtes Bein", + BAUCH: "Bauchwunde", + KOPF: "Kopfwunde", + BRUST: "Brustwunde", +} + +export const Wunde = "Wunde" \ No newline at end of file diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index 693c7fb5..b6e5eb4b 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -59,6 +59,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { aktuell: new NumberField({required: true, integer: true, initial: 0}), mod: new NumberField({required: true, integer: true}), }), + ws: new NumberField({required: true, integer: true, initial: 0}), attribute: new SchemaField({ mu: new SchemaField({ start: new NumberField({required: true, integer: true}), @@ -138,7 +139,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { beinlinks: new NumberField({required: true, integer: true, initial: 0}), beinrechts: new NumberField({required: true, integer: true, initial: 0}), bauch: new NumberField({required: true, integer: true, initial: 0}), - torso: new NumberField({required: true, integer: true, initial: 0}), + brust: new NumberField({required: true, integer: true, initial: 0}), kopf: new NumberField({required: true, integer: true, initial: 0}), }), heldenausruestung: new ArrayField( @@ -180,9 +181,6 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { } async _onCreate(data, options, userId) { - - console.log(data, 'onCreate'); - } static getSlots() { diff --git a/src/module/documents/character.mjs b/src/module/documents/character.mjs index c6e5ce3d..eb1cfc8c 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -1,5 +1,6 @@ import {importCharacter} from "../xml-import/xml-import.mjs"; import {LiturgyData} from "../data/miracle/liturgydata.mjs"; +import {Zonenruestung, Zonenwunde} from "../data/Trefferzone.js"; export class Character extends Actor { @@ -95,7 +96,7 @@ export class Character extends Actor { if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) { systemData.rs = { - torso: 0, + brust: 0, bauch: 0, armlinks: 0, armrechts: 0, @@ -113,7 +114,7 @@ export class Character extends Actor { systemData.wunden.max = ko / 2; if (game.settings.get("DSA_4-1", "optional_trefferzonen")) { systemData.wunden.kopf = 0; - systemData.wunden.torso = 0; + systemData.wunden.brust = 0; systemData.wunden.bauch = 0; systemData.wunden.armlinks = 0; systemData.wunden.armrechts = 0; @@ -121,6 +122,7 @@ export class Character extends Actor { systemData.wunden.beinrechts = 0; } + systemData.ws = ko / 2; // map current set to RS and BE @@ -129,7 +131,7 @@ export class Character extends Actor { if (ausruestung.brust) { systemData.be += systemData.parent.items.get(ausruestung.brust).system.armorHandicap ?? 0 if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) { - systemData.rs.torso = systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0 + systemData.rs.brust = systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0 } else { systemData.rs += systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0 } @@ -242,4 +244,62 @@ export class Character extends Actor { return data; } + + /** + * + * @param amount + * @param zone either null or one of + * @returns {Promise} + */ + async takeDamage(amount = null, zone = null) { + + this.prepareDerivedData() + + const playWithZoneArmor = game.settings.get("DSA_4-1", "optional_ruestungzonen") + const playWithWoundZones = game.settings.get("DSA_4-1", "optional_trefferzonen") + const previousLeP = this.system.lep.aktuell; + + if (amount == null) { + // TODO show Dialog for entering damage amount (TP) + } + + let armorReduction = 0 + let setEquipped = this.system.setEquipped + let woundThreshold = this.system.ws + + if (playWithZoneArmor) { + const armorId = this.system.heldenausruestung[setEquipped][Zonenruestung[zone]] + const zoneArmor = await this.items.find(p => p._id === armorId) + if (!zoneArmor) { + return console.error(`zone "${zone}" is not a valid value`) + } + armorReduction = zoneArmor.system.armorValue ?? 0 + } else { + armorReduction = this.system.rs + } + + let damage = amount - armorReduction + let wounds = damage / woundThreshold + + let wound = null + + if (playWithWoundZones) { + wound = await game.packs.get("DSA_4-1.Wounds").index.find(p => p.name === Zonenwunde[zone]) + if (!wound) { + return console.error(`Wunden Dokument zu "${zone}" konnten nicht gefunden werden`) + } + } else { + wound = await game.packs.get("DSA_4-1.Wounds").index.find(p => p.name === Wunde) + if (!wound) { + return console.error(`Wunden Dokument zu "${Wunde}" konnten nicht gefunden werden`) + } + } + + // TODO this doesnt work yet, wound documents wont get expanded + + for (let i = 0; i < wounds; i++) { + await this.createEmbeddedDocuments('Item', [wound]) + } + await this.update({system: {lep: {aktuell: previousLeP - damage}}}) + } } diff --git a/src/templates/actor/actor-character-sheet.hbs b/src/templates/actor/actor-character-sheet.hbs index 6d2597d5..3b6af840 100644 --- a/src/templates/actor/actor-character-sheet.hbs +++ b/src/templates/actor/actor-character-sheet.hbs @@ -310,14 +310,14 @@ von - + {{#if ausdauer}}
von - +
{{/if}} {{#if (not zonenruestung)}} @@ -371,7 +371,7 @@ {{#if trefferzonen}} {{derived.wunden.kopf}} - {{derived.wunden.torso}} + {{derived.wunden.brust}} {{derived.wunden.armlinks}} {{derived.wunden.armrechts}} {{derived.wunden.bauch}} @@ -380,7 +380,7 @@ {{/if}} {{#if zonenruestung}} {{derived.rs.kopf}} - {{derived.rs.torso}} + {{derived.rs.brust}} {{derived.rs.armlinks}} {{derived.rs.armrechts}} {{derived.rs.bauch}} @@ -544,11 +544,11 @@ von - {{derived.asp.max}} +
- {{derived.mr.aktuell}} +
@@ -594,7 +594,7 @@ von - {{derived.kap.max}} +