import type { Spell } from '../game' import { stackCount, type StackCounts } from './stackCounts' export type SlotModifier = { stacks: StackCounts id: (slot: string) => T multiplier?: number } export type StackModifier = { stacks: StackCounts id: T multiplier?: number } function slotKey(spell: Spell) { return String(spell.key) } function slotModifierStacks(spell: Spell, modifier?: SlotModifier) { return modifier ? stackCount(modifier.stacks, modifier.id(slotKey(spell))) : 0 } function stackModifierStacks(modifier?: StackModifier) { return modifier ? stackCount(modifier.stacks, modifier.id) : 0 } function stackMultiplier(modifier?: StackModifier) { if (!modifier) return 1 return (modifier.multiplier ?? 1.25) ** stackModifierStacks(modifier) } export function spellSlotMultiplier( spell: Spell, positive?: SlotModifier, negative?: SlotModifier, ) { const positiveMultiplier = (positive?.multiplier ?? 0.75) ** slotModifierStacks(spell, positive) const negativeMultiplier = (negative?.multiplier ?? 1.25) ** slotModifierStacks(spell, negative) return positiveMultiplier * negativeMultiplier } export function spellCooldownMultiplier( spell: Spell, cooldownDown?: SlotModifier, cooldownUp?: SlotModifier, ) { return spellSlotMultiplier(spell, cooldownDown, cooldownUp) } export function spellResourceCost({ spell, costDown, costUp, freeCastReady = false, freeCast, }: { spell: Spell costDown?: SlotModifier costUp?: SlotModifier freeCastReady?: boolean freeCast?: StackModifier }) { if (freeCastReady && stackModifierStacks(freeCast) > 0) return 0 return Math.ceil(spell.cost * spellSlotMultiplier(spell, costDown, costUp)) } export function spellExtraTargets( spell: Spell, extraTarget: SlotModifier, ) { return slotModifierStacks(spell, extraTarget) } export function spellPowerMultiplier(modifier: StackModifier) { return stackMultiplier(modifier) } export function hasSpellStack(modifier: StackModifier) { return stackModifierStacks(modifier) > 0 }