finalises spell system on basic implementation level

pull/67/head
macniel 2025-12-03 20:07:35 +01:00
parent 98864464b1
commit 75280e5590
6 changed files with 88 additions and 11 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 280 B

View File

@ -49,7 +49,8 @@
"title": "Zauber kann aus folgenden Gründen nicht gewirkt werden:", "title": "Zauber kann aus folgenden Gründen nicht gewirkt werden:",
"noRepresentation": "Keine Repräsentation gewählt", "noRepresentation": "Keine Repräsentation gewählt",
"tooManySpoMods": "Zu viele Spontane Modifikationen ausgewählt", "tooManySpoMods": "Zu viele Spontane Modifikationen ausgewählt",
"noZFPDataAvailable": "Noch keine Zauberprobe gewürfelt" "noZFPDataAvailable": "Noch keine Zauberprobe gewürfelt",
"overspentZFP": "Zu viele ZfP ausgegeben"
} }
}, },
"ITEM_BROWSER": { "ITEM_BROWSER": {

View File

@ -18,6 +18,11 @@ export const leadingAttribute = {
"Zaubertänzer": "IN" "Zaubertänzer": "IN"
} }
/*
die ohne ZfP Kosten mussen vorher ausgewählt werden
*/
/** /**
* *
* @type {[String: {name: string, description: string, modFn: string, castTimeModFn: string, costModFn: string}]} * @type {[String: {name: string, description: string, modFn: string, castTimeModFn: string, costModFn: string}]}

View File

@ -76,6 +76,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
this.cost = this.normalizeCastingCost() ?? 0 this.cost = this.normalizeCastingCost() ?? 0
this.castingTime = this.#normalizeCastingTime(this._spell) this.castingTime = this.#normalizeCastingTime(this._spell)
this.zfp = null this.zfp = null
this.zfpDetermined = false
if (this._selectedRepresentation) { if (this._selectedRepresentation) {
this._costModel = this._spell.system.kosten.find(c => c.repräsentation === context.selectedRepresentation) ?? this._spell.system.kosten.find(c => c.repräsentation === "") this._costModel = this._spell.system.kosten.find(c => c.repräsentation === context.selectedRepresentation) ?? this._spell.system.kosten.find(c => c.repräsentation === "")
this._castTimeModel = this._spell.system.zauberdauer this._castTimeModel = this._spell.system.zauberdauer
@ -133,7 +134,6 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
this._castTimeMutators = castTimeMutators this._castTimeMutators = castTimeMutators
this.mod = 0 this.mod = 0
this._activeVariants = Object.entries(this._variants) this._activeVariants = Object.entries(this._variants)
.filter(([key, truthiness]) => truthiness) .filter(([key, truthiness]) => truthiness)
@ -253,6 +253,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
"3d20", "3d20",
{ {
value: this._spell.system.zfw + this.mod, value: this._spell.system.zfw + this.mod,
werte: this.#getProbenWerte(),
owner: this._actor owner: this._actor
} }
) )
@ -268,6 +269,8 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
}) })
} }
this.zfp = result.tap this.zfp = result.tap
this.zfpDetermined = true
this.render({parts: ["form"]}) this.render({parts: ["form"]})
} }
@ -361,6 +364,28 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
return options return options
} }
#getProbenWerte() {
let dice = []
this._spell.system.probe.map(p => {
if (p === "*") {
return this._spellDie ?? null
} else {
return p
}
}).forEach(p => {
if (p !== null) {
dice.push(
this._actor.system.attribute[p.toLowerCase()].aktuell
)
} else {
dice.push(
"??"
)
}
})
return dice
}
async _prepareContext(options) { async _prepareContext(options) {
const context = await super._prepareContext(options) const context = await super._prepareContext(options)
@ -376,6 +401,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
context.displayModResult = (context.modResult > 0 ? "+" : "") + context.modResult context.displayModResult = (context.modResult > 0 ? "+" : "") + context.modResult
context.castingTime = this.castingTime context.castingTime = this.castingTime
context.ready = true context.ready = true
context.zfpDetermined = this.zfpDetermined
// variable probe (should consider Achaz as they can replace one KL in a KL/KL/* spell with IN // variable probe (should consider Achaz as they can replace one KL in a KL/KL/* spell with IN
@ -499,9 +525,34 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
context.ready = false context.ready = false
context.diceRoll = true context.diceRoll = true
} else { } else {
context.zfp = this.zfp if (this.zfp === 0) {
this.zfp = 1
}
let zfpMod = 0
Object.entries(this._spoMods).forEach(([modName, times]) => {
const actualMod = spoModData[modName]
for (let i = 0; i < times; i++) {
const zmfn = new Function("mod", "return " + actualMod.modFn)
zfpMod = zmfn(zfpMod)
}
})
if (this.zfp + zfpMod > this._spell.system.zfw) { // cant be higher than the learnt level
context.zfpModified = this._spell.system.zfw
} else {
context.zfpModified = this.zfp + zfpMod
}
context.spellName = this._spell.system.name context.spellName = this._spell.system.name
context.variant = context.variants.filter(v => v.variantChecked).map(v => v.variantText).join("<br/><br/>") context.variant = context.variants.filter(v => v.variantChecked).map(v => `<em>${v.variantName}</em>&mdash;${v.variantText}`).join("<br/><br/>")
if (context.zfpModified < 0) {
context.ready = false
}
} }
if (!context.ready) { // rules have changed, it cant be cast when zfp - selected mutators is below 0 if (!context.ready) { // rules have changed, it cant be cast when zfp - selected mutators is below 0
@ -511,7 +562,9 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
if (this.zfp == null) { if (this.zfp == null) {
context.notReadyReasons += `<li>${game.i18n.format("SPELL_DIALOG.notReadyReason.noZFPDataAvailable")}</li>` context.notReadyReasons += `<li>${game.i18n.format("SPELL_DIALOG.notReadyReason.noZFPDataAvailable")}</li>`
} }
if (context.zfpModified < 0) {
context.notReadyReasons += `<li>${game.i18n.format("SPELL_DIALOG.notReadyReason.overspentZFP")}</li>`
}
if (context.spoModCount > context.maxSpoModCount) { if (context.spoModCount > context.maxSpoModCount) {
context.notReadyReasons += `<li>${game.i18n.format("SPELL_DIALOG.notReadyReason.tooManySpoMods")}</li>` context.notReadyReasons += `<li>${game.i18n.format("SPELL_DIALOG.notReadyReason.tooManySpoMods")}</li>`
} }

View File

@ -26,14 +26,25 @@ const evaluateRoll = async (rolledDice, {
let failCounter = 0; let failCounter = 0;
let evaluated = null let evaluated = null
if (typeof rolledDice == "string") { // we need to roll it ourself if (typeof rolledDice == "string") { // we need to roll it ourself
let roll1 = new Roll(rolledDice, owner.getRollData()); let roll1 = new Roll(rolledDice, owner.getRollData());
evaluated = await roll1.evaluate() evaluated = await roll1.evaluate()
rolledDice = evaluated.terms[0].results rolledDice = evaluated.terms[0].results
} else {
evaluated = rolledDice
} }
if (tap < 0) { // increases rolledDice by |tap| (as this defacto lowers the target value)
rolledDice = rolledDice.map(({result, active}) => {
return {
result: result - tap,
active
}
})
tap = 0 // and then reset tap to 0 as we applied the reduction
}
rolledDice.forEach((rolledDie, index) => { rolledDice.forEach((rolledDie, index) => {
if (tap < 0 && rolledDie.result > werte[index]) { if (tap < 0 && rolledDie.result > werte[index]) {
tap -= rolledDie.result - werte[index]; tap -= rolledDie.result - werte[index];

View File

@ -1,6 +1,6 @@
<section> <section>
{{#unless zfp}} {{#unless zfpDetermined}}
<div class="attributes {{#if this.colorfulDice}}colorfulDice{{/if}}"> <div class="attributes {{#if this.colorfulDice}}colorfulDice{{/if}}">
@ -74,7 +74,11 @@
{{{this.text}}} {{{this.text}}}
{{#if variant}} {{#if variant}}
<hr/> <hr/>
{{{variantText}}} {{{variant}}}
{{/if}}
{{#if checkModTest}}
<hr/>
<em>{{checkModTest}}</em>&mdash;{{checkModValue}}
{{/if}} {{/if}}
</fieldset> </fieldset>
@ -120,6 +124,9 @@
<fieldset> <fieldset>
<legend>Dauer und Kosten</legend> <legend>Dauer und Kosten</legend>
<div class="malus-and-mod"> <div class="malus-and-mod">
<label><span>ZfP*</span>
<output name="zfp">{{zfpModified}}</output>
</label>
<label><span>Zauberdauer (A)</span> <label><span>Zauberdauer (A)</span>
<output name="castingTime">{{castingTime}}</output> <output name="castingTime">{{castingTime}}</output>
</label> </label>
@ -132,8 +139,8 @@
<button class="actions" {{#if ready}}data-action="cast" {{else}} <button class="actions" {{#if ready}}data-action="cast" {{else}}
data-tooltip="{{{notReadyReasons}}}" disabled="disabled" {{/if}}><i class="fa-solid fa-sparkles"></i> Zauber data-tooltip="{{{notReadyReasons}}}" disabled="disabled" {{/if}}><i class="fa-solid fa-sparkles"></i> Zauber
wirken {{#if modResult}} wirken
[{{displayModResult}}]{{/if}}</button> </button>
{{/unless}} {{/unless}}