59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import type { PartyMember, Spell } from '../game'
|
|
import { applyCastStateUpdate, type CastStateFields } from './combatStateTransitions'
|
|
import { canCastSpell } from './spellCasting'
|
|
import { applySpellEffectProfile, type SpellEffectProfile, type SpellTargetPlan } from './spellEffects'
|
|
|
|
export function applyPvpSpellCast<TState extends CastStateFields<PartyMember[]>>({
|
|
current,
|
|
spell,
|
|
targetId,
|
|
resourceCost,
|
|
targetPlan,
|
|
profile,
|
|
setCurrent,
|
|
emitFloatingHeal,
|
|
cooldownMultiplier = 1,
|
|
cooldowns,
|
|
freeCast,
|
|
}: {
|
|
current: TState
|
|
spell: Spell
|
|
targetId: string
|
|
resourceCost: number
|
|
targetPlan: SpellTargetPlan
|
|
profile: SpellEffectProfile
|
|
setCurrent: (next: TState) => void
|
|
emitFloatingHeal: (memberId: string, value: number) => void
|
|
cooldownMultiplier?: number
|
|
cooldowns?: Record<string, number>
|
|
freeCast?: {
|
|
enabled: boolean
|
|
wasReady: boolean
|
|
}
|
|
}) {
|
|
if (!canCastSpell(spell, current.resource, current.cooldowns, resourceCost)) return false
|
|
const target = current.party.find((member) => member.id === targetId && member.health > 0)
|
|
if (!target) return false
|
|
|
|
const { party: nextParty, floatingHeals } = applySpellEffectProfile({
|
|
party: current.party,
|
|
spell,
|
|
targetId,
|
|
plan: targetPlan,
|
|
profile,
|
|
})
|
|
floatingHeals.forEach((event) => emitFloatingHeal(event.memberId, event.value))
|
|
|
|
const nextState = applyCastStateUpdate({
|
|
current,
|
|
party: nextParty,
|
|
cooldowns,
|
|
spell,
|
|
resourceCost,
|
|
cooldownMultiplier,
|
|
freeCast,
|
|
})
|
|
setCurrent(nextState)
|
|
return true
|
|
}
|