2024-08-23 11:45:23 +02:00
|
|
|
import { RMFRPUtility } from "./rmfrp-utility.js";
|
|
|
|
import { RMFRP_ATTACK_TABLES } from "./rmfrp-attack-tables.js";
|
|
|
|
|
2024-08-15 22:52:36 +02:00
|
|
|
export class RMFRPProcessTable {
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
// Load a reference to the rmfrp-tables.json file
|
2024-08-23 11:45:23 +02:00
|
|
|
this.rmfrpTables = RMFRP_ATTACK_TABLES
|
2024-08-15 22:52:36 +02:00
|
|
|
// Loop thru the tables and create a definition object, with key, name and min/ax value of each table
|
|
|
|
this.rmfrpTablesDef = {}
|
2024-08-23 11:45:23 +02:00
|
|
|
|
2024-08-15 22:52:36 +02:00
|
|
|
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;
|
2024-08-23 11:45:23 +02:00
|
|
|
let minKey = "";
|
2024-08-15 22:52:36 +02:00
|
|
|
let max = Number.MIN_SAFE_INTEGER;
|
2024-08-23 11:45:23 +02:00
|
|
|
let maxKey = "";
|
2025-01-18 18:14:52 +01:00
|
|
|
for (let element of tableData) {
|
2024-08-23 11:45:23 +02:00
|
|
|
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
|
2024-08-15 22:52:36 +02:00
|
|
|
}
|
2025-01-18 18:14:52 +01:00
|
|
|
} 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)
|
2024-08-15 22:52:36 +02:00
|
|
|
}
|
2024-08-23 11:45:23 +02:00
|
|
|
}
|
2025-01-18 18:14:52 +01:00
|
|
|
|
2024-08-15 22:52:36 +02:00
|
|
|
this.rmfrpTablesDef[table] = {
|
|
|
|
key: table,
|
|
|
|
name: RMFRPUtility.capitalizeFirstLetters(table.replace(/_/g, " ")),
|
|
|
|
min: min,
|
2024-08-23 11:45:23 +02:00
|
|
|
minKey: minKey,
|
|
|
|
max: max,
|
|
|
|
maxKey: maxKey
|
2024-08-15 22:52:36 +02:00
|
|
|
};
|
|
|
|
}
|
2024-08-23 11:45:23 +02:00
|
|
|
// Sort rmfrpTablesDef by name
|
|
|
|
this.rmfrpTablesDef = Object.values(this.rmfrpTablesDef).sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
}
|
|
|
|
|
|
|
|
getTableDef() {
|
|
|
|
return this.rmfrpTablesDef;
|
2024-08-15 22:52:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get roll result from table
|
2024-08-23 11:45:23 +02:00
|
|
|
getAttackRollResult(tableKey, roll, armorValue) {
|
|
|
|
roll = Number(roll);
|
|
|
|
if (isNaN(roll)) {
|
2025-01-18 18:14:52 +01:00
|
|
|
console.error(`Roll ${roll} is not a number`)
|
2024-08-23 11:45:23 +02:00
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
let table = this.rmfrpTables[tableKey]
|
2025-01-18 18:14:52 +01:00
|
|
|
let tableDef = this.rmfrpTablesDef.find(t => t.key == tableKey)
|
2024-08-23 11:45:23 +02:00
|
|
|
if (!table || !tableDef) {
|
2025-01-18 18:14:52 +01:00
|
|
|
console.error(`Table ${tableKey} not found`)
|
2024-08-23 11:45:23 +02:00
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check min and max values
|
|
|
|
if (roll < tableDef.min) {
|
|
|
|
// return the min value
|
2025-01-18 18:14:52 +01:00
|
|
|
let elem = table.find((element) => element.result == tableDef.minKey);
|
|
|
|
if (elem) {
|
2024-08-23 11:45:23 +02:00
|
|
|
return elem[String(armorValue)];
|
2025-01-18 18:14:52 +01:00
|
|
|
} else {
|
|
|
|
console.error(`Element ${tableDef.minKey} not found in table ${tableKey}`)
|
|
|
|
}
|
2024-08-23 11:45:23 +02:00
|
|
|
}
|
|
|
|
if (roll > tableDef.max) {
|
2025-01-18 18:14:52 +01:00
|
|
|
// return the max value
|
|
|
|
let elem = table.find((element) => element.result == tableDef.maxKey);
|
|
|
|
if (elem) {
|
2024-08-23 11:45:23 +02:00
|
|
|
return elem[String(armorValue)];
|
2025-01-18 18:14:52 +01:00
|
|
|
} else {
|
|
|
|
console.error(`Element ${tableDef.maxKey} not found in table ${tableKey}`)
|
|
|
|
}
|
2024-08-23 11:45:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return table.find((element) => {
|
2025-01-18 18:14:52 +01:00
|
|
|
if (Number(element.result) ) {
|
|
|
|
if ( Number(element.result) == Number(roll) ) {
|
|
|
|
return element[String(armorValue)];
|
|
|
|
}
|
|
|
|
} else if (element.result && element.result.includes("-")) {
|
2024-08-23 11:45:23 +02:00
|
|
|
// Split the result into a range
|
2024-08-15 22:52:36 +02:00
|
|
|
let range = element.result.split("-");
|
|
|
|
if (Number(roll) >= Number(range[0]) && Number(roll) <= Number(range[1])) {
|
|
|
|
return element[String(armorValue)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2025-01-04 20:42:37 +01:00
|
|
|
|
2025-01-18 18:14:52 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2025-01-04 20:42:37 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2025-01-18 18:14:52 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-08-15 22:52:36 +02:00
|
|
|
}
|