From 99485215126126c766c3b2f4e186999dbdbca773 Mon Sep 17 00:00:00 2001 From: macniel Date: Fri, 31 Oct 2025 19:15:15 +0100 Subject: [PATCH] liturgies can now be pushed into queue. --- package.json | 1 + src/main.mjs | 4 +- src/module/dialog/combatAction.mjs | 7 ++- src/module/dialog/liturgyDialog.mjs | 55 ++++++++++++++++++-- src/module/sheets/actions/action-manager.mjs | 29 ++++++++++- src/module/sheets/characterSheet.mjs | 26 ++++++--- src/style/atoms/_colours.scss | 22 ++++---- src/style/molecules/_sidebar-elements.scss | 20 +++++++ src/system.json | 4 +- src/templates/actor/character/main-sheet.hbs | 6 +-- 10 files changed, 142 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 6d4f60aa..5d99859c 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "scripts": { "test": "true", "build": "gulp", + "localBuild": "VERSION=0.0.1 gulp", "installToFoundry": "node installToFoundry.mjs" }, "devDependencies": { diff --git a/src/main.mjs b/src/main.mjs index b77cf4e8..fa265965 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -32,6 +32,7 @@ import {MerchantDataModel} from "./module/data/merchant.mjs"; import {MerchantSheet} from "./module/sheets/merchantSheet.mjs"; import {RestingDialog} from "./module/dialog/restingDialog.mjs"; import {BattleDialog} from "./module/dialog/battleDialog.mjs"; +import {Talent} from "./module/data/talent.mjs"; async function preloadHandlebarsTemplates() { return foundry.applications.handlebars.loadTemplates([ @@ -60,7 +61,8 @@ Hooks.once("init", () => { Trefferzone, Wunde, RestingDialog, - BattleDialog + BattleDialog, + Talent } // Configure custom Document implementations. diff --git a/src/module/dialog/combatAction.mjs b/src/module/dialog/combatAction.mjs index fee7e713..e50061f8 100644 --- a/src/module/dialog/combatAction.mjs +++ b/src/module/dialog/combatAction.mjs @@ -89,7 +89,8 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 weapon: this._weaponId, skill: this._skillId, target: this._targetId, - maneuver, + title: maneuver.name, + maneuver: maneuver.activate.toString(), mod: this._mod, circumstance: this._circumstance, penalty: this._penalty, @@ -104,10 +105,12 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 start: maneuver.cooldown({weapon, skill, target, mod: this._mod}), current: maneuver.cooldown({weapon, skill, target, mod: this._mod}), data: { + cssClass: "Kampf", weapon: this._weaponId, skill: this._skillId, target: this._targetId, - maneuver, + title: maneuver.name, + maneuver: maneuver.activate.toString(), mod: this._mod, circumstance: this._circumstance, penalty: this._penalty, diff --git a/src/module/dialog/liturgyDialog.mjs b/src/module/dialog/liturgyDialog.mjs index bdb70a67..90431acc 100644 --- a/src/module/dialog/liturgyDialog.mjs +++ b/src/module/dialog/liturgyDialog.mjs @@ -135,10 +135,55 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { const castingTime = this.#normalizeCastingTime(this._liturgy) //TODO push it into the sun eeerh cooldown queue - //if (castingTime > 0) { + if (castingTime > 0) { + const cooldowns = this._actor.system.cooldowns + let m = (queue, data) => { + new game.DSA41.Talent({ + name: data.title, + taw: data.taw, + mod: data.mod, + eigenschaften: { + mu: data.eigenschaften.mu, + in: data.eigenschaften.in, + ch: data.eigenschaften.ch, + }, + eigenschaft1: "mu", + eigenschaft2: "in", + eigenschaft3: "ch" + }).evaluate("publicroll").then(result => { - // this._actor.system.cooldowns.push() - //} else { + result.evaluatedRoll.toMessage({ + speaker: ChatMessage.getSpeaker({actor: game.actors.get(data.actorId)}), + flavor: `Liturgie: ${data.title}
LkP*: ${result.tap}
${result.meisterlich ? "Meisterlich" : ""}${result.patzer ? "Petzer" : ""}
${data.variant}`, + }) + }) + } + cooldowns.push({ + start: castingTime, + current: castingTime, + data: { + cssClass: "Karmal", + title: this._liturgy.name, + taw: lkp, + mod: mod, + actorId: this._actor._id, + variant: this._variation.effect, + eigenschaften: { + mu: this._actor.system.attribute.mu.aktuell, + in: this._actor.system.attribute.in.aktuell, + ch: this._actor.system.attribute.ch.aktuell, + }, + eigenschaft1: "mu", + eigenschaft2: "in", + eigenschaft3: "ch", + circumstance: circumstance, + maneuver: m.toString() + } + + }) + await this._actor.update({"system.cooldowns": cooldowns}) + ui.notifications.info(`Neue Aktion für ${this._liturgy.name} mit Abklingzeit von ${castingTime} Aktionen hinzugefügt`); + } else { const result = await new Talent({ name: this._liturgy.name, taw: lkp, @@ -157,7 +202,7 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { speaker: ChatMessage.getSpeaker({actor: this._actor}), flavor: `Liturgie: ${this._liturgy.name}
Zauberdauer: ${castingTime > 0 ? castingTime + " Aktionen" : resultingLiturgy.castduration}
LkP*: ${result.tap}
${result.meisterlich ? "Meisterlich" : ""}${result.patzer ? "Petzer" : ""}
${this._variation.effect}`, }) - //} + } this.close() } @@ -175,7 +220,7 @@ export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) { const [_, actions] = castingTime.match(stoßgebetRegExp) return actions } else if (castingTime.match(gebetRegExp)) { - const [_, actions] = castingTime.match(stoßgebetRegExp) + const [_, actions] = castingTime.match(gebetRegExp) return actions * 20 } else if (castingTime.match(invalidForCooldownRegExp)) { return -1 diff --git a/src/module/sheets/actions/action-manager.mjs b/src/module/sheets/actions/action-manager.mjs index ec66f937..c48e0765 100644 --- a/src/module/sheets/actions/action-manager.mjs +++ b/src/module/sheets/actions/action-manager.mjs @@ -80,7 +80,11 @@ export class ActionManager { type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, - eval: (options) => this.#hatWaffeinHand(options) + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, + eval: (options) => this.#hatWaffeinHand(options), }, { name: "Fernkampfangriff", @@ -89,6 +93,8 @@ export class ActionManager { source: ActionManager.DEFAULT, cooldown: (options) => 1, activate: (queue, data) => { + data.actor.rollAttack(data) + return true }, eval: (options) => this.#hatFernkampfWaffeinHand(options), }, @@ -98,6 +104,10 @@ export class ActionManager { cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, cooldown: (options) => options.mod, + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = this.#hatFernkampfWaffeinHand(options) const step2 = !this.#hatSonderfertigkeit("Scharfschütze", options) @@ -117,6 +127,7 @@ export class ActionManager { source: ActionManager.SF, cooldown: (options) => options.mod - 2, activate: (queue, data) => { + console.log(queue, data) data.actor.rollAttack(data) return true }, @@ -211,6 +222,10 @@ export class ActionManager { source: ActionManager.SF, modDescription: "verringert PA des Ziels um {}", mod: (value) => value, + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = this.#hatWaffeinHand(options) && this.#hatSonderfertigkeit("Finte", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Finte", options) @@ -227,6 +242,10 @@ export class ActionManager { source: ActionManager.DEFAULT, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -(value * 2), + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) const step2 = !this.#hatSonderfertigkeit("Wuchtschlag", options) @@ -244,6 +263,10 @@ export class ActionManager { source: ActionManager.SF, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -(value), + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Wuchtschlag", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Wuchtschlag", options) @@ -258,6 +281,10 @@ export class ActionManager { type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.SF, + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Betäubungsschlag", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Betäubungsschlag", options) diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index 5fdbd5ee..30337909 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -146,7 +146,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { cooldowns.push(cooldown) this.document.update({"system.cooldowns": cooldowns.sort((a, b) => a.current - b.current)}) - ui.notifications.info(`Abklingzeit von ${cooldown.data.maneuver.name} um 1 Aktion reduziert`) + ui.notifications.info(`Abklingzeit von ${cooldown.data.title} um 1 Aktion reduziert`) } static async #cancelCooldown(event, target) { @@ -167,17 +167,18 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { if (cooldown && cooldown.current <= 0) { const am = new ActionManager(this.document) - const action = am.evaluate().find(action => action.name === cooldown.data.maneuver.id) + console.log(cooldown.data.maneuver) + const action = new Function(`return ${cooldown.data.maneuver}`) if (action) { - action.activate(cooldowns, {...cooldown.data, actor: this.document}) + action()(this.document.system.cooldowns, {...cooldown.data, actor: this.document}) } } cooldowns.splice(cooldownId, 1) this.document.update({"system.cooldowns": cooldowns.sort((a, b) => a.current - b.current)}) - ui.notifications.info(`${cooldown.data.maneuver.name} ausgeführt`) + ui.notifications.info(`${cooldown.data.title} ausgeführt`) } /** @@ -426,11 +427,20 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { context.cooldowns = actorData.system.cooldowns ?? [] context.cooldowns.forEach(cooldown => { - const weapon = this.document.itemTypes["Equipment"].find(p => p._id === cooldown.data.weapon) - const skill = this.document.itemTypes["Skill"].find(p => p._id === cooldown.data.skillId) - const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === cooldown.data.target).actorId) + let weapon = null + let target = null + let tooltip = cooldown.data.title + if (cooldown.data.weapon) { + weapon = this.document.itemTypes["Equipment"].find(p => p._id === cooldown.data.weapon) + tooltip += `
Waffe:${weapon.name}` + } + if (cooldown.data.target) { + target = game.actors.get(game.scenes.current.tokens.find(p => p._id === cooldown.data.target).actorId) + tooltip += `
Waffe:${target.name}` + } + cooldown.title = cooldown.data.title cooldown.progress = ((cooldown.current / cooldown.start) * 100) + "%" - cooldown.tooltip = `${cooldown.data.maneuver.name}
Waffe:${weapon.name}
Ziel: ${target.name}
Wurfziel: ${cooldown.data.targetNumber}
Aktionen verbleibend: ${cooldown.current}` + cooldown.tooltip = tooltip + `
Aktionen verbleibend: ${cooldown.current}` }) context.hasSpells = actorData.itemTypes["Spell"].length > 0 diff --git a/src/style/atoms/_colours.scss b/src/style/atoms/_colours.scss index bcbe7eec..143d6026 100644 --- a/src/style/atoms/_colours.scss +++ b/src/style/atoms/_colours.scss @@ -1,13 +1,13 @@ -$nachteil-color: #555753ff; -$nachteil-text-color: #FFFF; -$liturgie-color: #edd400ff; -$liturgie-text-color: #000F; -$zauber-color: #3465a4ff; -$zauber-text-color: #000F; -$talent-color: #f57900ff; -$talent-text-color: #000F; -$kampftalent-color: #cc0000ff; -$kampftalent-text-color: #FFFF; +$nachteil-color: #555753; +$nachteil-text-color: #FFF; +$liturgie-color: #edd400; +$liturgie-text-color: #000; +$zauber-color: #3465a4; +$zauber-text-color: #000; +$talent-color: #f57900; +$talent-text-color: #000; +$kampftalent-color: #cc0000; +$kampftalent-text-color: #FFF; $talent-body-color: #16bd6c; $talent-body-text-color: #000; @@ -79,3 +79,5 @@ $default-action-color: #000; $special-action: rgba(68, 34, 204, 0.8); $special-action-color: #000; + + diff --git a/src/style/molecules/_sidebar-elements.scss b/src/style/molecules/_sidebar-elements.scss index 8b5921a0..2ec297a8 100644 --- a/src/style/molecules/_sidebar-elements.scss +++ b/src/style/molecules/_sidebar-elements.scss @@ -1,3 +1,6 @@ +@use "../atoms/colours" as colors; +@use "sass:color"; + .dsa41.sheet.actor.character { .head-data { @@ -234,6 +237,23 @@ background-color: rgba(0, 0, 0, 0.8); } + + &.Kampf .progress::after { + background-color: rgba(colors.$kampftalent-color, 0.5); + } + + &.Karmal .progress::after { + background-color: rgba(colors.$liturgie-color, 0.5); + } + + &.Magisch .progress::after { + background-color: rgba(colors.$zauber-color, 0.5); + } + + &.Talent .progress::after { + background-color: rgba(colors.$talent-color, 0.5); + } + } } diff --git a/src/system.json b/src/system.json index 3d2ce40b..bd2faaa5 100644 --- a/src/system.json +++ b/src/system.json @@ -2,7 +2,7 @@ "id": "DSA_4-1", "title": "Das Schwarze Auge 4.1", "description": "Noch ein Spielsystem für Das Schwarze Auge 4.1", - "version": "0.3.3", + "version": "0.0.1", "compatibility": { "minimum": 12, "verified": 13 @@ -348,5 +348,5 @@ "primaryTokenAttribute": "lep.aktuell", "url": "https://git.macniel.online/macniel/foundry-dsa41-game", "manifest": "https://git.macniel.online/macniel/foundry-dsa41-game/raw/branch/main/src/system.json", - "download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.3.3/release.zip" + "download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.0.1/release.zip" } diff --git a/src/templates/actor/character/main-sheet.hbs b/src/templates/actor/character/main-sheet.hbs index 94027a79..e4420fc3 100644 --- a/src/templates/actor/character/main-sheet.hbs +++ b/src/templates/actor/character/main-sheet.hbs @@ -91,13 +91,13 @@

Abklingzeiten

{{#each this.cooldowns}} -
+
{{#if (gt this.current 0)}} - {{this.data.maneuver.name}} + {{this.title}} @@ -105,7 +105,7 @@ - {{this.data.maneuver.name}} + {{this.title}}