From 005f7ec1b40e5eeb637e562a9a5d8738ce89c990 Mon Sep 17 00:00:00 2001 From: Jeremy Valentine <38669521+valentine195@users.noreply.github.com> Date: Thu, 11 Jan 2024 09:55:54 -0500 Subject: [PATCH] fix: fixes party level calculation for pf2e system --- src/utils/rpg-system/pf2e.ts | 208 +++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 96 deletions(-) diff --git a/src/utils/rpg-system/pf2e.ts b/src/utils/rpg-system/pf2e.ts index 611fd407..be9f9e14 100644 --- a/src/utils/rpg-system/pf2e.ts +++ b/src/utils/rpg-system/pf2e.ts @@ -1,7 +1,7 @@ -import { RpgSystem } from './rpgSystem' -import { crToString, getFromCreatureOrBestiary } from '..' -import type { DifficultyLevel, GenericCreature, DifficultyThreshold } from '.' -import type InitiativeTracker from '../../main' +import { RpgSystem } from "./rpgSystem"; +import { crToString, getFromCreatureOrBestiary } from ".."; +import type { DifficultyLevel, GenericCreature, DifficultyThreshold } from "."; +import type InitiativeTracker from "../../main"; // level without proficiency variant // const xpVariantCreatureDifferences = new Map([ @@ -23,113 +23,129 @@ import type InitiativeTracker from '../../main' // ]); const XP_CREATURE_DIFFERENCES: Record = { - '-4': 10, - '-3': 15, - '-2': 20, - '-1': 30, - '0': 40, - '1': 60, - '2': 80, - '3': 120, - '4': 160, -} + "-4": 10, + "-3": 15, + "-2": 20, + "-1": 30, + "0": 40, + "1": 60, + "2": 80, + "3": 120, + "4": 160 +}; const XP_SIMPLE_HAZARD_DIFFERENCES: Record = { - '-4': 2, - '-3': 3, - '-2': 4, - '-1': 6, - '0': 8, - '1': 12, - '2': 16, - '3': 24, - '4': 32, -} + "-4": 2, + "-3": 3, + "-2": 4, + "-1": 6, + "0": 8, + "1": 12, + "2": 16, + "3": 24, + "4": 32 +}; const PF2E_DND5E_DIFFICULTY_MAPPING: Record = { - 'trivial': 'trivial', - 'low': 'easy', - 'moderate': 'medium', - 'severe': 'hard', - 'extreme': 'deadly' -} + trivial: "trivial", + low: "easy", + moderate: "medium", + severe: "hard", + extreme: "deadly" +}; -export class Pathfinder2eRpgSystem extends RpgSystem { - plugin: InitiativeTracker +export class Pathfinder2eRpgSystem extends RpgSystem { + plugin: InitiativeTracker; - override systemDifficulties: [string, string, ...string[]] = [ - "Trivial", - "Low", - "Moderate", - "Severe", - "Extreme" - ] + override systemDifficulties: [string, string, ...string[]] = [ + "Trivial", + "Low", + "Moderate", + "Severe", + "Extreme" + ]; - constructor(plugin: InitiativeTracker) { - super() - this.plugin = plugin - this.displayName = 'Pathfinder 2e' - } + constructor(plugin: InitiativeTracker) { + super(); + this.plugin = plugin; + this.displayName = "Pathfinder 2e"; + } - getCreatureDifficulty( - creature: GenericCreature, - playerLevels?: number[] - ): number { - const lvl = getFromCreatureOrBestiary( - this.plugin, - creature, - (c) => c?.level - )?.toString().split(' ').slice(-1) - if (lvl == null || lvl == undefined) return 0 - const partyLvl = playerLevels?.length ?? 0 > 0 ? playerLevels.reduce((a, b) => a + b) / playerLevels.length : 0 + getCreatureDifficulty( + creature: GenericCreature, + playerLevels?: number[] + ): number { + const lvl = getFromCreatureOrBestiary( + this.plugin, + creature, + (c) => c?.level + ) + ?.toString() + .split(" ") + .slice(-1); + if (lvl == null || lvl == undefined) return 0; + const partyLvl = Math.round( + playerLevels?.length ?? 0 > 0 + ? playerLevels.reduce((a, b) => a + b) / playerLevels.length + : 0 + ); - const creature_differences = String( - lvl - partyLvl - ) + const creature_differences = String(lvl - partyLvl); - return XP_CREATURE_DIFFERENCES[creature_differences] ?? 0 - } + return XP_CREATURE_DIFFERENCES[creature_differences] ?? 0; + } - getDifficultyThresholds(playerLevels: number[]): DifficultyThreshold[] { - const budget = playerLevels.length * 20 - const encounterBudget: Record = { - trivial: Math.floor(budget * 0.5), - low: Math.floor(budget * 0.75), - moderate: budget, - severe: Math.floor(budget * 1.5), - extreme: Math.floor(budget * 2), - } - return Object.entries(encounterBudget).map(([name, value]) => ({ - displayName: name.charAt(0).toUpperCase() + name.slice(1), - minValue: value - })).sort((a, b) => a.minValue - b.minValue) - } + getDifficultyThresholds(playerLevels: number[]): DifficultyThreshold[] { + const budget = playerLevels.length * 20; + const encounterBudget: Record = { + trivial: Math.floor(budget * 0.5), + low: Math.floor(budget * 0.75), + moderate: budget, + severe: Math.floor(budget * 1.5), + extreme: Math.floor(budget * 2) + }; + return Object.entries(encounterBudget) + .map(([name, value]) => ({ + displayName: name.charAt(0).toUpperCase() + name.slice(1), + minValue: value + })) + .sort((a, b) => a.minValue - b.minValue); + } - getEncounterDifficulty( - creatures: Map, - playerLevels: number[] - ): DifficultyLevel { - const creatureXp = [...creatures].reduce( - (acc, [creature, count]) => - acc + this.getCreatureDifficulty(creature, playerLevels) * count, - 0 - ) + getEncounterDifficulty( + creatures: Map, + playerLevels: number[] + ): DifficultyLevel { + const creatureXp = [...creatures].reduce( + (acc, [creature, count]) => + acc + + this.getCreatureDifficulty(creature, playerLevels) * count, + 0 + ); - const thresholds = this.getDifficultyThresholds(playerLevels) - const displayName = thresholds.find(threshold => creatureXp <= threshold.minValue)?.displayName ?? "Trivial" - const thresholdSummary = thresholds.map((threshold) => `${threshold.displayName}: ${threshold.minValue}`).join('\n') - const summary = `Encounter is ${displayName} + const thresholds = this.getDifficultyThresholds(playerLevels); + const displayName = + thresholds.find((threshold) => creatureXp <= threshold.minValue) + ?.displayName ?? "Trivial"; + const thresholdSummary = thresholds + .map( + (threshold) => `${threshold.displayName}: ${threshold.minValue}` + ) + .join("\n"); + const summary = `Encounter is ${displayName} Total XP: ${creatureXp} Threshold ${thresholdSummary}`; - return { - displayName, - summary, - cssClass: PF2E_DND5E_DIFFICULTY_MAPPING[displayName.toLowerCase()] ?? "trivial", - value: creatureXp, - title: "Total XP", - intermediateValues: [{ label: "Total XP", value: creatureXp }], - }; - } + return { + displayName, + summary, + cssClass: + PF2E_DND5E_DIFFICULTY_MAPPING[displayName.toLowerCase()] ?? + "trivial", + value: creatureXp, + title: "Total XP", + intermediateValues: [{ label: "Total XP", value: creatureXp }] + }; + } }