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 & {_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 & {_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, } } }