From 469025ca05e2f5032ebc3b3b0ab48628749edd3b Mon Sep 17 00:00:00 2001 From: macniel Date: Sat, 7 Feb 2026 10:32:48 +0100 Subject: [PATCH] adds combat-awareness to attacks/defenses/spells/liturgies --- src/module/dialog/combatAction.mjs | 92 ++++++++++++--------- src/module/dialog/defenseAction.mjs | 73 ++++++++-------- src/module/dialog/liturgyDialog.mjs | 9 +- src/module/dialog/spellDialog.mjs | 11 ++- src/module/documents/character.mjs | 2 + src/module/sheets/characterSheet.mjs | 2 +- src/templates/chat/attack-chat-message.hbs | 1 + src/templates/chat/liturgy-chat-message.hbs | 1 + src/templates/chat/spell-chat-message.hbs | 1 + src/templates/dialog/combat-action.hbs | 4 +- 10 files changed, 110 insertions(+), 86 deletions(-) diff --git a/src/module/dialog/combatAction.mjs b/src/module/dialog/combatAction.mjs index 05eaae06..4a7b6de3 100644 --- a/src/module/dialog/combatAction.mjs +++ b/src/module/dialog/combatAction.mjs @@ -59,6 +59,9 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 this._defenseManeuverId = null this._actionManager = new ActionManager(this._actor) CombatActionDialog._instance = this + if (!game.scenes.current?.grid.units) { + this._targetId = actor._id + } } static _instance = null @@ -106,7 +109,7 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 const maneuver = CombatActionDialog._instance.#evaluateManeuvers().find(p => p.id === this._defenseManeuverId) const weapon = this._actor.itemTypes["Equipment"].find(p => p._id === this._weaponId) const skill = this._actor.itemTypes["Skill"].find(p => p._id === this._skillId) - const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === this._targetId).actorId) + const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === this._targetId)?.actorId) ?? this._actor if (maneuver.cost !== ActionManager.CONTINUING) { this._actor.rollAttack({ weapon: this._weaponId, @@ -123,10 +126,15 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 return true } else { // push into cooldown queue const cooldowns = this._actor.system.cooldowns + let currentCooldown = 0 + if (game.combats.size === 0) { // no combat started + currentCooldown = maneuver.cooldown({weapon, skill, target, mod: this._mod}) + } + /** @type Cooldown */ const newCooldown = { start: maneuver.cooldown({weapon, skill, target, mod: this._mod}), - current: 0, + current: currentCooldown, data: { cssClass: "Kampf", weapon: this._weaponId, @@ -138,6 +146,7 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 circumstance: this._circumstance, penalty: this._penalty, targetNumber: this._targetNumber, + castingTime: maneuver.cooldown({weapon, skill, target, mod: this._mod}), modDescription: maneuver?.modDescription?.replace("{}", "" + this._mod) ?? "" } } @@ -261,7 +270,7 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 const manager = this._actionManager const weapon = this._actor.itemTypes["Equipment"].find(p => p._id === this._weaponId) const skill = this._actor.itemTypes["Skill"].find(p => p._id === this._skillId) - const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === this._targetId).actorId) + const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === this._targetId)?.actorId) ?? this._actor this._maneuvers = manager.evaluate({ target, weapon, @@ -293,47 +302,48 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 if (context.distanceUnit && this._actor.getActiveTokens()[0]?.id) { context.tokenDistances = this.#evaluateDistances() - context.weapons = this.#evaluateWeapons() - - if (this._targetId && this._weaponId && this._skillId) { - context.maneuver = this.#evaluateManeuvers() - } - const maneuver = this._maneuvers?.find(p => p.id === this._defenseManeuverId) - if (maneuver) { - context.canMod = maneuver.mod != undefined - } - - context.targetNumber = context.weapons.find(p => p.weaponId === this._weaponId && p.skillId === this._skillId)?.combatStatistics.at - - // TODO get W/M of weapon NOW - - if (this._targetNumber >= 0 && this._targetId && this._weaponId && this._skillId && maneuver) { - context.ready = true - } else { - context.notReadyReason = `${game.i18n.format("COMBAT_DIALOG.notReadyReason.title")}" - context.ready = false - } - return context + context.hasTokens = true } else { - ui.notifications.error(`Feature funktioniert nur wenn der Akteur ein Token auf der aktuellen Szene hat`); + context.tokenDistances = [] + context.hasTokens = false + } + context.weapons = this.#evaluateWeapons() + + if ( (this._targetId || !context.hasTokens) && this._weaponId && this._skillId) { + context.maneuver = this.#evaluateManeuvers() + } + const maneuver = this._maneuvers?.find(p => p.id === this._defenseManeuverId) + if (maneuver) { + context.canMod = maneuver.mod != undefined } + context.targetNumber = context.weapons.find(p => p.weaponId === this._weaponId && p.skillId === this._skillId)?.combatStatistics.at + + // TODO get W/M of weapon NOW + + if (this._targetNumber >= 0 && this._targetId && this._weaponId && this._skillId && maneuver) { + context.ready = true + } else { + context.notReadyReason = `${game.i18n.format("COMBAT_DIALOG.notReadyReason.title")}" + context.ready = false + } + return context } #update(context) { diff --git a/src/module/dialog/defenseAction.mjs b/src/module/dialog/defenseAction.mjs index 5e136d90..67b307cf 100644 --- a/src/module/dialog/defenseAction.mjs +++ b/src/module/dialog/defenseAction.mjs @@ -1,4 +1,4 @@ -import {ActionManager} from "../sheets/actions/action-manager.mjs"; + import {ActionManager} from "../sheets/actions/action-manager.mjs"; const { ApplicationV2, @@ -236,49 +236,42 @@ export class DefenseActionDialog extends HandlebarsApplicationMixin(ApplicationV const context = await super._prepareContext(options) context.actor = this._actor - context.distanceUnit = game.scenes.current.grid.units - if (this._actor.getActiveTokens()[0]?.id) { + context.weapons = this.#evaluateWeapons() - context.weapons = this.#evaluateWeapons() - - if (this._skillId) { - context.maneuver = this.#evaluateManeuvers() - } - const maneuver = this._maneuvers?.find(p => p.id === this._defenseManeuverId) - if (maneuver) { - context.canMod = maneuver.mod != undefined - } - - context.targetNumber = context.weapons.find(p => ((this._weaponId != "") || p.weaponId === this._weaponId) && p.skillId === this._skillId)?.combatStatistics.pa - - // TODO get W/M of weapon NOW - - if (this._weaponId && this._skillId && this._defenseManeuverId) { - context.ready = true - } else { - context.notReadyReason = `${game.i18n.format("COMBAT_DIALOG.notReadyReason.title")}" - context.ready = false - } - - return context - } else { - ui.notifications.error(`Feature funktioniert nur wenn der Akteur ein Token auf der aktuellen Szene hat`); + if (this._skillId) { + context.maneuver = this.#evaluateManeuvers() + } + const maneuver = this._maneuvers?.find(p => p.id === this._defenseManeuverId) + if (maneuver) { + context.canMod = maneuver.mod != undefined } + context.targetNumber = context.weapons.find(p => ((this._weaponId != "") || p.weaponId === this._weaponId) && p.skillId === this._skillId)?.combatStatistics.pa + + // TODO get W/M of weapon NOW + + if (this._weaponId && this._skillId && this._defenseManeuverId) { + context.ready = true + } else { + context.notReadyReason = `${game.i18n.format("COMBAT_DIALOG.notReadyReason.title")}" + context.ready = false + } + + return context } #update(context) { diff --git a/src/module/dialog/liturgyDialog.mjs b/src/module/dialog/liturgyDialog.mjs index 1c54a152..11ed2830 100644 --- a/src/module/dialog/liturgyDialog.mjs +++ b/src/module/dialog/liturgyDialog.mjs @@ -157,6 +157,7 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { eigenschaft3: "ch" }).evaluate("publicroll").then(result => { const context = { + ...data, liturgy: data.title, lkw: data.taw, mod: data.mod, @@ -185,9 +186,14 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { }) } + + let currentCooldown = 0 + if (game.combats.size === 0) { // no combat started + currentCooldown = castingTime + } cooldowns.push({ start: castingTime, - current: 0, + current: currentCooldown, data: { cssClass: "Karmal", title: this._liturgy.name, @@ -205,6 +211,7 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { eigenschaft2: "in", eigenschaft3: "ch", circumstance: circumstance, + castingTime: castingTime, maneuver: m.toString() } diff --git a/src/module/dialog/spellDialog.mjs b/src/module/dialog/spellDialog.mjs index 11d2e9b5..e9162713 100644 --- a/src/module/dialog/spellDialog.mjs +++ b/src/module/dialog/spellDialog.mjs @@ -209,7 +209,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) { } let message = this._spell.system.wirkung - if (this._activeVariants.length > 0) { + if (this._activeVariants?.length > 0 ?? false) { message += "
" message += this._activeVariants.map(v => v.name).join(", ") } @@ -231,9 +231,14 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) { message += "
" + this.zfp + " ZfP*
" + this._spell.system.zfw + " ZfW" + let currentCooldown = 0 + if (game.combats.size === 0) { // no combat started + currentCooldown = this.castingTime + } + cooldowns.push({ start: this.castingTime, - current: 0, + current: currentCooldown, data: { cssClass: "Magisch", title: this._spell.name, @@ -242,6 +247,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) { actorId: this._actor._id, spellId: this._spell._id, message, + castingTime: this.castingTime, maneuver: m.toString() } @@ -270,6 +276,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) { const context = { spell: this._spell, + castingTime : this.castingTime, zfp: result.tap, ergebnis: [ diff --git a/src/module/documents/character.mjs b/src/module/documents/character.mjs index 742d283f..d4e92dd6 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -493,6 +493,7 @@ export class Character extends Actor { }) const context = { + ...data, weapon: weapon.name, maneuver, target: this.name, @@ -539,6 +540,7 @@ export class Character extends Actor { }) const context = { + ...data, weapon: weapon.name, maneuver, target: target.name, diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index acf22242..be851e43 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -595,7 +595,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { weapon = this.document.itemTypes["Equipment"].find(p => p._id === cooldown.data.weapon) tooltip += `
Waffe: ${weapon.name}` } - if (cooldown.data.target) { + if (cooldown.data.target && game.scenes.current.tokens.length > 0) { target = game.actors.get(game.scenes.current.tokens.find(p => p._id === cooldown.data.target).actorId) tooltip += `
Ziel: ${target.name}` } diff --git a/src/templates/chat/attack-chat-message.hbs b/src/templates/chat/attack-chat-message.hbs index d5d878c4..09ea047a 100644 --- a/src/templates/chat/attack-chat-message.hbs +++ b/src/templates/chat/attack-chat-message.hbs @@ -5,6 +5,7 @@
Gewürfelt: {{die}}
Erschwernis: {{circumstance}}
Modifikation: {{mod}}
+
Dauer in Aktionen: {{castingTime}}

{{#if missing}}
Gefehlt: {{missing}} {{#if fumble}}Patzer{{/if}}
diff --git a/src/templates/chat/liturgy-chat-message.hbs b/src/templates/chat/liturgy-chat-message.hbs index 97d56a5b..61f27bbd 100644 --- a/src/templates/chat/liturgy-chat-message.hbs +++ b/src/templates/chat/liturgy-chat-message.hbs @@ -3,6 +3,7 @@
{{liturgy}} (LkP*: {{lkp}})
Modifiziert: {{mod}}
+
Dauer in Aktionen: {{castingTime}}
Gewürfelt:

{{#if missing}} diff --git a/src/templates/chat/spell-chat-message.hbs b/src/templates/chat/spell-chat-message.hbs index 3951e391..167a0e1e 100644 --- a/src/templates/chat/spell-chat-message.hbs +++ b/src/templates/chat/spell-chat-message.hbs @@ -3,6 +3,7 @@
{{spell.name}} (ZfP*: {{zfp}})
Modifiziert: {{mod}}
+
Zauberdauer: {{castingTime}}
Gewürfelt:
{{#each ergebnis}} diff --git a/src/templates/dialog/combat-action.hbs b/src/templates/dialog/combat-action.hbs index 8fdad05a..d5a4688a 100644 --- a/src/templates/dialog/combat-action.hbs +++ b/src/templates/dialog/combat-action.hbs @@ -1,6 +1,8 @@
+ {{#if hasTokens}}
+ Ziel auswählen
    @@ -13,7 +15,7 @@
- + {{/if}}
Waffe auswählen