feat(v0.4): 回响编年史 — 跨周目叙事时间轴系统
- 新增 ChronicleEntry / RunStartSnapshot 类型与 GameState 字段 - 新建 chronicle.ts: 5 纪元名生成、模板化叙事、里程碑检测、run delta 计算 - engine.ts performPrestige 构建编年史条目并重置 runStart - gameStore: init 兼容旧存档 + tickTide 记录星潮 + resolveCurrentNode 计 BOSS 击杀 - chooseConstellationPerk 回填最近一条 entry 的 perksThisAscension - 新建 ChronicleDialog.tsx: 时间轴 UI + 5 纪元循环色 + 入场动画 - 新增 6 项成就: 首部编年/三纪元回响/五纪元闭环/首杀维度/维度猎手/星潮亲历者 - 新增 chronicle / chronicleOpen 程序化音效 - 修复关键 BUG: PrestigeDialog disabled 逻辑错误导致玩家永远无法飞升 - 修复 UX: newBp=0 时不再永久禁用飞升按钮(v0.3.1 星图+v0.4 编年史已提供动机) - 统计面板新增 BOSS 击破/星潮亲历/编年史条目 3 行 - 版本号升至 v0.4
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
DialogFooter,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { RotateCcw, Sparkles, Star } from "lucide-react";
|
||||
import { RotateCcw, Sparkles, Star, BookOpen } from "lucide-react";
|
||||
import { PRESTIGE } from "@/lib/game/config";
|
||||
import { computeNewBlueprints, computePrestigeBonus } from "@/lib/game/engine";
|
||||
import { constellationProgress } from "@/lib/game/constellation";
|
||||
@@ -29,6 +29,7 @@ export function PrestigeDialog({
|
||||
const doPrestige = useGameStore((s) => s.doPrestige);
|
||||
const { toast } = useToast();
|
||||
const [confirming, setConfirming] = useState(false);
|
||||
const [canReconfirm, setCanReconfirm] = useState(false);
|
||||
|
||||
const newBp = computeNewBlueprints(state);
|
||||
const bonus = computePrestigeBonus(state);
|
||||
@@ -111,6 +112,15 @@ export function PrestigeDialog({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 编年史铭刻提示(v0.4 新增) */}
|
||||
<div className="rounded-lg border border-violet-400/25 bg-violet-950/20 p-2.5 flex items-center gap-2">
|
||||
<BookOpen className="h-4 w-4 text-violet-300 flex-shrink-0" />
|
||||
<div className="flex-1 text-[10px] text-violet-100/70 leading-relaxed">
|
||||
本次飞升将铭刻入<span className="text-violet-200 font-bold">回响编年史</span>,
|
||||
记录本周目的解码、探险、星潮与觉醒天赋,形成永恒叙事时间轴。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
@@ -118,26 +128,37 @@ export function PrestigeDialog({
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
disabled={newBp <= 0 || confirming}
|
||||
disabled={confirming && !canReconfirm}
|
||||
onClick={() => {
|
||||
if (!confirming) {
|
||||
setConfirming(true);
|
||||
setCanReconfirm(false);
|
||||
window.setTimeout(() => setCanReconfirm(true), 900);
|
||||
return;
|
||||
}
|
||||
const res = doPrestige();
|
||||
onOpenChange(false);
|
||||
setConfirming(false);
|
||||
setCanReconfirm(false);
|
||||
if (res) {
|
||||
sfx("prestige");
|
||||
// 编年史铭刻音效(稍延迟,与飞升音分层)
|
||||
window.setTimeout(() => sfx("chronicle"), 600);
|
||||
toast({
|
||||
title: "✦ 飞升成功",
|
||||
description: `获得 ${res.newBp} 张蓝图,进入第 ${state.ascensions + 2} 周目。`,
|
||||
description: `获得 ${res.newBp} 张蓝图,进入第 ${state.ascensions + 2} 周目。编年史已铭刻新纪元。`,
|
||||
});
|
||||
}
|
||||
}}
|
||||
className="bg-gradient-to-r from-fuchsia-600 to-rose-500 hover:from-fuchsia-500 hover:to-rose-400 text-white border-0"
|
||||
>
|
||||
{confirming ? "再次确认飞升" : newBp <= 0 ? "无新蓝图" : "飞升"}
|
||||
{confirming
|
||||
? canReconfirm
|
||||
? "再次确认飞升"
|
||||
: "请确认…"
|
||||
: newBp <= 0
|
||||
? "飞升(无新蓝图)"
|
||||
: "飞升"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user