import { RMFRPUtility } from "./rmfrp-utility.js"; import { RMFRP_ATTACK_TABLES } from "./rmfrp-attack-tables.js"; export class RMFRPProcessTable { constructor() { // Load a reference to the rmfrp-tables.json file this.rmfrpTables = RMFRP_ATTACK_TABLES // Loop thru the tables and create a definition object, with key, name and min/ax value of each table this.rmfrpTablesDef = {} for (let table in this.rmfrpTables) { let tableData = this.rmfrpTables[table] // Search min and max values in the tableData let min = Number.MAX_SAFE_INTEGER; let minKey = ""; let max = Number.MIN_SAFE_INTEGER; let maxKey = ""; for (let element of tableData) { if (Number(element.result)) { let value = Number(element.result) if (value > max) { max = value maxKey = element.result } if (value < min) { min = value minKey = element.result } } else if (element.result && element.result.includes("-")) { let range = element.result.split("-"); if (Number(range[0]) > max) { max = Number(range[0]) maxKey = element.result } if (Number(range[1]) < min) { min = Number(range[1]) minKey = element.result } } else { console.error(`Element is not a number or a range`, element) } } this.rmfrpTablesDef[table] = { key: table, name: RMFRPUtility.capitalizeFirstLetters(table.replace(/_/g, " ")), min: min, minKey: minKey, max: max, maxKey: maxKey }; } // Sort rmfrpTablesDef by name this.rmfrpTablesDef = Object.values(this.rmfrpTablesDef).sort((a, b) => a.name.localeCompare(b.name)) } getTableDef() { return this.rmfrpTablesDef; } // Get roll result from table getAttackRollResult(tableKey, roll, armorValue) { roll = Number(roll); if (isNaN(roll)) { console.error(`Roll ${roll} is not a number`) return undefined; } let table = this.rmfrpTables[tableKey] let tableDef = this.rmfrpTablesDef.find(t => t.key == tableKey) if (!table || !tableDef) { console.error(`Table ${tableKey} not found`) return undefined; } // Check min and max values if (roll < tableDef.min) { // return the min value let elem = table.find((element) => element.result == tableDef.minKey); if (elem) { return elem[String(armorValue)]; } else { console.error(`Element ${tableDef.minKey} not found in table ${tableKey}`) } } if (roll > tableDef.max) { // return the max value let elem = table.find((element) => element.result == tableDef.maxKey); if (elem) { return elem[String(armorValue)]; } else { console.error(`Element ${tableDef.maxKey} not found in table ${tableKey}`) } } return table.find((element) => { if (Number(element.result) ) { if ( Number(element.result) == Number(roll) ) { return element[String(armorValue)]; } } else if (element.result && element.result.includes("-")) { // Split the result into a range let range = element.result.split("-"); if (Number(roll) >= Number(range[0]) && Number(roll) <= Number(range[1])) { return element[String(armorValue)]; } } }); } buildFumbleNonWeaponChoices() { let nonWeapon = CONFIG.rmfrp.fumbles.fumble_non_weapon[0] let fumblesChoice = [] for (let key in nonWeapon) { if (key === "score") { continue; } fumblesChoice.push({ key: key, name: RMFRPUtility.capitalizeFirstLetters(key) }) } return fumblesChoice } buildFumbleWeaponChoices() { let weapon = CONFIG.rmfrp.fumbles.fumble_weapon[0] let fumblesChoice = [] for (let key in weapon) { if (key === "score") { continue; } fumblesChoice.push({ key: key, name: RMFRPUtility.capitalizeFirstLetters(key) }) } return fumblesChoice } getFumbleDef() { let fumbles = [] for (let key in CONFIG.rmfrp.fumbles) { fumbles.push({ key: key, name: RMFRPUtility.capitalizeFirstLetters(key.replace(/_/g, " ")) }) } return fumbles } getCriticalDef() { let criticals = [] for (let key in CONFIG.rmfrp.criticals) { criticals.push({ key: key, name: RMFRPUtility.capitalizeFirstLetters(key.replace(/_/g, " ")) }) } return criticals } async getFumbleRollResult(fumble_table, fumble_column) { let table = CONFIG.rmfrp.fumbles[fumble_table] if (!table) { ui.notifications.error("Fumble table not found: " + fumble_table); console.error(`Fumble table ${fumble_table} not found`) return undefined; } let roll = new Roll("1d100") await roll.evaluate() let score = roll.total // Search the result for (let fumbleDef of table) { if (Number(fumbleDef.score) ) { if (Number(fumbleDef.score) == score) { return fumbleDef[fumble_column] } } else { // Score is XX-YY so split it to get the range values let range = fumbleDef.score.split("-") if (Number(range[0]) <= score && score <= Number(range[1])) { return fumbleDef[fumble_column] } } } return null } async getCriticalResult(tableKey, criticalKey) { let table = CONFIG.rmfrp.criticals[tableKey] if (!table) { console.error(`Critical table ${tableKey} not found`) return undefined; } let roll = new Roll("1d100") await roll.evaluate() let score = roll.total console.log("Critical Roll: ", score) // Search the result for (let criticalDef of table.criticals) { if (Number(criticalDef.score) ) { if (Number(criticalDef.score) == score) { return criticalDef.levels[criticalKey.toUpperCase()] } } else { // Score is XX-YY so split it to get the range values let range = criticalDef.score.split("-") if (Number(range[0]) <= score && score <= Number(range[1])) { return criticalDef.levels[criticalKey.toUpperCase()] } } } return null } }