import type { Iwt2ArenaEvent, Iwt2PartyEntityState, Iwt2RoguelikePressureContentType, Iwt2RoguelikePressureState, } from './types' import { applyPartyDamageToMember, createArenaEvent } from './mechanics' const ROGUELIKE_PRESSURE_INTERVAL_SECONDS = 5 const ROGUELIKE_PRESSURE_BASE_DAMAGE = 9 const ROGUELIKE_PRESSURE_INITIAL_STAGE_DAMAGE = 2 const ROGUELIKE_PRESSURE_SOURCE_ID = 'roguelike-pressure' export function roguelikeIncomingDamageScale( stage: number, contentType: Iwt2RoguelikePressureContentType, ): number { void stage void contentType return 1 } export function createRoguelikePressureState( stage: number, contentType: Iwt2RoguelikePressureContentType, ): Iwt2RoguelikePressureState { const safeStage = safeRoguelikeStage(stage) return { stage: safeStage, contentType, damage: Math.round(ROGUELIKE_PRESSURE_BASE_DAMAGE + ROGUELIKE_PRESSURE_INITIAL_STAGE_DAMAGE), intervalSeconds: ROGUELIKE_PRESSURE_INTERVAL_SECONDS, nextPulseAt: ROGUELIKE_PRESSURE_INTERVAL_SECONDS, } } export function tickRoguelikePressure({ party, pressure, time, }: { party: Iwt2PartyEntityState[] pressure?: Iwt2RoguelikePressureState time: number }): { events: Iwt2ArenaEvent[] party: Iwt2PartyEntityState[] pressure?: Iwt2RoguelikePressureState } { if (!pressure || time < pressure.nextPulseAt) { return { events: [], party, pressure } } const events: Iwt2ArenaEvent[] = [] const nextParty = party.map((member) => { if (member.health <= 0) return member const before = member.health const result = applyPartyDamageToMember(member, pressure.damage) events.push(createArenaEvent( 0, time, 'partyDamaged', ROGUELIKE_PRESSURE_SOURCE_ID, member.id, result.damage, )) if (before > 0 && result.member.health <= 0) { events.push(createArenaEvent(0, time, 'entityDefeated', ROGUELIKE_PRESSURE_SOURCE_ID, member.id)) } return result.member }) let nextPulseAt = pressure.nextPulseAt while (nextPulseAt <= time) nextPulseAt += pressure.intervalSeconds return { events, party: nextParty, pressure: { ...pressure, nextPulseAt, }, } } function safeRoguelikeStage(stage: number): number { return Number.isFinite(stage) ? Math.max(1, Math.floor(stage)) : 1 }