feat: move to typescript, miniplex ecs

This commit is contained in:
2026-09-05 12:07:22 +05:00
parent 63f9885e46
commit f6596f765e
69 changed files with 3932 additions and 1838 deletions
+44
View File
@@ -0,0 +1,44 @@
import type { Player } from '../core/types'
import type { PlayerStatsSnapshot } from './events'
/** Статистика зрителей: убийства и промахи по именам. */
export class PlayerStats {
private readonly entries = new Map<string, { kills: number; misses: number }>()
reset(): void {
this.entries.clear()
}
addKill(player: Player): void {
this.entry(player).kills++
}
addMiss(player: Player): void {
this.entry(player).misses++
}
/** Топ-3 по убийствам и главный «Мазила» по промахам. */
snapshot(): PlayerStatsSnapshot {
const names = [...this.entries.keys()]
const byKills = names.slice().sort((a, b) => this.entries.get(b)!.kills - this.entries.get(a)!.kills)
const top = byKills.slice(0, 3).map((name) => ({ name, kills: this.entries.get(name)!.kills }))
let mazila: PlayerStatsSnapshot['mazila'] = null
for (const name of names) {
const { misses } = this.entries.get(name)!
if (misses > 0 && (!mazila || misses > mazila.misses)) {
mazila = { name, misses }
}
}
return { top, mazila }
}
private entry(player: Player): { kills: number; misses: number } {
let entry = this.entries.get(player.name)
if (!entry) {
entry = { kills: 0, misses: 0 }
this.entries.set(player.name, entry)
}
return entry
}
}