const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api export class RestingDialog extends HandlebarsApplicationMixin(ApplicationV2) { static DEFAULT_OPTIONS = { classes: ['dsa41', 'dialog', 'resting'], tag: "form", position: { width: 480, height: 800 }, window: { resizable: false, title: "Rasten und Regenerieren" }, form: { submitOnChange: true, closeOnSubmit: false, handler: RestingDialog.#onSubmitForm }, actions: { regenerate: RestingDialog.#regenerate } } static PARTS = { form: { template: 'systems/DSA_4-1/templates/dialog/resting-dialog.hbs', } } /** * @type {Actor} * @private */ _actor = null /** * @typedef RestingCircumstance * @property {String} name Displaytext of this circumstance modifier * @property {Number|[Number]} aspMod modifier to AsP regeneration * @property {Number|[Number]} lepMod modifier to LeP regeneration * @property {Boolean|Number} active indicates if this modifier is active and or which index of aspMod/lepMod to be used */ /** * @typedef RestingOptions * @property {Number} length the time of this rest, will be used for reducing exhaustion and overexertion * @property {Number} wounds the amount of wounds the actor has suffered * @property {Number|Boolean} treated if the wounds have been treated with the Skill "Heilkunde: Wunden" the Value is the Modificator for the wound regeneration * @property {RestingCircumstance} circumstances the circumstances of this Rest */ #type = { DRAUßEN: "draußen", SCHLAFSAAL: "schlafsaal", EINZELZIMMER: "einzelzimmer", SUITE: "suite", } /** * @type {[RestingCircumstance]} * @private */ #circumstances = [ { name: "Ruhestörung", display: "boolean", lepMod: -1, aspMod: -1, group: "interrupted", active: false, value: "on" }, { name: "Wache gehalten", display: "boolean", lepMod: -1, aspMod: -1, group: "watch", active: false, value: "on" }, { name: "Unter freiem Himmel", display: "radio", aspMod: 0, lepMod: 0, active: false, value: this.#type.DRAUßEN, group: "type" }, { name: "Schlechtes Wetter", aspMod: [-1, -2, -3, -4, -5], lepMod: [-1, -2, -3, -4, -5], display: "range", noLabel: "Gutes Wetter", labels: [ "Schlechtes Wetter I", "Schlechtes Wetter II", "Schlechtes Wetter III", "Schlechtes Wetter IV", "Schlechtes Wetter V", ], group: "bad_weather", active: -1, }, { name: "Schlechter Lagerplatz", aspMod: -1, lepMod: -1, display: "boolean", group: "bad_camp", active: false, value: "on" }, { name: "Magere Lagerstätte (Schlafsaal, Heuboden)", aspMod: 0, lepMod: 0, display: "radio", group: "type", value: this.#type.SCHLAFSAAL, active: false, }, { name: "Komfortable Schlafstätte", aspMod: 1, lepMod: 1, display: "radio", group: "type", value: this.#type.EINZELZIMMER, active: false, }, { name: "Luxuriöse Schlafstätte (Suite)", aspMod: 2, lepMod: 2, display: "radio", group: "type", value: this.#type.SUITE, active: false, } ] constructor(actor) { super(); this._actor = actor; this.restDuration = 6 this.restingType = this.#circumstances.find(p => p.value === this.#type.DRAUßEN) this.badWeather = -1 this.woundTreated = false this.woundRegenerationModifier = 0 this.wounds = 1 this.badCamp = false this.watch = false this.interrupted = false this.lepModifier = this._actor.system.regeneration.lep.split("d6")[1] this.aspModifier = this._actor.system.regeneration.asp.split("d6")[1] this.regKoMod = this._actor.system.regeneration.ko this.regInMod = this._actor.system.regeneration.in } static async #regenerate() { const context = this.#updateData() const rollData = this._actor.getRollData() // regenerate LeP const targetBonusLep = rollData.attribute.ko.aktuell + context.koRoll const targetBonusAsp = rollData.attribute.in.aktuell + context.inRoll const regenerationRoll = await new Roll("1d20[Konstitution]+1d20[Intuition]+1d20[Konstitution] + 2d6").evaluate() const [koRoll, _, inRoll, __, woundRoll, ___, lepAndAsp] = regenerationRoll.terms // the 3d20s const plusLep = koRoll.results[0].result <= targetBonusLep ? 1 : 0 const plusAsp = inRoll.results[0].result <= targetBonusAsp ? 1 : 0 const woundHealed = woundRoll.results[0].result <= rollData.attribute.ko.aktuell + (context.woundMod * -1) const [regLep, regAsp] = lepAndAsp.results // the 2d6s await regenerationRoll.toMessage({ speaker: ChatMessage.getSpeaker({actor: this.actor}), flavor: `Regeneration in der Nacht:
LE: ${regLep.result} ${context.lepMod > 0 ? ("+" + context.lepMod) : ""} ${plusLep > 0 ? "+1" : ""}
AE: ${regAsp.result} ${context.aspMod > 0 ? ("+" + context.aspMod) : ""} ${plusAsp > 0 ? "+1" : ""}
Wunde: ${woundHealed ? "geheilt" : "nicht geheilt"}`, rollMode: game.settings.get('core', 'rollMode'), }) this.close() } static async #onSubmitForm(event, form, formData) { event.preventDefault() this.restDuration = formData.object.length this.restingType = formData.object.type this.badWeather = formData.object.bad_weather this.woundTreated = formData.object.wound_treated this.woundRegenerationModifier = formData.object.wound_treat_modifier this.wounds = formData.object.wounds this.badCamp = formData.object.bad_camp === "on" this.watch = formData.object.watch === "on" this.interrupted = formData.object.interrupted === "on" const elementLepMod = this.element.querySelector('output[name="lepMod"]') const elementKoMod = this.element.querySelector('output[name="koMod"]') const elementAspMod = this.element.querySelector('output[name="aspMod"]') const elementInMod = this.element.querySelector('output[name="inMod"]') const elementWoundMod = this.element.querySelector('output[name="woundMod"]') const context = this.#updateData() elementLepMod.value = context.lepModDisplay elementKoMod.value = context.koRollDisplay elementAspMod.value = context.aspModDisplay elementInMod.value = context.inRollDisplay elementWoundMod.value = context.woundModDisplay } #updateData(context = {}) { context.circumstances = this.#circumstances context.actorId = this._actor._id context.hasWounds = true context.hasAsP = true context.wounds = this.wounds // TODO count wounds let lepRestModifier = 0 let aspRestModifier = 0 if (this.restingType) { const circ = this.#circumstances.find(p => p.value === this.restingType) if (circ) { lepRestModifier += Number(circ.lepMod) aspRestModifier += Number(circ.aspMod) } } if (this.restingType === this.#type.DRAUßEN && this.badWeather !== -1) { const circ = this.#circumstances.find(p => p.group === "bad_weather") if (circ) { if (circ["lepMod"][this.badWeather] !== 0) { lepRestModifier += circ["lepMod"][this.badWeather] } if (circ["aspMod"][this.badWeather] !== 0) { aspRestModifier += circ["aspMod"][this.badWeather] } } } if (this.woundTreated) { context.woundModDisplay = `1w20-${this.woundRegenerationModifier ?? 0}` context.woundMod = this.woundRegenerationModifier ?? 0 } else { if (context.hasWounds) { context.woundModDisplay = `1w20+${context.wounds * 3}` context.woundMod = context.wounds * 3 } } if (this.restingType === this.#type.DRAUßEN && this.badCamp) { const circ = this.#circumstances.find(p => p.group === "bad_camp") if (circ) { lepRestModifier += Number(circ.lepMod) aspRestModifier += Number(circ.aspMod) } } if (this.watch) { const circ = this.#circumstances.find(p => p.group === "watch") if (circ) { lepRestModifier += Number(circ.lepMod) aspRestModifier += Number(circ.aspMod) } } if (this.interrupted) { const circ = this.#circumstances.find(p => p.group === "interrupted") if (circ) { lepRestModifier += Number(circ.lepMod) aspRestModifier += Number(circ.aspMod) } } const lepMod = (Number(this.lepModifier) + (lepRestModifier)) ?? 0 const aspMod = (Number(this.aspModifier) + (aspRestModifier)) ?? 0 context.lepMod = lepMod if (lepMod == 0) { context.lepModDisplay = "1w6" } else if (lepMod > 0) { context.lepModDisplay = "1w6+" + lepMod } else { context.lepModDisplay = "1w6" + lepMod } context.aspMod = aspMod if (aspMod == 0) { context.aspModDisplay = "1w6" } else if (lepMod > 0) { context.aspModDisplay = "1w6+" + aspMod } else { context.aspModDisplay = "1w6" + aspMod } context.koRoll = this.regKoMod if (this.regKoMod < 0) { context.koRollDisplay = `1w20${this.regKoMod}` } else { context.koRollDisplay = `1w20+${this.regKoMod}` } context.inRoll = this.regInMod if (this.regInMod < 0) { context.inRollDisplay = `1w20${this.regInMod}` } else { context.inRollDisplay = `1w20+${this.regInMod}` } console.log(this, context) return context } async _prepareContext(options) { const context = await super._prepareContext(options) return this.#updateData(context) } _onRender(context, options) { } }