foundry-dsa41-game/src/module/dialog/liturgyDialog.mjs

357 lines
13 KiB
JavaScript

import {LiturgyData} from "../data/miracle/liturgydata.mjs";
import {Talent} from "../data/talent.mjs";
const {
ApplicationV2,
HandlebarsApplicationMixin
} = foundry.applications.api
export class LiturgyDialog extends HandlebarsApplicationMixin(ApplicationV2) {
static DEFAULT_OPTIONS = {
classes: ['dsa41', 'dialog', 'liturgy'],
tag: "form",
position: {
width: 480,
height: 800
},
window: {
resizable: false,
title: "Liturgie wirken"
},
form: {
submitOnChange: true,
closeOnSubmit: false,
handler: LiturgyDialog.#onSubmitForm
},
actions: {
selectVariant: LiturgyDialog.#selectVariant,
addMod: LiturgyDialog.#addModification,
removeMod: LiturgyDialog.#removeModification,
castLiturgy: LiturgyDialog.#castLiturgy,
}
}
static PARTS = {
form: {
template: 'systems/DSA_4-1/templates/dialog/liturgy-dialog.hbs',
}
}
static data = {}
static naming = {
"range": "Reichweite",
"strength": "Wirkung",
"target": "Ziele",
"castduration": "Wirkzeit",
"duration": "Wirkdauer"
}
static #romanNumerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
/**
*
* @type {Actor}
* @private
*/
_actor = null
constructor(actor, liturgyValue, liturgyId, deity) {
super()
this._actor = actor
this._liturgy = this._actor.itemTypes["Liturgy"].find(p => p._id === liturgyId)
this._deity = deity
this._maxmods = Math.round(liturgyValue / 3)
this._variations = []
Object.entries(this._liturgy.system.auswirkung).forEach(([rank, text]) => {
if (text) {
this._variations.push({
level: LiturgyDialog.#romanNumerals.findIndex(p => p === rank) + 1,
rank: rank,
effect: text
})
}
})
this._variation = this._variations[0]
this._mods = []
this._blessing = this._actor.itemTypes["Blessing"].find(p => p.system.gottheit === this._deity)
this._initialRank = 0
this._circumstance = 0
}
static async #onSubmitForm(event, form, formData) {
event.preventDefault()
this._circumstance = formData.object["circumstance"]
this.render({parts: ["form"]})
}
static #selectVariant(event, target) {
if (target.checked) {
this._variation = this._variations.find(p => p.rank === target.dataset['rank']);
this._mods = [];
}
this.render({parts: ["form"]})
event.stopPropagation()
event.preventDefault()
return false
}
static #addModification(event, target) {
event.stopPropagation()
event.preventDefault()
if (game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien")) {
const value = this.element.querySelector('select[name="mod"]').value
if (value === '') return
const currentRank = this._mods.length + (this._variation?.level ?? 0)
this._mods.push({
rank: currentRank,
displayRank: LiturgyDialog.#romanNumerals.findIndex(p => p === currentRank),
mod: value,
})
this.render({parts: ["form"]})
}
return false
}
static #removeModification(event, target) {
event.stopPropagation()
event.preventDefault()
if (game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien")) {
const {index} = target.dataset
this._mods.splice(index, 1)
this.render({parts: ["form"]})
}
return false
}
static async #castLiturgy(event, target) {
const lkp = context.lkp = this._blessing.system.wert
const resultingLiturgy = this.#getLiturgyData()
const circumstance = this._circumstance
const mod = 0 + lkp + resultingLiturgy.castPenalty - circumstance
const castingTime = this.#normalizeCastingTime(this._liturgy)
//TODO push it into the sun eeerh cooldown queue
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 => {
result.evaluatedRoll.toMessage({
speaker: ChatMessage.getSpeaker({actor: game.actors.get(data.actorId)}),
flavor: `Liturgie: ${data.title}<br/>LkP*: ${result.tap}<br/>${result.meisterlich ? "Meisterlich" : ""}${result.patzer ? "Petzer" : ""}<br/>${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,
mod: mod,
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"
}).evaluate("publicroll")
result.evaluatedRoll.toMessage({
speaker: ChatMessage.getSpeaker({actor: this._actor}),
flavor: `Liturgie: ${this._liturgy.name}<br/>Zauberdauer: ${castingTime > 0 ? castingTime + " Aktionen" : resultingLiturgy.castduration}<br/>LkP*: ${result.tap}<br/>${result.meisterlich ? "Meisterlich" : ""}${result.patzer ? "Petzer" : ""}<br/>${this._variation.effect}`,
})
}
this.close()
}
#normalizeCastingTime(liturgy) {
const castingTime = liturgy.system.zauberdauer
// direct actions
const stoßgebetRegExp = /(.*) Aktionen \(Stoßgebet\)/
const gebetRegExp = /(.*) Spielrunden? \(Gebet\)/
const invalidForCooldownRegExp = /Andacht|Zeremonie|Zyklus/
if (castingTime.match(stoßgebetRegExp)) {
const [_, actions] = castingTime.match(stoßgebetRegExp)
return actions
} else if (castingTime.match(gebetRegExp)) {
const [_, actions] = castingTime.match(gebetRegExp)
return actions * 20
} else if (castingTime.match(invalidForCooldownRegExp)) {
return -1
}
return -1
}
_configureRenderOptions(options) {
super._configureRenderOptions(options)
if (options.window) {
if (this._liturgy) {
options.window.title = `${this._liturgy.name} wirken`
}
if (game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien")) {
options.position.height = 800
} else {
options.position.height = 640
}
}
return options
}
#getLiturgyData() {
let baseline = this._liturgy.system
baseline.name = this._liturgy.name
if (game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien")) {
let upgradeDuration = false
let upgradeCastDuration = false
let upgradeStrength = false
this._mods.forEach(({mod}) => {
switch (mod) {
case "range":
break;
case "strength":
upgradeStrength = true
break;
case "target":
break;
case "castduration":
upgradeCastDuration = true
break;
case "duration":
upgradeDuration = true
break;
}
})
baseline.effectiveLevel = (this._variation?.level ?? 0) + this._mods.length
baseline.costKaP = LiturgyData.getModifiedRank(baseline.effectiveLevel).costKaP
baseline.costKaPPermanent = LiturgyData.getModifiedRank(baseline.effectiveLevel).costKaPPermanent
//baseline.mod = LiturgyData.getModifiedRank(baseline.effectiveLevel).mod
baseline.rank = LiturgyData.getModifiedRank(baseline.effectiveLevel).name
// estimate duration rank
// insert mods into text
baseline.text = this._variation.effect
const strengthRegexp = /(LkP\*.*?)[ .]/g
//baseline.text = baseline.text.replace(strengthRegexp, LiturgyData.getModifiedRank((baseline.effectiveLevel ?? 0) + upgradeStrength).strength)
const durationRegexp = /(LkP\*?.*?)(\*10 KR| Stunden| Tage| Wochen| Monate| Jahre oder permanent)/g
const effectiveDuration = LiturgyData.getModifiedDuration(baseline.duration, upgradeDuration + upgradeStrength)
baseline.duration = baseline.duration.replace(effectiveDuration.durationText, effectiveDuration.adjustedDurationText)
} else {
baseline.rank = this._variation.rank
baseline.text = this._variation.effect
baseline.target = baseline.ziel
baseline.duration = baseline.wirkungsdauer
baseline.castduration = baseline.zauberdauer
baseline.costKaP = LiturgyData.getModifiedRank(this._variation.level).costKaP
baseline.costKaPPermanent = LiturgyData.getModifiedRank(this._variation.level).costKaPPermanent
if (this._variation.level > this._liturgy.system.herkunft.find(p => p.name === this._deity).grad) {
baseline.castPenalty = LiturgyData.getModifiedRank(this._liturgy.system.herkunft.find(p => p.name === this._deity).grad).mod
} else {
baseline.castPenalty = LiturgyData.getModifiedRank(this._variation.level).mod
}
}
return baseline
}
async _prepareContext(options) {
const context = await super._prepareContext(options)
context.actor = this._actor
context.liturgy = this._liturgy
context.mods = this._mods
context.variation = this._variation
context.maxmods = this._maxmods
context.variations = this._variations
context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice')
context.mu = {wert: this._actor.system.attribute.mu.aktuell, name: "MU", tooltip: "Mut"}
context.in = {wert: this._actor.system.attribute.in.aktuell, name: "IN", tooltip: "Intuition"}
context.ch = {wert: this._actor.system.attribute.ch.aktuell, name: "CH", tooltip: "Charisma"}
context.moddingEnabled = game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien")
context.canMod = game.settings.get("DSA_4-1", "optional_aufstufen_von_liturgien") && (this._maxmods - (this._variation?.level ?? 0) - this._mods.length) >= 0
context.addingModRank = LiturgyDialog.#romanNumerals[(context._variation?.level ?? 0) + this._mods.length + 1]
context.lkp = this._blessing.system.wert
context.deity = this._blessing.system.name
context.resultingLiturgy = this.#getLiturgyData()
context.resultingCastPenalty = 0
context.circumstance = this._circumstance
if (context.resultingLiturgy.castPenalty > 0) {
context.resultingCastPenalty = `+${context.resultingLiturgy.castPenalty}`
} else {
context.resultingCastPenalty = context.resultingLiturgy.castPenalty
}
context.modResult = 0 + context.lkp + context.resultingLiturgy.castPenalty - this._circumstance
context.displayModResult = context.modResult > 0 ? "+" + context.modResult : context.modResult
return context
}
}