80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import type { Spell } from '../game'
|
|
|
|
export function cooldownNow() {
|
|
return Date.now()
|
|
}
|
|
|
|
export function cooldownRemaining(
|
|
cooldowns: Record<string, number>,
|
|
spellId: string,
|
|
now = cooldownNow(),
|
|
) {
|
|
return Math.max(0, ((cooldowns[spellId] ?? 0) - now) / 1000)
|
|
}
|
|
|
|
export function hasActiveCooldowns(
|
|
cooldowns: Record<string, number>,
|
|
now = cooldownNow(),
|
|
) {
|
|
return Object.values(cooldowns).some((readyAtMs) => readyAtMs > now)
|
|
}
|
|
|
|
export function pruneExpiredCooldowns(
|
|
cooldowns: Record<string, number>,
|
|
now = cooldownNow(),
|
|
) {
|
|
let changed = false
|
|
const nextCooldowns: Record<string, number> = {}
|
|
for (const id in cooldowns) {
|
|
if (cooldowns[id] <= now) {
|
|
changed = true
|
|
continue
|
|
}
|
|
nextCooldowns[id] = cooldowns[id]
|
|
}
|
|
return changed ? nextCooldowns : cooldowns
|
|
}
|
|
|
|
export function reduceCooldown(
|
|
cooldowns: Record<string, number>,
|
|
spellId: string,
|
|
seconds: number,
|
|
now = cooldownNow(),
|
|
) {
|
|
const readyAtMs = cooldowns[spellId]
|
|
if (!readyAtMs || readyAtMs <= now) return cooldowns
|
|
const nextReadyAtMs = readyAtMs - seconds * 1000
|
|
const nextCooldowns = { ...cooldowns }
|
|
if (nextReadyAtMs <= now) delete nextCooldowns[spellId]
|
|
else nextCooldowns[spellId] = nextReadyAtMs
|
|
return nextCooldowns
|
|
}
|
|
|
|
export function canCastSpell(
|
|
spell: Spell,
|
|
resource: number,
|
|
cooldowns: Record<string, number>,
|
|
resourceCost: number,
|
|
now = cooldownNow(),
|
|
) {
|
|
return resource >= resourceCost && cooldownRemaining(cooldowns, spell.id, now) <= 0
|
|
}
|
|
|
|
export function putSpellOnCooldown(
|
|
cooldowns: Record<string, number>,
|
|
spell: Spell,
|
|
cooldownMultiplier = 1,
|
|
now = cooldownNow(),
|
|
) {
|
|
const cooldownMs = spell.cooldown * cooldownMultiplier * 1000
|
|
if (cooldownMs <= 0) {
|
|
const nextCooldowns = { ...cooldowns }
|
|
delete nextCooldowns[spell.id]
|
|
return nextCooldowns
|
|
}
|
|
return {
|
|
...cooldowns,
|
|
[spell.id]: now + cooldownMs,
|
|
}
|
|
}
|