Files
i-want-to-heal/src/modes/iwt2/sim/roguelikePressure.ts
T
2026-07-06 23:49:14 -04:00

90 lines
2.3 KiB
TypeScript

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
}