import type { ToolKind } from "./components"; import { TOOL_LABELS } from "./logging"; export interface ToolEffectDelta { playerWaterDelta?: number; ownToolWaterDelta?: number; otherToolWaterDelta?: number; centralWaterDelta?: number; } export interface ToolEffectRecord extends Required { tool: ToolKind; phase: string; description?: string; } export interface ToolEffectSummary extends Required { tool: ToolKind; activations: number; } export interface ToolEffectRecorder { record(tool: ToolKind, phase: string, delta?: ToolEffectDelta, description?: string): void; } export class ToolEffectStats implements ToolEffectRecorder { private readonly summaries = new Map(); private readonly records: ToolEffectRecord[] = []; record( tool: ToolKind, phase: string, delta: ToolEffectDelta = {}, description?: string, ): void { const record: ToolEffectRecord = { tool, phase, description, playerWaterDelta: delta.playerWaterDelta ?? 0, ownToolWaterDelta: delta.ownToolWaterDelta ?? 0, otherToolWaterDelta: delta.otherToolWaterDelta ?? 0, centralWaterDelta: delta.centralWaterDelta ?? 0, }; this.records.push(record); const summary = this.summaries.get(tool) ?? { tool, activations: 0, playerWaterDelta: 0, ownToolWaterDelta: 0, otherToolWaterDelta: 0, centralWaterDelta: 0, }; summary.activations++; summary.playerWaterDelta += record.playerWaterDelta; summary.ownToolWaterDelta += record.ownToolWaterDelta; summary.otherToolWaterDelta += record.otherToolWaterDelta; summary.centralWaterDelta += record.centralWaterDelta; this.summaries.set(tool, summary); } getRecords(): readonly ToolEffectRecord[] { return this.records; } getSummaries(): ToolEffectSummary[] { return [...this.summaries.values()].sort((a, b) => TOOL_LABELS[a.tool].localeCompare(TOOL_LABELS[b.tool], "zh-Hans-CN"), ); } } export function formatToolEffectSummaries(stats: ToolEffectStats): string[] { const summaries = stats.getSummaries(); if (summaries.length === 0) return ["无道具效果记录"]; return [ "道具 | 触发次数 | 玩家水变化 | 自身道具水变化 | 其他道具水变化 | 中央水变化", "--- | ---: | ---: | ---: | ---: | ---:", ...summaries.map((summary) => [ TOOL_LABELS[summary.tool], summary.activations, summary.playerWaterDelta, summary.ownToolWaterDelta, summary.otherToolWaterDelta, summary.centralWaterDelta, ].join(" | "), ), ]; }