(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([typeof document === "object" ? document.currentScript : undefined, "[project]/src/store/gameStore.ts [app-client] (ecmascript) ", ((__turbopack_context__) => { "use strict"; __turbopack_context__.s([ "nextFragmentThreshold", ()=>nextFragmentThreshold, "useGameStore", ()=>useGameStore ]); var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$build$2f$polyfills$2f$process$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = /*#__PURE__*/ __turbopack_context__.i("[project]/node_modules/next/dist/build/polyfills/process.js [app-client] (ecmascript)"); // 回响星核 / Echo Nexus — Zustand 游戏状态管理 var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$zustand$2f$esm$2f$react$2e$mjs__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/zustand/esm/react.mjs [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$zustand$2f$esm$2f$middleware$2e$mjs__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/zustand/esm/middleware.mjs [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/config.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/engine.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/decode.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/expedition.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$achievements$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/achievements.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/starTide.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/constellation.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$chronicle$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/chronicle.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/beacon.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$offlineReport$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/offlineReport.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/attributes.ts [app-client] (ecmascript)"); "use client"; ; ; ; ; ; ; ; ; ; ; ; ; ; /** 全球星潮持续毫秒数(与 mini-service DURATION_SEC * 1000 一致) */ const GLOBAL_TIDE_DURATION_MS = 60_000; /** 计算并写回产能字段 */ function syncStats(state) { const s = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["recomputeStats"])(state); return { crystalsPerSec: s.crystalsPerSec, crystalCap: s.crystalCap, pulsePower: s.pulsePower, offlineEff: s.offlineEff, insightMult: s.insightMult, contactRateMult: s.contactRateMult, autoDecode: s.autoDecode, decodeStepsBonus: s.decodeStepsBonus }; } /** * 深空信标进度追踪(v0.5 → v0.8 → v0.8.2 扩展)。 * 在游戏关键动作(脉冲/解码/探险/BOSS/洞见)后调用,同时更新: * 1. 日挑战进度(按今日挑战类型增量) * 2. 限时挑战进度(按当前 4 小时时段挑战类型增量) * 3. 周挑战进度(按本周挑战类型增量) * 4. 信标链:日挑战刚完成时记录一次完成(含 grace 续命逻辑) * 进度独立存储于 localStorage,不污染 GameState。 * @returns 四类状态变更供 UI 触发通知 */ function trackBeacon(type, delta) { const result = { dailyJustCompleted: false, timedJustCompleted: false, weeklyJustCompleted: false, newChainMilestones: [] }; if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable ; try { // ---- 日挑战 ---- const challenge = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateDailyChallenge"])(); if (challenge.type === type) { const current = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadDailyProgress"])(); if (current.completedAt === null) { const { justCompleted } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["addBeaconProgress"])(current, challenge, delta); result.dailyJustCompleted = justCompleted; // 日挑战刚完成 → 更新信标链 if (justCompleted) { const { newMilestones } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["recordChainCompletion"])((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTodayKey"])()); result.newChainMilestones = newMilestones; } } } // ---- 限时挑战(v0.8.2)---- const tChallenge = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateTimedChallenge"])(); if (tChallenge.type === type) { const tCurrent = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadTimedProgress"])(); if (tCurrent.completedAt === null) { const { justCompleted } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["addTimedProgress"])(tCurrent, tChallenge, delta); result.timedJustCompleted = justCompleted; } } // ---- 周挑战 ---- const wChallenge = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateWeeklyChallenge"])(); if (wChallenge.type === type) { const wCurrent = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadWeeklyProgress"])(); if (wCurrent.completedAt === null) { const { justCompleted } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["addWeeklyProgress"])(wCurrent, wChallenge, delta); result.weeklyJustCompleted = justCompleted; } } return result; } catch { return result; } } /** 检查并解锁叙事碎片 */ function checkFragments(state) { const unlocked = []; for (const f of __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["FRAGMENTS"]){ if (!state.fragments[f.id] && state.totalDecoded >= f.threshold) { state.fragments[f.id] = true; unlocked.push(f.id); } } return unlocked; } const useGameStore = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$zustand$2f$esm$2f$react$2e$mjs__$5b$app$2d$client$5d$__$28$ecmascript$29$__["create"])()((0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$zustand$2f$esm$2f$middleware$2e$mjs__$5b$app$2d$client$5d$__$28$ecmascript$29$__["persist"])((set, get)=>({ ...(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialState"])(), _lastAutoDecode: Date.now(), _lastSpawn: Date.now(), _combo: 0, _lastPulse: 0, _achievementQueue: [], _tideEvents: [], globalTide: null, init: ()=>{ const s = get(); const now = Date.now(); // 兼容旧存档:若存在不可解的活跃谜题(旧算法生成),直接清掉 let activePuzzle = s.activePuzzle; if (activePuzzle && !(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["isSolvable"])(activePuzzle)) { // 把晶体放回队列,避免玩家卡死 const crystal = { id: `c_${now}_rec`, tier: activePuzzle.tier, value: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_VALUE"][activePuzzle.tier].crystals, createdAt: now }; activePuzzle = null; set({ pendingCrystals: [ ...s.pendingCrystals, crystal ].slice(-__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_SPAWN"].maxPending) }); } // 兼容旧存档:补全 achievements / 星潮 / 星图 字段 const achievements = s.achievements ?? {}; const activeTide = s.activeTide ?? null; const constellation = s.constellation ?? []; const pendingPerkChoices = s.pendingPerkChoices ?? null; // v0.4 编年史兼容:补全 chronicle / runStart / bossKills / starTidesEncountered const migrated = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$chronicle$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["migrateChronicleFields"])(s); // v0.7 角色属性兼容:补全 attributes / attributeProgress / pendingAttrPoints const attrMigrated = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["migrateAttributes"])(s); // 星图「能量共振」天赋 +1 能量上限 const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(constellation); const energyMax = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["INITIAL_STATE"].energyMax + cm.energyMaxBonus; // lastTideEnd:0 表示从未触发过星潮(首次游玩),保留 0 让 firstDelay 生效 const lastTideEndRaw = s.lastTideEnd ?? 0; // 若旧存档有已过期的星潮,清掉 const tide = activeTide && activeTide.endsAt > now ? activeTide : null; // 首次进入:补发离线收益 const elapsed = Math.max(0, (now - s.lastTick) / 1000); if (elapsed > 5) { const cap = 8 * 3600; const secs = Math.min(elapsed, cap); const gain = s.crystalsPerSec * secs * s.offlineEff; const crystalsBefore = s.crystals; const crystalsAfter = Math.min(s.crystalCap, s.crystals + gain); // 设置离线报告(v0.5.2):通知 UI 弹出"欢迎回来"对话框 (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$offlineReport$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["setPendingOfflineReport"])({ elapsedSec: secs, rawElapsedSec: elapsed, gain: crystalsAfter - crystalsBefore, rate: s.crystalsPerSec, eff: s.offlineEff, capped: elapsed > cap, crystalsBefore, crystalsAfter, crystalCap: s.crystalCap }); set({ crystals: crystalsAfter, lastTick: now, activePuzzle, achievements, activeTide: tide, lastTideEnd: tide ? lastTideEndRaw : lastTideEndRaw, constellation, pendingPerkChoices, energyMax, chronicle: migrated.chronicle, runStart: migrated.runStart, bossKills: migrated.bossKills, starTidesEncountered: migrated.starTidesEncountered, attributes: attrMigrated.attributes, attributeProgress: attrMigrated.attributeProgress, pendingAttrPoints: attrMigrated.pendingAttrPoints, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements, activeTide: tide, constellation, attributes: attrMigrated.attributes }) }); } else { set({ lastTick: now, activePuzzle, achievements, activeTide: tide, lastTideEnd: tide ? lastTideEndRaw : lastTideEndRaw, constellation, pendingPerkChoices, energyMax, chronicle: migrated.chronicle, runStart: migrated.runStart, bossKills: migrated.bossKills, starTidesEncountered: migrated.starTidesEncountered, attributes: attrMigrated.attributes, attributeProgress: attrMigrated.attributeProgress, pendingAttrPoints: attrMigrated.pendingAttrPoints, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements, activeTide: tide, constellation, attributes: attrMigrated.attributes }) }); } }, loadOnline: ()=>{ const s = get(); set({ ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: s.attributes }) }); }, hardReset: ()=>{ set({ ...(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialState"])(), _lastAutoDecode: Date.now(), _lastSpawn: Date.now(), _combo: 0, _lastPulse: 0, _achievementQueue: [], _tideEvents: [], globalTide: null }); }, tickTide: (now)=>{ const s = get(); // === P3 全球星潮优先:若全球星潮进行中,本地不触发新的星潮 === if (s.globalTide) { // 1a) 检查全球星潮是否结束 if (now >= s.globalTide.endsAt) { const endedType = s.globalTide.type; let silenceCompensation = 0; if (endedType === "silence") { silenceCompensation = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeSilenceCompensation"])({ type: endedType, startedAt: s.globalTide.startedAt, endsAt: s.globalTide.endsAt, id: s.globalTide.id }); } const event = { ended: endedType, isGlobal: true }; if (silenceCompensation > 0) event.silenceCompensation = silenceCompensation; set({ globalTide: null, activeTide: null, lastTideEnd: now, insights: s.insights + silenceCompensation, // 星潮结束后重算 stats ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: null, constellation: s.constellation, attributes: s.attributes }), _tideEvents: [ ...s._tideEvents, event ] }); return event; } // 1b) 全球星潮仍在进行 — 不做本地处理(避免冲突) return null; } const tide = s.activeTide; // 星图「星潮引导」减少间隙 const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(s.constellation ?? []); // v0.7 灵感:星潮触发概率 +X%(缩短间隙) const am = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAllBonuses"])(s.attributes ?? {}); const tideGapReduction = Math.min(0.3, am.tideTriggerBonus); const gap = Math.max(15000, (__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["TIDE_CONFIG"].gap + cm.tideGapDeltaSec * 1000) * (1 - tideGapReduction)); // 2) 检查当前本地星潮是否结束 if (tide && now >= tide.endsAt) { const endedType = tide.type; // 寂静期补偿洞见 let silenceCompensation = 0; if (tide.type === "silence") { silenceCompensation = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeSilenceCompensation"])(tide); } const newInsights = s.insights + silenceCompensation; const event = { ended: endedType }; if (silenceCompensation > 0) event.silenceCompensation = silenceCompensation; set({ activeTide: null, lastTideEnd: now, insights: newInsights, // 星潮结束后重算 stats(移除 contactRate/insight 修饰) ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: null, constellation: s.constellation, attributes: s.attributes }), _tideEvents: [ ...s._tideEvents, event ] }); return event; } // 3) 检查是否该触发新星潮(间隙已过) if (!tide) { const since = now - s.lastTideEnd; // 首次:以 createdAt 起算 firstDelay;之后以 lastTideEnd 起算 gap const firstStart = s.lastTideEnd === 0 || s.lastTideEnd <= s.createdAt + 1000; const need = firstStart ? __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["TIDE_CONFIG"].firstDelay : gap; if (since >= need) { const type = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["rollTide"])(); const newTide = { id: `tide_${now}_${Math.random().toString(36).slice(2, 7)}`, type, startedAt: now, endsAt: now + __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["TIDE_CONFIG"].duration }; const event = { started: type }; // v0.4 编年史:累计遇到的星潮 ID(去重) const tidesAll = s.starTidesEncountered ?? []; const tideId = `tide_${type}`; const newTidesAll = tidesAll.includes(tideId) ? tidesAll : [ ...tidesAll, tideId ]; set({ activeTide: newTide, starTidesEncountered: newTidesAll, // 星潮开始后重算 stats(应用 contactRate/insight 修饰) ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: newTide, constellation: s.constellation, attributes: s.attributes }), _tideEvents: [ ...s._tideEvents, event ] }); return event; } } return null; }, consumeTideEvents: ()=>{ const s = get(); if (s._tideEvents.length === 0) return []; const items = s._tideEvents; set({ _tideEvents: [] }); return items; }, // P3 socket 多人同步:服务端广播全球星潮时调用,强制覆盖本地冷却 triggerGlobalTide: (type)=>{ const s = get(); const now = Date.now(); const id = `global_tide_${now}_${Math.random().toString(36).slice(2, 7)}`; const newTide = { id, type, startedAt: now, endsAt: now + GLOBAL_TIDE_DURATION_MS }; const newGlobalTide = { type, startedAt: now, endsAt: now + GLOBAL_TIDE_DURATION_MS, id }; // 编年史:累计遇到的星潮 ID(去重) const tidesAll = s.starTidesEncountered ?? []; const tideId = `tide_${type}`; const newTidesAll = tidesAll.includes(tideId) ? tidesAll : [ ...tidesAll, tideId ]; const event = { started: type, isGlobal: true }; set({ globalTide: newGlobalTide, activeTide: newTide, starTidesEncountered: newTidesAll, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: newTide, constellation: s.constellation, attributes: s.attributes }), _tideEvents: [ ...s._tideEvents, event ] }); }, tick: (now)=>{ const s = get(); const dt = Math.max(0, (now - s.lastTick) / 1000); if (dt <= 0) return; // 星潮产能修饰(即时乘) const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const effCps = s.crystalsPerSec * tideMod.crystalsPerSecMult; // 产能累加(仅闲置产能受仓库上限;探险奖励可超出) const newCrystals = s.crystals >= s.crystalCap ? s.crystals // 已达/超上限,不再自动产出 : Math.min(s.crystalCap, s.crystals + effCps * dt); // 自动产出待解码晶体(每 baseInterval 秒一颗,受技术/飞升略提速) const bpBoost = 1 + s.blueprints.length * 0.03; const spawnInterval = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_SPAWN"].baseIntervalSec / bpBoost * 1000; let pending = s.pendingCrystals; let lastSpawn = s._lastSpawn; if (now - lastSpawn > spawnInterval && pending.length < __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_SPAWN"].maxPending) { // 星图「晶体富集」提升 T2/T3 概率 const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(s.constellation ?? []); const tier = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["rollCrystalTierWithBonus"])(cm.t2t3BonusRate); const crystal = { id: `c_${now}_${Math.random().toString(36).slice(2, 7)}`, tier, value: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_VALUE"][tier].crystals, createdAt: now }; pending = [ ...pending, crystal ]; lastSpawn = now; } // 能量恢复(探险系统,v0.8.1 动态间隔) let energy = s.energy; let lastEnergyTick = s.lastEnergyTick; if (energy < s.energyMax) { const intervalSec = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeEnergyRegenInterval"])(s); const regen = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeEnergyRegen"])(lastEnergyTick, now, energy, s.energyMax, intervalSec); energy = regen.energy; lastEnergyTick = regen.lastTick; } else { lastEnergyTick = now; } set({ crystals: newCrystals, lastTick: now, pendingCrystals: pending, _lastSpawn: lastSpawn, energy, lastEnergyTick }); }, pulse: ()=>{ const s = get(); const now = Date.now(); // 连击 let combo = 1; if (now - s._lastPulse < 1500) { combo = Math.min(10, s._combo + 1); } const mult = 1 + (combo - 1) * 0.15; // 星潮脉冲威力修饰 const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); // v0.7 灵感:脉冲连击加成 +X% const am = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAllBonuses"])(s.attributes ?? {}); const comboBonusMult = 1 + am.pulseComboBonus * Math.max(0, combo - 1); const gain = s.pulsePower * mult * tideMod.pulsePowerMult * comboBonusMult; set({ crystals: Math.min(s.crystalCap, s.crystals + gain), _combo: combo, _lastPulse: now }); // 深空信标:脉冲任务进度 +1 trackBeacon("pulse", 1); // v0.7 角色属性:连击 ≥3 给灵感经验 if (combo >= 3) { const expGain = 1 + Math.floor(combo / 2); // 3 连击=2, 5 连击=3, 10 连击=6 // 内联经验获取(避免递归调用 set) const prog = s.attributeProgress?.inspiration ?? { exp: 0, level: s.attributes?.inspiration ?? 0 }; const nextExp = prog.exp + expGain; const lvlResult = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: nextExp, level: s.attributes?.inspiration ?? 0 }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const newAttributes = { ...s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(), inspiration: lvlResult.newProgress.level }; const newProgress = { ...s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(), inspiration: lvlResult.newProgress }; set({ attributes: newAttributes, attributeProgress: newProgress, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); } return { gain, combo }; }, startDecode: (crystalId)=>{ const s = get(); const crystal = s.pendingCrystals.find((c)=>c.id === crystalId); if (!crystal) return; // v0.8.2 涌动星潮:解码目标序列 +2(更长谜题) const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const targetLenBonus = tideMod.targetLenBonus ?? 0; const puzzle = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generatePuzzle"])(crystal.tier, undefined, targetLenBonus); set({ activePuzzle: puzzle, pendingCrystals: s.pendingCrystals.filter((c)=>c.id !== crystalId) }); }, clickNode: (nodeId)=>{ const s = get(); if (!s.activePuzzle) return { ok: false, finished: false, failReason: "无活跃谜题" }; // 深拷贝谜题 const puzzle = JSON.parse(JSON.stringify(s.activePuzzle)); const res = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["tryClickNode"])(puzzle, nodeId); if (res.ok) { if (res.finished) { // 结算奖励(星潮解码奖励修饰 + 星图「二周目经验」) const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(s.constellation ?? []); const base = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["decodeRewards"])(puzzle.tier, s.insightMult, s.contactRateMult); const finalMult = tideMod.decodeRewardMult * cm.decodeRewardMult; const rewards = { crystals: Math.round(base.crystals * finalMult), insights: Math.round(base.insights * finalMult), contact: +(base.contact * finalMult).toFixed(2) }; const newTotal = s.totalDecoded + 1; const newContact = Math.min(100, s.contact + rewards.contact); const newInsights = s.insights + rewards.insights; const newCrystals = s.crystals + rewards.crystals; // 解锁碎片 const tentative = { ...s, totalDecoded: newTotal, fragments: { ...s.fragments } }; const unlocked = checkFragments(tentative); // v0.7 角色属性:完成解码给智慧经验(tier 越高经验越多) const wisdomExpGain = puzzle.tier * 2; const curAttrs = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); const curProg = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); const progEntry = curProg.wisdom ?? { exp: 0, level: curAttrs.wisdom }; const wisdomLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: progEntry.exp + wisdomExpGain, level: curAttrs.wisdom }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const newAttributes = { ...curAttrs, wisdom: wisdomLvl.newProgress.level }; const newProgress = { ...curProg, wisdom: wisdomLvl.newProgress }; set({ activePuzzle: null, crystals: newCrystals, insights: newInsights, contact: newContact, totalDecoded: newTotal, fragments: tentative.fragments, attributes: newAttributes, attributeProgress: newProgress, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); // 深空信标:解码 +1,洞见累计 trackBeacon("decode", 1); trackBeacon("insight", rewards.insights); return { ok: true, finished: true, failReason: unlocked.join(",") || undefined }; } // 点击成功但未完成:检测当前局面是否仍可解 const solvable = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["isSolvable"])(puzzle); set({ activePuzzle: puzzle }); return { ok: true, finished: false, solvable }; } return res; }, undoStep: ()=>{ const s = get(); if (!s.activePuzzle || s.activePuzzle.path.length === 0) return; const puzzle = JSON.parse(JSON.stringify(s.activePuzzle)); const lastId = puzzle.path.pop(); if (lastId !== undefined) { const node = puzzle.grid.find((n)=>n.id === lastId); if (node) node.used = false; } set({ activePuzzle: puzzle }); }, retryPuzzle: ()=>{ const s = get(); if (!s.activePuzzle) return; set({ activePuzzle: (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$decode$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["resetPuzzle"])(s.activePuzzle) }); }, abandonPuzzle: ()=>{ const s = get(); if (!s.activePuzzle) return; // 晶体放回队列末尾 const crystal = { id: `c_${Date.now()}_ret`, tier: s.activePuzzle.tier, value: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_VALUE"][s.activePuzzle.tier].crystals, createdAt: Date.now() }; set({ activePuzzle: null, pendingCrystals: [ ...s.pendingCrystals, crystal ].slice(-__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRYSTAL_SPAWN"].maxPending) }); }, autoDecodeTick: ()=>{ const s = get(); if (!s.autoDecode) return; const now = Date.now(); // 星图「自动校准」减少自动解码周期 const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(s.constellation ?? []); // v0.7 智慧:自动解码周期 -X% const am = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAllBonuses"])(s.attributes ?? {}); const baseInterval = 12000 + cm.autoDecodeIntervalDeltaSec * 1000; // v0.8.2 棱镜星潮:自动解码周期 ×0.7(-30%) const tideModEarly = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const tideIntervalMult = tideModEarly.autoDecodeIntervalMult ?? 1; const interval = Math.max(5000, baseInterval * am.autoDecodeIntervalMult * tideIntervalMult); if (now - s._lastAutoDecode < interval) return; // 找一颗 T1 晶体自动解码;v0.9 dec_5「全息解码核心」解锁后可自动解码 T2 let autoTier = 1; let idx = s.pendingCrystals.findIndex((c)=>c.tier === 1); if (idx < 0 && s.tech?.dec_5) { idx = s.pendingCrystals.findIndex((c)=>c.tier === 2); autoTier = 2; } if (idx < 0) return; const crystal = s.pendingCrystals[idx]; const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const base = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["decodeRewards"])(autoTier, s.insightMult, s.contactRateMult); const finalMult = tideMod.decodeRewardMult * cm.decodeRewardMult; const rewards = { crystals: Math.round(base.crystals * finalMult), insights: Math.round(base.insights * finalMult), contact: +(base.contact * finalMult).toFixed(2) }; const newTotal = s.totalDecoded + 1; const tentative = { ...s, totalDecoded: newTotal, fragments: { ...s.fragments } }; checkFragments(tentative); // v0.7 角色属性:自动解码给智慧经验(少量) const curAttrs = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); const curProg = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); const progEntry = curProg.wisdom ?? { exp: 0, level: curAttrs.wisdom }; const wisdomLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: progEntry.exp + 1, level: curAttrs.wisdom }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const newAttributes = { ...curAttrs, wisdom: wisdomLvl.newProgress.level }; const newProgress = { ...curProg, wisdom: wisdomLvl.newProgress }; set({ pendingCrystals: s.pendingCrystals.filter((c)=>c.id !== crystal.id), crystals: s.crystals + rewards.crystals, insights: s.insights + rewards.insights, contact: Math.min(100, s.contact + rewards.contact), totalDecoded: newTotal, fragments: tentative.fragments, _lastAutoDecode: now, attributes: newAttributes, attributeProgress: newProgress, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); // 深空信标:自动解码也算进度 trackBeacon("decode", 1); trackBeacon("insight", rewards.insights); }, buyTech: (techId)=>{ const s = get(); const node = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["TECH_TREE"].find((t)=>t.id === techId); if (!node) return false; const cur = s.tech[techId] ?? 0; if (cur >= 1) return false; // v0.1 每节点 1 级 if (s.insights < node.cost) return false; const newTech = { ...s.tech, [techId]: 1 }; set({ insights: s.insights - node.cost, tech: newTech, ...syncStats({ tech: newTech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: s.attributes }) }); return true; }, // ============ 探险系统 ============ startExpedition: ()=>{ const s = get(); if (s.activeExpedition && !s.activeExpedition.finished) { return { ok: false, reason: "已有进行中的探险" }; } if (s.energy < __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["EXPEDITION_CONFIG"].energyCost) { return { ok: false, reason: "能量不足" }; } const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); // v0.7 角色属性:探索力 +X% 探险力,勇气 +X 探险生命 const am = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAllBonuses"])(s.attributes ?? {}); const basePower = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeExpeditionPower"])(s) + tideMod.expeditionPowerBonus; const baseHp = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeExpeditionHp"])(s) + tideMod.expeditionHpBonus; const power = Math.round(basePower * am.expeditionPowerMult); const hp = baseHp + am.expeditionHpBonus; const seed = Math.floor(Math.random() * 1e9); const expedition = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateExpedition"])(seed, power, hp); set({ activeExpedition: expedition, energy: s.energy - __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["EXPEDITION_CONFIG"].energyCost, totalExpeditions: s.totalExpeditions + 1 }); return { ok: true }; }, resolveCurrentNode: ()=>{ const s = get(); if (!s.activeExpedition || s.activeExpedition.finished) return null; // 深拷贝 const exp = JSON.parse(JSON.stringify(s.activeExpedition)); // v0.7 勇气:BOSS 战胜率 +X%(动态提高 RNG 阈值) // v0.8.2 蚀相星潮:BOSS 胜率 +20% const nodeBefore = exp.nodes[exp.currentNode]; const isBossNode = nodeBefore?.type === "boss"; const am = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAllBonuses"])(s.attributes ?? {}); const tideMod = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$starTide$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getTideModifiers"])(s.activeTide); const tideBossBonus = tideMod.bossWinRateBonus ?? 0; const result = isBossNode ? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["resolveNode"])(exp, ()=>{ // 单次 rng() 调用:B% 概率返回 0(必胜),其余情况返回 r-B(保持均匀分布) const r = Math.random(); const b = Math.min(0.95, am.bossWinRateBonus + tideBossBonus); return r < b ? 0 : Math.min(1, r - b); }) : (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$expedition$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["resolveNode"])(exp); // 累计奖励 if (result.crystals) exp.rewards.crystals += result.crystals; if (result.insights) exp.rewards.insights += result.insights; if (result.contact) exp.rewards.contact += result.contact; if (result.fragments) exp.rewards.fragments.push(...result.fragments); if (result.hpDelta) exp.hp = Math.max(0, Math.min(exp.maxHp, exp.hp + result.hpDelta)); // 实时入账(玩家立即获得) const newCrystals = s.crystals + (result.crystals || 0); const newInsights = s.insights + (result.insights || 0); const newContact = Math.min(100, s.contact + (result.contact || 0)); // 碎片解锁 const newFragments = { ...s.fragments }; if (result.fragments) { for (const fid of result.fragments)newFragments[fid] = true; } // 日志 const logEntry = { expeditionId: exp.id, nodeType: nodeBefore?.type || "combat", result: result.log, rewards: [ result.crystals ? `+${result.crystals}晶体` : "", result.insights ? `+${result.insights}洞见` : "", result.contact ? `+${result.contact.toFixed(1)}接触` : "", result.hpDelta ? `${result.hpDelta > 0 ? "+" : ""}${result.hpDelta}生命` : "" ].filter(Boolean).join(" "), timestamp: Date.now() }; const newLog = [ logEntry, ...s.expeditionLog ].slice(0, 30); // v0.10 工单 #2 修复:探险结束时立即清空 activeExpedition,避免 finished 状态卡死 // 保留 lastExpeditionSummary 用于入口展示「上次结果」 if (result.ended) { exp.finished = true; } // v0.9 工单修复:探险结束时记录摘要,用于入口界面展示 let lastExpeditionSummary = s.lastExpeditionSummary ?? null; if (result.ended && (result.endReason === "victory" || result.endReason === "defeat")) { lastExpeditionSummary = { result: result.endReason, rewards: { ...exp.rewards }, nodeCount: exp.nodes.length, finishedAt: Date.now() }; } // v0.4 编年史:击破 BOSS 时累计计数 let bossKills = s.bossKills ?? 0; let bossKilledThisNode = false; if (result.ended && result.endReason === "victory" && nodeBefore?.type === "boss") { bossKills = bossKills + 1; bossKilledThisNode = true; } // v0.7 角色属性:战斗胜利给勇气+探索力经验;BOSS 额外奖励 let newAttributes = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); let newProgress = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); let statsNeedResync = false; // 战斗类节点(combat/boss)且胜利:勇气 + 探索力经验 const isCombatVictory = (nodeBefore?.type === "combat" || nodeBefore?.type === "boss") && !result.ended; // 中途战斗胜利(未结束探险) const isExpeditionVictory = result.ended && result.endReason === "victory"; if (isCombatVictory || bossKilledThisNode || isExpeditionVictory) { const courageGain = bossKilledThisNode ? 8 : 2; const explorationGain = bossKilledThisNode ? 6 : isExpeditionVictory ? 4 : 1; const courageLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: newProgress.courage.exp + courageGain, level: newAttributes.courage }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const explLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: newProgress.exploration.exp + explorationGain, level: newAttributes.exploration }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); newAttributes = { ...newAttributes, courage: courageLvl.newProgress.level, exploration: explLvl.newProgress.level }; newProgress = { ...newProgress, courage: courageLvl.newProgress, exploration: explLvl.newProgress }; statsNeedResync = true; } set({ // v0.10 工单 #2 修复:探险结束立即清空 activeExpedition,让玩家无障碍再出发 activeExpedition: result.ended ? null : exp, crystals: newCrystals, insights: newInsights, contact: newContact, fragments: newFragments, expeditionLog: newLog, bossKills, attributes: newAttributes, attributeProgress: newProgress, lastExpeditionSummary, ...statsNeedResync ? syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) : {} }); // 深空信标:探险完成(胜负都计)+ 洞见累计 + BOSS 击破 if (result.ended) { trackBeacon("expedition", 1); if (bossKilledThisNode) { trackBeacon("boss", 1); } } if (result.insights) trackBeacon("insight", result.insights); return result; }, advanceNode: ()=>{ const s = get(); if (!s.activeExpedition || s.activeExpedition.finished) return; const exp = JSON.parse(JSON.stringify(s.activeExpedition)); const node = exp.nodes[exp.currentNode]; if (!node || !node.cleared) return; // 当前节点未结算不能前进 if (exp.currentNode >= exp.nodes.length - 1) return; exp.currentNode++; set({ activeExpedition: exp }); }, abortExpedition: ()=>{ const s = get(); if (!s.activeExpedition) return; const exp = JSON.parse(JSON.stringify(s.activeExpedition)); const logEntry = { expeditionId: exp.id, nodeType: "rest", result: "探险队主动撤退,保留已获奖励。", rewards: "", timestamp: Date.now() }; // v0.9 工单修复:记录上次探险摘要,用于入口展示 const summary = { result: "abort", rewards: { ...exp.rewards }, nodeCount: exp.nodes.length, finishedAt: Date.now() }; set({ // v0.10 工单 #2 修复:撤退立即清空 activeExpedition,避免 finished 卡死 activeExpedition: null, expeditionLog: [ logEntry, ...s.expeditionLog ].slice(0, 30), lastExpeditionSummary: summary }); }, // v0.9 工单修复:手动关闭已结束探险,回到入口 dismissExpedition: ()=>{ const s = get(); if (!s.activeExpedition || !s.activeExpedition.finished) return; set({ activeExpedition: null }); }, doPrestige: ()=>{ const s = get(); if (s.contact < __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CONTACT"].prestigeMin) return null; const newBp = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["computeNewBlueprints"])(s); const next = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["performPrestige"])(s); // 星图「能量共振」提升上限 const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(next.constellation ?? []); const energyMax = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["INITIAL_STATE"].energyMax + cm.energyMaxBonus; set({ ...next, energyMax, ...syncStats({ tech: next.tech, blueprints: next.blueprints, achievements: next.achievements, activeTide: next.activeTide, constellation: next.constellation, attributes: next.attributes }), _lastAutoDecode: Date.now(), _lastSpawn: Date.now(), _combo: 0, _lastPulse: 0, _tideEvents: [] }); return { newBp }; }, chooseConstellationPerk: (perkId)=>{ const s = get(); if (!s.pendingPerkChoices || !s.pendingPerkChoices.includes(perkId)) return false; const perk = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getPerk"])(perkId); if (!perk) return false; if (s.constellation?.includes(perkId)) return false; const newConstellation = [ ...s.constellation ?? [], perkId ]; const cm = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["constellationBonuses"])(newConstellation); const energyMax = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["INITIAL_STATE"].energyMax + cm.energyMaxBonus; // v0.4 编年史:回填最近一条 entry 的 perksThisAscension const chronicle = s.chronicle ?? []; let newChronicle = chronicle; if (chronicle.length > 0) { const lastEntry = chronicle[chronicle.length - 1]; const updatedLast = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$chronicle$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["withPerks"])(lastEntry, [ perkId ]); newChronicle = [ ...chronicle.slice(0, -1), updatedLast ]; } set({ constellation: newConstellation, pendingPerkChoices: null, energyMax, chronicle: newChronicle, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: newConstellation, attributes: s.attributes }) }); return true; }, rerollPerkChoices: ()=>{ const s = get(); if (!s.pendingPerkChoices) return; const choices = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$constellation$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["rollPerkChoices"])(s.constellation ?? []); if (choices.length > 0) set({ pendingPerkChoices: choices }); }, checkAchievements: ()=>{ const s = get(); const newlyUnlocked = []; const updated = { ...s.achievements }; let crystals = s.crystals; let insights = s.insights; let contact = s.contact; let statsDirty = false; for (const a of __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$achievements$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ACHIEVEMENTS"]){ if (updated[a.id]) continue; if (a.check(s)) { updated[a.id] = true; newlyUnlocked.push(a); // 发放即时奖励 if (a.reward.crystals) crystals += a.reward.crystals; if (a.reward.insights) insights += a.reward.insights; if (a.reward.contact) contact = Math.min(100, contact + a.reward.contact); if (a.reward.crystalsPerSecPct || a.reward.insightPct) statsDirty = true; } } if (newlyUnlocked.length === 0) return []; set({ achievements: updated, crystals, insights, contact, ...statsDirty ? syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: updated, activeTide: s.activeTide, constellation: s.constellation, attributes: s.attributes }) : {}, _achievementQueue: [ ...s._achievementQueue, ...newlyUnlocked ] }); return newlyUnlocked; }, consumeAchievementQueue: ()=>{ const s = get(); if (s._achievementQueue.length === 0) return []; const items = s._achievementQueue; set({ _achievementQueue: [] }); return items; }, canPrestige: ()=>get().contact >= __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CONTACT"].prestigeMin, toggleTheme: ()=>set({ theme: get().theme === "dark" ? "light" : "dark" }), toggleSound: ()=>set({ soundOn: !get().soundOn }), // 深空信标:发放每日挑战奖励(v0.5) grantBeaconReward: (insights, contact)=>{ const s = get(); set({ insights: s.insights + Math.round(insights), contact: Math.min(100, s.contact + contact) }); }, // 深空信标:领取周挑战奖励(v0.8) claimWeeklyBeacon: ()=>{ const challenge = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateWeeklyChallenge"])(); const progress = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadWeeklyProgress"])(); const res = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["claimWeeklyReward"])(challenge, progress); if (res.rewardInsight > 0 || res.rewardContact > 0) { const s = get(); set({ insights: s.insights + Math.round(res.rewardInsight), contact: Math.min(100, s.contact + res.rewardContact) }); // 异步提交到云排行榜(失败静默,不影响本地) if (res.entry) { void (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["submitCloudScore"])(res.entry); } } return { rewardInsight: res.rewardInsight, rewardContact: res.rewardContact, score: res.score }; }, // 深空信标:领取限时挑战奖励(v0.8.2) claimTimedBeacon: ()=>{ const challenge = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateTimedChallenge"])(); const progress = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadTimedProgress"])(); const res = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["claimTimedReward"])(challenge, progress); if (res.rewardInsight > 0 || res.rewardContact > 0) { const s = get(); set({ insights: s.insights + Math.round(res.rewardInsight), contact: Math.min(100, s.contact + res.rewardContact) }); // 异步提交到云排行榜(失败静默,不影响本地) if (res.entry) { void (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["submitCloudScore"])(res.entry); } } return { rewardInsight: res.rewardInsight, rewardContact: res.rewardContact, score: res.score }; }, // 深空信标:领取信标链里程碑奖励(v0.8) claimChainReward: (milestone)=>{ // loadChainState 仅用于前置校验,真正的状态修改由 claimChainMilestone 完成 const pre = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadChainState"])(); if (pre.currentStreak < milestone || pre.milestonesClaimed.includes(milestone)) { return { rewardInsight: 0, rewardContact: 0, label: "", ok: false }; } const res = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$beacon$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["claimChainMilestone"])(milestone); if (res.rewardInsight > 0 || res.rewardContact > 0) { const s = get(); set({ insights: s.insights + Math.round(res.rewardInsight), contact: Math.min(100, s.contact + res.rewardContact) }); } return { rewardInsight: res.rewardInsight, rewardContact: res.rewardContact, label: res.label, ok: res.rewardInsight > 0 || res.rewardContact > 0 }; }, // 深空巡航:发放实时玩法奖励(v0.6) grantCruiseReward: (rewards)=>{ const s = get(); const addCrystals = rewards.crystals ?? 0; const addInsights = rewards.insights ?? 0; const addContact = rewards.contact ?? 0; // v0.7 角色属性:巡航通关给探索力+勇气经验(按晶体奖励量缩放) const totalReward = addCrystals + addInsights * 10 + addContact * 10; const expBase = Math.max(2, Math.floor(totalReward / 30)); const curAttrs = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); const curProg = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); const explLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: curProg.exploration.exp + expBase, level: curAttrs.exploration }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const courageLvl = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: curProg.courage.exp + Math.floor(expBase * 0.6), level: curAttrs.courage }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const newAttributes = { ...curAttrs, exploration: explLvl.newProgress.level, courage: courageLvl.newProgress.level }; const newProgress = { ...curProg, exploration: explLvl.newProgress, courage: courageLvl.newProgress }; set({ crystals: Math.min(s.crystalCap, s.crystals + addCrystals), insights: s.insights + Math.round(addInsights), contact: Math.min(100, s.contact + addContact), attributes: newAttributes, attributeProgress: newProgress, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); }, // ============ 角色属性系统(v0.7 P1) ============ allocateAttribute: (attr, points = 1)=>{ const s = get(); const cur = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); const curVal = cur[attr] ?? 0; if (curVal >= __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]) { return { ok: false, leveledUp: 0 }; } if ((s.pendingAttrPoints ?? 0) < points) { return { ok: false, leveledUp: 0 }; } const alloc = Math.min(points, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"] - curVal, s.pendingAttrPoints); const newVal = curVal + alloc; const newAttributes = { ...cur, [attr]: newVal }; // 同步经验进度 level 字段(保持一致) const curProg = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); const oldProg = curProg[attr] ?? { exp: 0, level: curVal }; const newProgress = { ...curProg, [attr]: { exp: oldProg.exp, level: newVal } }; set({ attributes: newAttributes, attributeProgress: newProgress, pendingAttrPoints: s.pendingAttrPoints - alloc, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); return { ok: true, leveledUp: alloc }; }, gainAttributeExp: (attr, amount)=>{ const s = get(); const cur = s.attributes ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributes"])(); const curProg = s.attributeProgress ?? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialAttributeProgress"])(); const progEntry = curProg[attr] ?? { exp: 0, level: cur[attr] }; const result = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["levelUpCheck"])({ exp: progEntry.exp + amount, level: cur[attr] }, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$attributes$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["ATTRIBUTE_HARD_CAP"]); const newAttributes = { ...cur, [attr]: result.newProgress.level }; const newProgress = { ...curProg, [attr]: result.newProgress }; set({ attributes: newAttributes, attributeProgress: newProgress, ...syncStats({ tech: s.tech, blueprints: s.blueprints, achievements: s.achievements, activeTide: s.activeTide, constellation: s.constellation, attributes: newAttributes }) }); return { leveledUp: result.levelsGained, newLevel: result.newProgress.level }; } }), { name: "echo-nexus-save-v2", version: 2, storage: (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$zustand$2f$esm$2f$middleware$2e$mjs__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createJSONStorage"])(()=>localStorage), // v0.12 存档迁移:旧存档(v0/v1,key=echo-nexus-save-v1)补全新增字段,防崩溃 migrate: (persistedState, version)=>{ void version; // v0/v1 统一走合并迁移,无需分支 const s = persistedState || {}; const base = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$engine$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["createInitialState"])(); // 合并:以当前 INITIAL_STATE 为基底,旧存档字段覆盖,缺失字段用默认值 const migrated = { ...base, ...s, // v0.8+ 新增字段兜底 bossKills: s.bossKills ?? 0, starTidesEncountered: s.starTidesEncountered ?? [], chronicle: s.chronicle ?? [], runStart: s.runStart ?? Date.now(), // v0.8.2 attributes 系统 attributes: s.attributes ?? base.attributes, attributeProgress: s.attributeProgress ?? base.attributeProgress, pendingAttrPoints: s.pendingAttrPoints ?? 0, // v0.10 探险系统字段兜底 activeExpedition: s.activeExpedition ?? null, totalExpeditions: s.totalExpeditions ?? 0, lastExpeditionSummary: s.lastExpeditionSummary ?? null, // 星图兜底 constellation: s.constellation ?? [], pendingPerkChoices: s.pendingPerkChoices ?? [], // 技术树/碎片/成就兜底(防旧存档为 undefined) tech: s.tech ?? {}, fragments: s.fragments ?? {}, achievements: s.achievements ?? {} }; // 丢弃不可解的活跃谜题(旧算法生成) if (migrated.activePuzzle && typeof migrated.activePuzzle === "object") { const p = migrated.activePuzzle; if (!p.nodes || !Array.isArray(p.nodes) || p.nodes.length === 0) { migrated.activePuzzle = null; } } return migrated; }, // 不持久化临时字段 partialize: (s)=>{ const { _lastAutoDecode, _lastSpawn, _combo, _lastPulse, _achievementQueue, _tideEvents, globalTide, ...rest } = s; void _lastAutoDecode; void _lastSpawn; void _combo; void _lastPulse; void _achievementQueue; void _tideEvents; void globalTide; return rest; } })); function nextFragmentThreshold(totalDecoded) { for (const f of __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["FRAGMENTS"]){ if (totalDecoded < f.threshold) return f.threshold; } return null; } ; // 开发期调试:暴露 store 到 window,便于 QA 测试 if ("TURBOPACK compile-time truthy", 1) { window.__gameStore = useGameStore; } if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) { __turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$); } }), "[project]/src/hooks/useAudio.ts [app-client] (ecmascript)", ((__turbopack_context__) => { "use strict"; __turbopack_context__.s([ "sfx", ()=>sfx, "useAudioSync", ()=>useAudioSync ]); // 回响星核 / Echo Nexus — 音频 React 适配 var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/compiled/react/index.js [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$audio$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/audio.ts [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/src/store/gameStore.ts [app-client] (ecmascript) "); var _s = __turbopack_context__.k.signature(); "use client"; ; ; ; function useAudioSync() { _s(); const soundOn = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useAudioSync.useGameStore[soundOn]": (s)=>s.soundOn }["useAudioSync.useGameStore[soundOn]"]); (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({ "useAudioSync.useEffect": ()=>{ (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$audio$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAudio"])().setEnabled(soundOn); } }["useAudioSync.useEffect"], [ soundOn ]); } _s(useAudioSync, "ZDNYY6yOyIKdqEM3NI9qVh7+PYk=", false, function() { return [ __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"] ]; }); function sfx(name, opts) { (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$audio$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["getAudio"])().play(name, opts); } if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) { __turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$); } }), "[project]/src/hooks/useGameLoop.ts [app-client] (ecmascript)", ((__turbopack_context__) => { "use strict"; __turbopack_context__.s([ "useGameLoop", ()=>useGameLoop ]); // 回响星核 / Echo Nexus — 主循环 hook var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/compiled/react/index.js [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/src/store/gameStore.ts [app-client] (ecmascript) "); var _s = __turbopack_context__.k.signature(); "use client"; ; ; function useGameLoop() { _s(); const tick = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGameLoop.useGameStore[tick]": (s)=>s.tick }["useGameLoop.useGameStore[tick]"]); const autoDecodeTick = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGameLoop.useGameStore[autoDecodeTick]": (s)=>s.autoDecodeTick }["useGameLoop.useGameStore[autoDecodeTick]"]); const tickTide = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGameLoop.useGameStore[tickTide]": (s)=>s.tickTide }["useGameLoop.useGameStore[tickTide]"]); const checkAchievements = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGameLoop.useGameStore[checkAchievements]": (s)=>s.checkAchievements }["useGameLoop.useGameStore[checkAchievements]"]); const init = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGameLoop.useGameStore[init]": (s)=>s.init }["useGameLoop.useGameStore[init]"]); const inited = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(false); (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({ "useGameLoop.useEffect": ()=>{ // 等待 persist rehydrate 完成后再 init(v0.5.2 修复离线收益不弹窗 BUG) // Zustand persist 即使用同步 localStorage,rehydrate 也是异步(Promise.resolve 包装) const doInit = { "useGameLoop.useEffect.doInit": ()=>{ if (!inited.current) { init(); inited.current = true; } } }["useGameLoop.useEffect.doInit"]; let unsub = null; let fallback = null; if (__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"].persist.hasHydrated()) { doInit(); } else { unsub = __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"].persist.onFinishHydration(doInit); // 兜底:500ms 后强制 init(防止 hydrated 状态异常) fallback = setTimeout(doInit, 500); } let counter = 0; const id = setInterval({ "useGameLoop.useEffect.id": ()=>{ const now = Date.now(); tick(now); autoDecodeTick(); // 星潮检测每 tick 都查(结束/触发判定需及时) tickTide(now); counter++; // 成就检测每秒执行一次(降低开销) if (counter % 4 === 0) { checkAchievements(); } } }["useGameLoop.useEffect.id"], 250); return ({ "useGameLoop.useEffect": ()=>{ clearInterval(id); if (unsub) unsub(); if (fallback) clearTimeout(fallback); } })["useGameLoop.useEffect"]; } }["useGameLoop.useEffect"], [ tick, autoDecodeTick, tickTide, checkAchievements, init ]); // 页面可见性:切回时补 tick + 星潮 + 成就 (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({ "useGameLoop.useEffect": ()=>{ const onVis = { "useGameLoop.useEffect.onVis": ()=>{ if (document.visibilityState === "visible") { tick(Date.now()); tickTide(Date.now()); checkAchievements(); } } }["useGameLoop.useEffect.onVis"]; document.addEventListener("visibilitychange", onVis); return ({ "useGameLoop.useEffect": ()=>document.removeEventListener("visibilitychange", onVis) })["useGameLoop.useEffect"]; } }["useGameLoop.useEffect"], [ tick, tickTide, checkAchievements ]); } _s(useGameLoop, "tLDT5k02T5AHn62KJSomBcU8OZw=", false, function() { return [ __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"], __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"], __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"], __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"], __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"] ]; }); if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) { __turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$); } }), "[project]/src/hooks/useGlobalTide.ts [app-client] (ecmascript)", ((__turbopack_context__) => { "use strict"; __turbopack_context__.s([ "adminTriggerGlobalTide", ()=>adminTriggerGlobalTide, "useGlobalTide", ()=>useGlobalTide ]); var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$build$2f$polyfills$2f$process$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = /*#__PURE__*/ __turbopack_context__.i("[project]/node_modules/next/dist/build/polyfills/process.js [app-client] (ecmascript)"); // 回响星核 / Echo Nexus — 全球星潮同步 hook(P3 / 工单 #10-c) // // 连接 star-tide-service(端口 3031),监听全球星潮事件: // - `tide-state` 连接时立即推送当前状态 // - `global-tide` 全球星潮开始 → 调用 gameStore.triggerGlobalTide(type) // - `tide-ended` 全球星潮结束(本地 tickTide 也会在 60s 后自动收尾,这是双保险) // // 网关:socket.io 必须用 `io("/?XTransformPort=3031")`,path 默认 "/" // 离线容错:socket.io 默认自动重连;断连期间本地 tickTide 继续工作 var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/compiled/react/index.js [app-client] (ecmascript)"); var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$socket$2e$io$2d$client$2f$build$2f$esm$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/node_modules/socket.io-client/build/esm/index.js [app-client] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/src/store/gameStore.ts [app-client] (ecmascript) "); var _s = __turbopack_context__.k.signature(); "use client"; ; ; ; /** 单例 socket —— 多次挂载 hook 共享同一连接 */ let sharedSocket = null; let connectRefCount = 0; function getSharedSocket() { if (!sharedSocket) { sharedSocket = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$socket$2e$io$2d$client$2f$build$2f$esm$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["io"])("/?XTransformPort=3031", { transports: [ "websocket", "polling" ], reconnection: true, reconnectionAttempts: Infinity, reconnectionDelay: 1000, reconnectionDelayMax: 10_000, timeout: 10_000 }); } return sharedSocket; } function useGlobalTide() { _s(); const triggerGlobalTide = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"])({ "useGlobalTide.useGameStore[triggerGlobalTide]": (s)=>s.triggerGlobalTide }["useGlobalTide.useGameStore[triggerGlobalTide]"]); // 用 ref 缓存最新 action,避免 socket 监听器依赖变化导致重绑 const triggerRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(triggerGlobalTide); (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({ "useGlobalTide.useEffect": ()=>{ triggerRef.current = triggerGlobalTide; } }["useGlobalTide.useEffect"], [ triggerGlobalTide ]); // 记录已处理过的 global-tide 事件 id(避免重连时重复触发) const processedIds = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(new Set()); (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({ "useGlobalTide.useEffect": ()=>{ const sock = getSharedSocket(); connectRefCount += 1; const onGlobalTide = { "useGlobalTide.useEffect.onGlobalTide": (tide)=>{ // 用 startedAt+type 作为去重 key(同一道全球星潮可能在重连后被重复推送) const key = `${tide.startedAt}_${tide.type}`; if (processedIds.current.has(key)) return; processedIds.current.add(key); // 限制集合大小 if (processedIds.current.size > 32) { const first = processedIds.current.values().next().value; if (first) processedIds.current.delete(first); } // 防御:如果服务端推送的星潮已经过期(例如重连时拿到的旧状态),不触发 if (tide.endsAt <= Date.now()) return; triggerRef.current(tide.type); } }["useGlobalTide.useEffect.onGlobalTide"]; const onTideState = { "useGlobalTide.useEffect.onTideState": (state)=>{ // 连接/重连时若服务端正有进行中的全球星潮,且本地还没触发过,补触发 if (state.current && state.current.endsAt > Date.now()) { const key = `${state.current.startedAt}_${state.current.type}`; if (!processedIds.current.has(key)) { processedIds.current.add(key); triggerRef.current(state.current.type); } } } }["useGlobalTide.useEffect.onTideState"]; sock.on("global-tide", onGlobalTide); sock.on("tide-state", onTideState); // 主动查询一次当前状态(保险,防止错过连接时的初始推送) sock.emit("get-next-tide"); return ({ "useGlobalTide.useEffect": ()=>{ sock.off("global-tide", onGlobalTide); sock.off("tide-state", onTideState); connectRefCount -= 1; // 最后一个使用者退出时才真正断开 if (connectRefCount <= 0 && sharedSocket) { sharedSocket.disconnect(); sharedSocket = null; connectRefCount = 0; } } })["useGlobalTide.useEffect"]; } }["useGlobalTide.useEffect"], []); } _s(useGlobalTide, "06te8jY+CFt5X79ydMcCUfRcDD8=", false, function() { return [ __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"] ]; }); function adminTriggerGlobalTide() { if (!sharedSocket) { // 还没连接则先建立 getSharedSocket(); } sharedSocket?.emit("admin-trigger-tide"); } if ("TURBOPACK compile-time truthy", 1) { window.__adminTriggerGlobalTide = adminTriggerGlobalTide; } if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) { __turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$); } }), ]); //# sourceMappingURL=src_f0d25b4c._.js.map