From 2ec863077dd4995709bae09c3baec8e0c6c89202 Mon Sep 17 00:00:00 2001 From: horrible little slime <69secret69email69@gmail.com> Date: Sat, 21 Dec 2024 12:28:51 -0500 Subject: [PATCH 1/2] draft --- src/damage.ts | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/damage.ts diff --git a/src/damage.ts b/src/damage.ts new file mode 100644 index 0000000000..c6dd31e32e --- /dev/null +++ b/src/damage.ts @@ -0,0 +1,64 @@ +import { Element } from "kolmafia"; +import { $elements } from "./template-string.js"; +import { get as getModifier } from "./modifier.js"; +import { sum } from "./utils.js"; + +export const SUPER_EFFECTIVE_CHART = Object.freeze({ + hot: $elements`Spooky, Cold`, + spooky: $elements`Cold, Sleaze`, + cold: $elements`Sleaze, Stench`, + sleaze: $elements`Stench, Hot`, + stench: $elements`Hot, Spooky`, +} as const); + +function isConventionalElement( + name: string, +): name is keyof typeof SUPER_EFFECTIVE_CHART { + return name in SUPER_EFFECTIVE_CHART; +} + +/** + * Determines if one type deals super effective damage against the other + * @param element The type of the damage + * @param against The type of the monster + * @returns Whether `element` is super effective against `against` + */ +export function isSuperEffective(element: Element, against: Element): boolean { + const elementName = element.toString(); + + return ( + isConventionalElement(elementName) && + SUPER_EFFECTIVE_CHART[elementName].includes(against) + ); +} + +/** + * Determines the amount of expected elemental damage, taking into account immunity and super effectiveness. + * @param damage The base amount of damage + * @param damageType The elemental type of the damage + * @param monsterType The elemental type of the target + * @returns The expected amount of damage the target would take + */ +export function elementalDamage( + damage: number, + damageType: Element, + monsterType: Element, +): number { + if (damage === 0) return 0; + if (damageType === monsterType) return 1; + if (isSuperEffective(damageType, monsterType)) return 2 * damage; + return damage; +} + +export const TRADITIONAL_ELEMENTS = Object.freeze( + $elements`cold, hot, sleaze, spooky, stench`, +); + +export function totalElementalDamage(): number { + return sum( + TRADITIONAL_ELEMENTS.map((el) => el.toString()).filter( + isConventionalElement, + ), + (el) => getModifier(`${el} Damage`), + ); +} From 5a1d2804cf6c2a2e20c81d0902d859a328e3508a Mon Sep 17 00:00:00 2001 From: horrible little slime <69secret69email69@gmail.com> Date: Sat, 21 Dec 2024 12:34:40 -0500 Subject: [PATCH 2/2] add and use `capitalize` utility function --- src/damage.ts | 7 +++++-- src/utils.ts | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/damage.ts b/src/damage.ts index c6dd31e32e..66439c5847 100644 --- a/src/damage.ts +++ b/src/damage.ts @@ -1,7 +1,7 @@ import { Element } from "kolmafia"; import { $elements } from "./template-string.js"; import { get as getModifier } from "./modifier.js"; -import { sum } from "./utils.js"; +import { capitalize, sum } from "./utils.js"; export const SUPER_EFFECTIVE_CHART = Object.freeze({ hot: $elements`Spooky, Cold`, @@ -54,11 +54,14 @@ export const TRADITIONAL_ELEMENTS = Object.freeze( $elements`cold, hot, sleaze, spooky, stench`, ); +/** + * @returns The total amount of elemental damage you have from all sources + */ export function totalElementalDamage(): number { return sum( TRADITIONAL_ELEMENTS.map((el) => el.toString()).filter( isConventionalElement, ), - (el) => getModifier(`${el} Damage`), + (el) => getModifier(`${capitalize(el)} Damage`), ); } diff --git a/src/utils.ts b/src/utils.ts index 05e4fa0fd2..0afa78ee08 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -409,3 +409,6 @@ export type Range = Exclude< Enumerate, Enumerate >; + +export const capitalize = (str: T): Capitalize => + (str.length ? `${str[0].toUpperCase()}${str.slice(1)}` : "") as Capitalize;