From 801de801ba1c42f42067e6d3d5af369c094a8e22 Mon Sep 17 00:00:00 2001 From: macniel Date: Sat, 4 Oct 2025 16:58:26 +0200 Subject: [PATCH] initial draft of combat --- src/main.mjs | 12 ++++++-- src/module/data/character.mjs | 41 +++++++++++++------------- src/module/documents/character.mjs | 44 +++++++++++++++++++++++++++- src/module/sheets/characterSheet.mjs | 6 ++-- src/module/xml-import/xml-import.mjs | 12 ++++---- src/system.json | 4 +-- 6 files changed, 85 insertions(+), 34 deletions(-) diff --git a/src/main.mjs b/src/main.mjs index 1a9d560e..020f549b 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -11,6 +11,8 @@ import {GroupDataModel} from "./module/data/group.mjs"; import {GroupSheet} from "./module/sheets/groupSheet.mjs"; import {EquipmentDataModel} from "./module/data/equipment.mjs"; import {AusruestungSheet} from "./module/sheets/equipmentSheet.mjs"; +import { CreatureDataModel } from "./module/data/creature.mjs"; +import { CreatureSheet } from "./module/sheets/creatureSheet.mjs"; async function preloadHandlebarsTemplates() { return loadTemplates([ @@ -38,7 +40,8 @@ Hooks.once("init", () => { // Configure System Data Models. CONFIG.Actor.dataModels = { character: PlayerCharacterDataModel, - group: GroupDataModel + group: GroupDataModel, + creature: CreatureDataModel, }; CONFIG.Item.dataModels = { @@ -49,7 +52,7 @@ Hooks.once("init", () => { } CONFIG.Combat.initiative = { - formula: `(@attribute.ini.wuerfel)d6 + @attribute.ini.aktuell`, + formula: `(@ini.wuerfel)d6 + @ini.aktuell`, decimals: 0 } @@ -60,6 +63,11 @@ Hooks.once("init", () => { makeDefault: true, label: 'DSA41.CharacterLabels.Item' }) + Actors.registerSheet('dsa41.creature', CreatureSheet, { + types: ["creature"], + makeDefault: true, + label : 'DSA41.CreatureLabel.Item' + }) Actors.registerSheet('dsa41.group', GroupSheet, { types: ["group"], makeDefault: true, diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index f70ac2ab..8e4a2641 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -26,6 +26,27 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { titel: new StringField(), stand: new StringField(), }), + ini: new SchemaField({ + aktuell: new NumberField({ required: true, integer: true, initial: 0 }), + mod: new NumberField({ required: true, integer: true, initial: 0 }), + wuerfel: new NumberField({ required: true, integer: true, initial: 1}), + }), + lep: new SchemaField({ + aktuell: new NumberField({ required: true, integer: true, initial: 0 }), + mod: new NumberField({ required: true, integer: true }), + }), + mr: new SchemaField({ + mod: new NumberField({ required: true, integer: true }), + }), + aup: new SchemaField({ + mod: new NumberField({ required: true, integer: true }), + }), + asp: new SchemaField({ + mod: new NumberField({ required: true, integer: true }), + }), + kap: new SchemaField({ + mod: new NumberField({ required: true, integer: true }), + }), attribute: new SchemaField({ mu: new SchemaField({ start: new NumberField({ required: true, integer: true }), @@ -67,21 +88,6 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { aktuell: new NumberField({ required: true, integer: true }), mod: new NumberField({ required: true, integer: true }), }), - mr: new SchemaField({ - mod: new NumberField({ required: true, integer: true }), - }), - lep: new SchemaField({ - mod: new NumberField({ required: true, integer: true }), - }), - aup: new SchemaField({ - mod: new NumberField({ required: true, integer: true }), - }), - asp: new SchemaField({ - mod: new NumberField({ required: true, integer: true }), - }), - kap: new SchemaField({ - mod: new NumberField({ required: true, integer: true }), - }), at: new SchemaField({ aktuell: new NumberField({ required: true, integer: true }), mod: new NumberField({ required: true, integer: true }), @@ -94,11 +100,6 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { aktuell: new NumberField({ required: true, integer: true }), mod: new NumberField({ required: true, integer: true }), }), - ini: new SchemaField({ - aktuell: new NumberField({ required: true, integer: true, initial: 0 }), - mod: new NumberField({ required: true, integer: true, initial: 0 }), - wuerfel: new NumberField({ required: true, integer: true, initial: 1}), - }), so: new SchemaField({ start: new NumberField({ required: true, integer: true }), aktuell: new NumberField({ required: true, integer: true }), diff --git a/src/module/documents/character.mjs b/src/module/documents/character.mjs index e692fb6a..de14b377 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -11,6 +11,48 @@ export class Character extends Actor { } input.click() } + + /** + * @override + * Augment the actor source data with additional dynamic data. Typically, + * you'll want to handle most of your calculated/derived data in this step. + * Data calculated in this step should generally not exist in template.json + * (such as ability modifiers rather than ability scores) and should be + * available both inside and outside of character sheets (such as if an actor + * is queried and has a roll executed directly from it). + */ + prepareDerivedData() { + + if (this.type === "character") { + const actorData = this; + const systemData = actorData.system; + + const mu = systemData.attribute.mu.aktuell; + const kl = systemData.attribute.kl.aktuell; + const _in = systemData.attribute.in.aktuell; + const ch = systemData.attribute.ch.aktuell; + + const ff = systemData.attribute.ff.aktuell; + const ge = systemData.attribute.ge.aktuell; + const ko = systemData.attribute.kk.aktuell; + const kk = systemData.attribute.kk.aktuell; + + + systemData.lep.max = (ko + ko + kk) / 2 + systemData.lep.mod; + systemData.aup.max = (mu + ko + ge) / 2 + systemData.aup.mod; + systemData.asp.aktuell = (mu + _in + ch) / 2 + systemData.asp.mod; + + systemData.at = (mu + ge + kk) / 5; + systemData.pa = (_in + ge + kk) / 5; + systemData.fk = (_in + ff + kk) / 5; + + systemData.ini.aktuell = (mu + mu + _in + ge) / 5 + systemData.ini.mod; + systemData.mr.aktuell = (mu + kl + ko) / 5 + systemData.mr.mod; + } + + + } + /** * Augment the basic Item data model with additional dynamic data. */ @@ -22,7 +64,7 @@ export class Character extends Actor { getRollData() { const data = super.getRollData(); - if (this.type !== 'character') return; + if (this.type !== 'character' && this.type !== 'creature') return; // Copy the ability scores to the top level, so that rolls can use // formulas like `@str.mod + 4`. diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index 3e413c7b..7035b618 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -173,9 +173,9 @@ export class CharacterSheet extends ActorSheet { #addCombatStatistics(context) { const actorData = context.data; - context.inidice = actorData.system.attribute.ini.wuerfel; - context.inivalue = actorData.system.attribute.ini.aktuell; - context.inimod = actorData.system.attribute.ini.mod; + context.inidice = actorData.system.ini.wuerfel; + context.inivalue = actorData.system.ini.aktuell; + context.inimod = actorData.system.ini.mod; } diff --git a/src/module/xml-import/xml-import.mjs b/src/module/xml-import/xml-import.mjs index 5d9af9b6..b9cbb5ae 100644 --- a/src/module/xml-import/xml-import.mjs +++ b/src/module/xml-import/xml-import.mjs @@ -206,19 +206,19 @@ function mapRawJson(actor, rawJson) { json.attribute.ge = getAttributeJson(attributes, "Gewandtheit") json.attribute.ko = getAttributeJson(attributes, "Konstitution") json.attribute.kk = getAttributeJson(attributes, "Körperkraft") - json.attribute.mr = { + json.mr = { mod: filterAttribute(attributes,"Magieresistenz").mod } - json.attribute.lep = { + json.lep = { mod: filterAttribute(attributes,"Lebensenergie").mod } - json.attribute.aup = { + json.aup = { mod: filterAttribute(attributes,"Ausdauer").mod } - json.attribute.asp = { + json.asp = { mod: filterAttribute(attributes,"Astralenergie").mod } - json.attribute.kap = { + json.kap = { mod: filterAttribute(attributes,"Karmaenergie").mod } let attribute = filterAttribute(attributes,"Karmaenergie") @@ -242,7 +242,7 @@ function mapRawJson(actor, rawJson) { aktuell: attribute.value } attribute = filterAttribute(attributes,"ini") - json.attribute.ini = { + json.ini = { mod: attribute.mod, aktuell: attribute.value } diff --git a/src/system.json b/src/system.json index baa3832d..f7e58186 100644 --- a/src/system.json +++ b/src/system.json @@ -95,6 +95,7 @@ ], "documentTypes": { "Actor": { + "creature": {}, "group": { }, @@ -216,8 +217,7 @@ "distance": 10, "units": "Schritt" }, - "primaryTokenAttribute": "resources.sp", - "secondaryTokenAttribute": "resources.aus", + "primaryTokenAttribute": "lep.aktuell", "url": "https://git.macniel.online/macniel/foundry-dsa41-game", "manifest": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/{{VERSION}}/system.json", "download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/{{VERSION}}/release.zip"