implements partial (display) support for SpoMods
parent
5f85631679
commit
959f47f348
|
|
@ -22,8 +22,8 @@ export class SpellDataModel extends BaseItem {
|
|||
hauszauber: new BooleanField(),
|
||||
technik: new StringField(),
|
||||
zauberdauer: new SchemaField({
|
||||
min: new NumberField(),
|
||||
normal: new NumberField(),
|
||||
min: new StringField(),
|
||||
normal: new StringField(),
|
||||
additionalFormula: new StringField(),
|
||||
variables: new ArrayField(new StringField()),
|
||||
additionalFormulaTimeUnit: new StringField(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
const data = {
|
||||
|
||||
"Veränderte Technik": {
|
||||
name: "Veränderte Technik",
|
||||
description: "Verändert die Technik",
|
||||
mod: -7,
|
||||
castTimeMod: 3,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
"Veränderte Technik, zentral": {
|
||||
name: "Veränderte Technik, zentral",
|
||||
description: "Verändert die Technik",
|
||||
mod: -12,
|
||||
castTimeMod: 3,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
"Halbierte Zauberdauer": {
|
||||
name: "Halbierte Zauberdauer",
|
||||
description: "Halbiert die Zauberdauer für eine Erschwernis von 5",
|
||||
mod: -5,
|
||||
castTimeMod: 0.5,
|
||||
castTimeMode: "Multiply"
|
||||
},
|
||||
"Verdoppelte Zauberdauer": {
|
||||
name: "Verdoppelte Zauberdauer",
|
||||
description: "Verdoppelt die Zauberdauer für eine Erleichterung von 3",
|
||||
mod: 3,
|
||||
castTimeMod: 2,
|
||||
castTimeMode: "Multiply"
|
||||
},
|
||||
"Erzwingen": {
|
||||
name: "Erzwingen",
|
||||
description: "Verringert Erschwernis um 1 je doppelten AsP Punkt",
|
||||
mod: -1,
|
||||
castTimeMod: 1,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
"Kosten einsparen": {
|
||||
name: "Kosten einsparen",
|
||||
description: "Reduziert die Kosten des Zaubers um 10% für jede zusätzlich aufgewendete Aktion",
|
||||
mod: 3,
|
||||
castingCosts: 0.1,
|
||||
castingCostsMode: "Multiply",
|
||||
castTimeMod: 1,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
// more to come
|
||||
"Vergrößerung von Reichweite oder Wirkungsradius": {
|
||||
name: "Vergrößerung von Reichweite oder Wirkungsradius",
|
||||
description: "Vergrößert die Reichweite oder wenn möglich den Wirkungsradius auf kosten von Aktionen",
|
||||
mod: 5,
|
||||
castTimeMod: 1,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
"Verkleinerung von Reichweite oder Wirkungsradius": {
|
||||
name: "Verkleinerung von Reichweite oder Wirkungsradius",
|
||||
description: "Verkleinert die Reichweite oder wenn möglich den Wirkungsradius auf kosten von Aktionen",
|
||||
mod: 3,
|
||||
castTimeMod: 1,
|
||||
castTimeMode: "Addition"
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default data
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import {Talent} from "../data/talent.mjs";
|
||||
import {ATTRIBUTE} from "../data/attribute.mjs";
|
||||
import SpoModData from "../data/spomods/spoModData.mjs";
|
||||
|
||||
const {
|
||||
ApplicationV2,
|
||||
|
|
@ -44,23 +45,32 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
* @private
|
||||
*/
|
||||
_actor = null
|
||||
_mutators = {}
|
||||
_costMutators = {}
|
||||
_castTimeMutators = {}
|
||||
_variants = {}
|
||||
_costModel = {}
|
||||
_castTimeModel = {}
|
||||
displayModResult = 0
|
||||
|
||||
constructor(actor, spellId) {
|
||||
super()
|
||||
this._actor = actor
|
||||
this._spell = this._actor.itemTypes["Spell"].find(p => p._id === spellId)
|
||||
this.displayModResult = Number(this._spell.system.zfw)
|
||||
this._circumstance = 0
|
||||
this._mods = []
|
||||
this._mutators = {}
|
||||
this.mod = 0
|
||||
this._costMutators = {}
|
||||
this._castTimeMutators = {}
|
||||
this._selectedRepresentation = null
|
||||
this._spellDie = null
|
||||
this._variants = {}
|
||||
this._costModel = {}
|
||||
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._castTimeMutators = {}
|
||||
this._costMutators = {}
|
||||
this._costModel.variables.forEach(v => this._costMutators[v] = 0)
|
||||
this._castTimeModel.variables.forEach(v => this._castTimeMutators[v] = 0)
|
||||
this.cost = this.normalizeCastingCost() ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,24 +110,34 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
}
|
||||
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._mutators = {}
|
||||
this._costModel.variables.forEach(v => this._mutators[v] = 0)
|
||||
this._castTimeModel = this._spell.system.zauberdauer
|
||||
this._castTimeMutators = {}
|
||||
this._costMutators = {}
|
||||
this._costModel.variables.forEach(v => this._costMutators[v] = 0)
|
||||
this._castTimeModel.variables.forEach(v => this._castTimeMutators[v] = 0)
|
||||
}
|
||||
let mutators = foundry.utils.expandObject(formData.object)["mutators"]
|
||||
let costMutators = foundry.utils.expandObject(formData.object)["costMutators"]
|
||||
|
||||
if (mutators) {
|
||||
this._mutators = mutators
|
||||
if (costMutators) {
|
||||
this._costMutators = costMutators
|
||||
}
|
||||
|
||||
this.displayModResult = Number(this._spell.system.zfw)
|
||||
this.cost = this.normalizeCastingCost()
|
||||
|
||||
let castTimeMutators = foundry.utils.expandObject(formData.object)["castTimeMutators"]
|
||||
|
||||
if (castTimeMutators) {
|
||||
this._castTimeMutators = castTimeMutators
|
||||
}
|
||||
|
||||
this.mod = 0
|
||||
this._activeVariants = Object.entries(this._variants)
|
||||
.filter(([key, truthiness]) => truthiness)
|
||||
.map(([key, truthiness]) => this._spell.system.varianten.find(v => v.name === key))
|
||||
this._activeVariants.forEach(variant => {
|
||||
|
||||
if (variant.mod) {
|
||||
this.displayModResult += Number(variant.mod)
|
||||
this.mod += Number(variant.mod)
|
||||
}
|
||||
|
||||
})
|
||||
|
|
@ -129,6 +149,23 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
|
||||
}
|
||||
|
||||
normalizeCastingCost() {
|
||||
|
||||
let costFormula = this._costModel.additionalFormula
|
||||
|
||||
this._costModel.variables.forEach(v => {
|
||||
|
||||
costFormula = costFormula.replace(v, this._costMutators[v])
|
||||
|
||||
})
|
||||
|
||||
costFormula = Number(eval(costFormula)) + Number(this._costModel.cost)
|
||||
if (costFormula <= this._costModel.min) {
|
||||
costFormula = this._costModel.min
|
||||
}
|
||||
return costFormula
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param spell
|
||||
|
|
@ -141,20 +178,50 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
// normal: Standard Zauberzeit eines Zaubers
|
||||
// additionalFormulaData: enthält die zur Normalzeit zusätzlichen Zauberdauer
|
||||
|
||||
const castingTime = spell.system.zauberdauer
|
||||
|
||||
// direct actions
|
||||
const aktionenRegExp = /(.*) Aktionen/
|
||||
const srRegExp = /(.*) SR/
|
||||
|
||||
if (castingTime.match(aktionenRegExp)) {
|
||||
const [_, actions] = castingTime.match(aktionenRegExp)
|
||||
return actions
|
||||
} else if (castingTime.match(srRegExp)) {
|
||||
const [_, actions] = castingTime.match(srRegExp)
|
||||
return actions * 20
|
||||
const castingTime = spell.system.zauberdauer.normal ?? 0
|
||||
let baseCastTime = 0
|
||||
const minCastingTime = spell.system.zauberdauer.min ?? 0
|
||||
let baseMinCastTime = 0
|
||||
if (castingTime) {
|
||||
baseCastTime = castingTime.replace(/(.*) Aktionen/g, (_, aktionen) => {
|
||||
return aktionen
|
||||
})
|
||||
baseCastTime = baseCastTime.replace(/(.*) SR/g, (_, aktionen) => {
|
||||
return aktionen * 20
|
||||
})
|
||||
}
|
||||
return -1
|
||||
if (minCastingTime) {
|
||||
baseMinCastTime = minCastingTime.replace(/(.*) Aktionen/g, (_, aktionen) => {
|
||||
return aktionen
|
||||
})
|
||||
baseMinCastTime = baseMinCastTime.replace(/(.*) SR/g, (_, aktionen) => {
|
||||
return aktionen * 20
|
||||
})
|
||||
}
|
||||
|
||||
let actualCastingTime = 0
|
||||
let formula = spell.system.zauberdauer.additionalFormula
|
||||
if (formula) {
|
||||
Object.entries(this._castTimeMutators).forEach(([variableName, variableValue]) => {
|
||||
console.log(variableName, variableValue)
|
||||
formula = formula.replaceAll(variableName, variableValue)
|
||||
})
|
||||
|
||||
if (spell.system.zauberdauer.additionalFormulaTimeUnit == "Aktionen") {
|
||||
actualCastingTime = (Number(baseCastTime) + Number(eval(formula)) ?? 0)
|
||||
} else {
|
||||
actualCastingTime = (Number(baseCastTime) + (Number(eval(formula)) * 20) ?? 0)
|
||||
}
|
||||
|
||||
} else {
|
||||
actualCastingTime = baseCastTime
|
||||
}
|
||||
|
||||
if (Number(actualCastingTime) <= Number(baseMinCastTime)) {
|
||||
actualCastingTime = baseMinCastTime
|
||||
}
|
||||
|
||||
return actualCastingTime
|
||||
}
|
||||
|
||||
_configureRenderOptions(options) {
|
||||
|
|
@ -180,8 +247,12 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
context.text = this._spell.system.wirkung
|
||||
context.dice = []
|
||||
context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice')
|
||||
context.modResult = this.displayModResult
|
||||
context.displayModResult = (context.modResult > 0 ? "+" : "") + this.displayModResult
|
||||
context.modResult = this._spell.system.zfw - this.mod
|
||||
context.penalty = (this.mod > 0 ? "+" : "") + this.mod
|
||||
context.displayModResult = (context.modResult > 0 ? "+" : "") + context.modResult
|
||||
context.castingTime = this.#normalizeCastingTime(this._spell)
|
||||
|
||||
// variable probe (should consider Achaz as they can replace one KL in a KL/KL/* spell with IN
|
||||
|
||||
this._spell.system.probe.map(p => {
|
||||
if (p === "*") {
|
||||
|
|
@ -214,28 +285,48 @@ export class SpellDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
}
|
||||
})
|
||||
|
||||
// Repräsentation
|
||||
|
||||
context.representationOptions[""] = ""
|
||||
Object.entries(this._spell.system.repräsentation).forEach(([key, value]) => {
|
||||
context.representationOptions[key] = key
|
||||
})
|
||||
|
||||
// Costs and Mutators
|
||||
|
||||
context.castingCosts = this.cost
|
||||
|
||||
|
||||
// set probe to current held probe variables or take from _spell
|
||||
context.mutators = this._mutators
|
||||
context.costMutators = this._costMutators
|
||||
|
||||
|
||||
if (this._costModel) {
|
||||
context.variables = this._costModel.variables
|
||||
context.costVariables = this._costModel.variables
|
||||
} else {
|
||||
context.variables = []
|
||||
context.costVariables = []
|
||||
}
|
||||
|
||||
// SpoMods
|
||||
context.spoMods = []
|
||||
if (this._spell.system.modifikationen) {
|
||||
this._spell.system.modifikationen.split(",").forEach(spoMod => {
|
||||
|
||||
// generate a list of variables in cost and castTime
|
||||
|
||||
// generate a list of variants
|
||||
|
||||
// generate a list of SpoMods
|
||||
switch (spoMod.trim()) {
|
||||
case "Zauberdauer":
|
||||
context.spoMods.push(SpoModData["Halbierte Zauberdauer"])
|
||||
context.spoMods.push(SpoModData["Verdoppelte Zauberdauer"])
|
||||
break;
|
||||
case "Kosten":
|
||||
context.spoMods.push(SpoModData["Kosten einsparen"])
|
||||
break;
|
||||
case "Reichweite":
|
||||
context.spoMods.push(SpoModData["Verkleinerung von Reichweite oder Wirkungsradius"])
|
||||
context.spoMods.push(SpoModData["Vergrößerung von Reichweite oder Wirkungsradius"])
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,17 +50,39 @@
|
|||
</fieldset>
|
||||
{{/if}}
|
||||
|
||||
<fieldset>
|
||||
<legend>Modifikationen</legend>
|
||||
|
||||
{{#if this.spoMods}}
|
||||
<fieldset class="scroll-y">
|
||||
<legend>Spontane Modifikation</legend>
|
||||
<div class="variantList">
|
||||
{{#each this.spoMods}}
|
||||
<div class="variant" data-tooltip="{{{description}}}">
|
||||
<div class="selection">
|
||||
<label>
|
||||
<input type="checkbox" name="spoMods.{{name}}" {{checked variantChecked}}>
|
||||
{{#if (gte mod 0)}}+{{/if}}{{mod}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="variantText">
|
||||
<em>{{name}}</em>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/if}}
|
||||
|
||||
<fieldset>
|
||||
<legend>Variablen</legend>
|
||||
{{#each variables}}
|
||||
{{#each castTimeVariables}}
|
||||
<div>
|
||||
<label for="{{this}}">{{this}}: </label>
|
||||
<input type="number" name="mutators.{{this}}" value="{{lookup ../mutators this}}"/>
|
||||
<input type="number" name="castTimeMutators.{{this}}" value="{{lookup ../castTimeMutators this}}"/>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each costVariables}}
|
||||
<div>
|
||||
<label for="{{this}}">{{this}}: </label>
|
||||
<input type="number" name="costMutators.{{this}}" value="{{lookup ../costMutators this}}"/>
|
||||
</div>
|
||||
{{/each}}
|
||||
</fieldset>
|
||||
|
|
@ -69,10 +91,10 @@
|
|||
<fieldset>
|
||||
<legend>Dauer und Kosten</legend>
|
||||
<div class="malus-and-mod">
|
||||
<label><span>Zauberdauer</span>
|
||||
<label><span>Zauberdauer (A)</span>
|
||||
<output name="castingTime">{{castingTime}}</output>
|
||||
</label>
|
||||
<label><span>Kosten</span>
|
||||
<label><span>Kosten (AsP)</span>
|
||||
<output name="costs">{{castingCosts}}</output>
|
||||
</label>
|
||||
<label><span>Erschwernis</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue