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:",
"noRepresentation": "Keine Repräsentation gewä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": {

View File

@ -18,6 +18,11 @@ export const leadingAttribute = {
"Zaubertänzer": "IN"
}
/*
die ohne ZfP Kosten mussen vorher ausgewählt werden
*/
/**
*
* @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.castingTime = this.#normalizeCastingTime(this._spell)
this.zfp = null
this.zfpDetermined = false
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._castTimeModel = this._spell.system.zauberdauer
@ -133,7 +134,6 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
this._castTimeMutators = castTimeMutators
this.mod = 0
this._activeVariants = Object.entries(this._variants)
.filter(([key, truthiness]) => truthiness)
@ -253,6 +253,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
"3d20",
{
value: this._spell.system.zfw + this.mod,
werte: this.#getProbenWerte(),
owner: this._actor
}
)
@ -268,6 +269,8 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
})
}
this.zfp = result.tap
this.zfpDetermined = true
this.render({parts: ["form"]})
}
@ -361,6 +364,28 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
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) {
const context = await super._prepareContext(options)
@ -376,6 +401,7 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
context.displayModResult = (context.modResult > 0 ? "+" : "") + context.modResult
context.castingTime = this.castingTime
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
@ -499,9 +525,34 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
context.ready = false
context.diceRoll = true
} 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.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
@ -511,7 +562,9 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
if (this.zfp == null) {
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) {
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 evaluated = null
if (typeof rolledDice == "string") { // we need to roll it ourself
let roll1 = new Roll(rolledDice, owner.getRollData());
evaluated = await roll1.evaluate()
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) => {
if (tap < 0 && rolledDie.result > werte[index]) {
tap -= rolledDie.result - werte[index];

View File

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