foundry-dsa41-game/src/module/data/talent.mjs

103 lines
3.1 KiB
JavaScript

export class Talent {
/**
* @typedef TalentEigenschaften
* @property Number mu
* @property Number kl
* @property Number in
* @property Number ch
* @property Number ff
* @property Number ge
* @property Number ko
* @property Number kk
*/
/**
* @typedef TalentData
* @property {String} name
* @property {Number} taw
* @property {Number} mod
* @property {TalentEigenschaften} eigenschaften
* @property {"mu","kl","in","ch","ff","ge","ko","kk"} eigenschaft1
* @property {"mu","kl","in","ch","ff","ge","ko","kk"} eigenschaft2
* @property {"mu","kl","in","ch","ff","ge","ko","kk"} eigenschaft3
*/
/**
*
* @param {TalentData} data
**/
constructor(data) {
this.data = data
}
/**
* @param {"publicroll", "gmroll", "privateroll"} rollMode
* @returns {Promise<{tap: any, meisterlich: boolean, patzer: boolean, evaluatedRoll: Roll<EmptyObject> & {_evaluated: true, _total: number, readonly total: number}}>}
*/
evaluate(rollMode) {
return this.#talentRoll(this.data, rollMode)
}
/**
*
* @param {TalentData} data
* @param {"publicroll", "gmroll", "privateroll"} rollMode
* @returns {Promise<{tap: any, meisterlich: boolean, patzer: boolean, evaluatedRoll: Roll<EmptyObject> & {_evaluated: true, _total: number, readonly total: number}}>}
*/
async #talentRoll(data, rollMode) {
let roll1 = new Roll("3d20");
let evaluated1 = (await roll1.evaluate())
const dsaDieRollEvaluated = this._evaluateRoll(evaluated1.terms[0].results, {
taw: data.taw,
mod: data.mod,
werte: [data.eigenschaften[data.eigenschaft1], data.eigenschaften[data.eigenschaft2], data.eigenschaften[data.eigenschaft3]],
})
return {
...dsaDieRollEvaluated,
evaluatedRoll: evaluated1,
}
}
_evaluateRoll(rolledDice, {
taw,
mod,
lowerThreshold = 1,
upperThreshold = 20,
countToMeisterlich = 3,
countToPatzer = 3,
werte = []
}) {
let meisterlichCounter = 0;
let patzerCounter = 0;
let failCounter = 0;
rolledDice.forEach((rolledDie, index) => {
if (mod < 0 && rolledDie.result > werte[index]) {
mod -= rolledDie.result - werte[index];
if (mod < 0) { // konnte nicht vollständig ausgeglichen werden
failCounter++;
}
} else if (rolledDie.result > werte[index]) { // taw ist bereits aufgebraucht und wert kann nicht ausgeglichen werden
mod -= rolledDie.result - werte[index];
failCounter++;
}
if (rolledDie.result <= lowerThreshold) meisterlichCounter++;
if (rolledDie.result > upperThreshold) patzerCounter++;
})
return {
tap: Math.min(taw, mod),
meisterlich: meisterlichCounter === countToMeisterlich,
patzer: patzerCounter === countToPatzer,
}
}
}