foundry-vtt-system-midgard5/source/module/rolls/M5Roll.ts

161 lines
4.4 KiB
TypeScript

import { Evaluated } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/dice/roll";
import { M5Character } from "../actors/M5Character";
import { M5EwResult, M5RollData, M5RollResult } from "../M5Base";
export class M5Roll { // extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs"
public _evaluated: boolean = false
public _total: number = 0
public pool: PoolTerm = null
constructor(public data: M5RollData, public actor: any, public label: string) {
//super(null)
//this.data = rollData
}
// @ts-ignore
//override evaluate(options?: InexactPartial<RollTerm.EvaluationOptions>): Evaluated<Roll<M5RollData>> | Promise<Evaluated<Roll<M5RollData>>> {
evaluate() {
const rollNames = Object.keys(this.data.rolls)
const rolls = rollNames.map(rollName => {
const formula = this.data.rolls[rollName]
const roll = new Roll(formula.formula, this.data)
return roll
})
this.pool = PoolTerm.fromRolls(rolls)
return this.pool.evaluate({ async: true }).then(results => {
this._total = 0
results.rolls.forEach((roll, index) => {
const rollResult = this.data.rolls[index.toString()] as M5RollResult
rollResult.result = roll.result
rollResult.total = roll.total
rollResult.totalStr = roll.total.toString()
this._total += roll.total
let rowRes = M5EwResult.TBD
roll.dice.forEach((d, dIndex) => {
rollResult.dice[dIndex.toString()] = d.total
if (rowRes === M5EwResult.TBD && dIndex === 0) {
if (rollResult.type === "ew") {
if (d.total === 1)
rowRes = M5EwResult.FUMBLE
else if (d.total === 20)
rowRes = M5EwResult.CRITICAL
else if (d.total >= 16)
rowRes = M5EwResult.HIGH
} else if (rollResult.type === "pw") {
if (d.total === 1)
rowRes = M5EwResult.FUMBLE
else if (d.total === 20)
rowRes = M5EwResult.CRITICAL
}
}
})
if (rollResult.type === "ew") {
if (roll.total < 20) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH)
rowRes = M5EwResult.FAIL
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
}
} else if (rollResult.type === "pw") {
if (roll.total < 0) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.FAIL
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
}
}
rollResult.css = rowRes
})
this.data.res.label = this.label
this._evaluated = true
return this
})
}
async render(): Promise<string> {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data)
}
async toMessage() {
if (!this._evaluated)
await this.evaluate()
const rMode = (game as Game).settings.get("core", "rollMode")
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
speaker: ChatMessage.getSpeaker({actor: this.actor}),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([this.pool])
}
ChatMessage.applyRollMode(chatData, rMode)
return ChatMessage.create(chatData)
}
static fromAttribute(actor: any, attributeKey: string) {
const character = actor as M5Character
const attribute = character.attribute(attributeKey)
const rollData = actor.getRollData() as M5RollData
rollData.i = attribute.value + attribute.bonus
rollData.rolls["0"] = {
formula: "@i - 1d100",
type: "pw",
label: (game as Game).i18n.localize("midgard5.pw"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`))
}
static brawl(actor: any) {
const rollData = actor.getRollData() as M5RollData
rollData.i = {
attackBonus: 0,
damageBonus: 0
}
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.brawl + @c.calc.stats.attackBonus + @i.attackBonus",
type: "ew",
label: (game as Game).i18n.localize("midgard5.attack"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
rollData.rolls["1"] = {
formula: "1d6 - 4 + @c.calc.stats.damageBonus + @i.damageBonus",
type: "dmg",
label: (game as Game).i18n.localize("midgard5.damage"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"))
}
}