v0.8.1: 探险平衡 + 信标系统扩展(周挑战 + 信标链)
P1-a 探险 BOSS 胜率平衡 + 能量恢复(expedition.ts + config.ts + gameStore.ts + ExpeditionPanel.tsx): - combatWinRate: scale 8→4, floor 0.25→0.35(基础力10对BOSS胜率 25%→35-45%) - BOSS 难度 5-7→3-5(配合新公式基础胜率达 45-55%) - computeEnergyRegenInterval(state): 动态恢复间隔 - exp_2 解锁 -30%, exp_3 解锁 -20%, 探索力属性 -最高30% - 下限 12s(原固定 45s) - computeEnergyRegen 接受 intervalSec 参数 - gameStore tick 传入动态间隔 - config.ts: exp_2/exp_3 描述加'能量恢复 +30%/+20%' - ExpeditionPanel: 显示实际恢复速度 + '已加速'标记 P1-b 信标系统扩展(beacon.ts + BeaconPanel.tsx + gameStore.ts)[subagent 9-b]: - 周挑战: getWeekKey ISO 8601 + FNV-1a 种子确定性生成 - 难度强制 anomaly 60%/singular 40%, goal 日挑战×3-5倍 - 完整进度/领奖/排行榜推送(isWeekly标记) - 信标链: 4里程碑(3/7/14/30天) + grace续命机制(每链1次) - recordChainCompletion 核心断链/续命逻辑 - 奖励 50→680洞见递增 - BeaconPanel: 周挑战fuchsia主题 + 信标链amber→rose渐变里程碑节点 - gameStore: trackBeacon升级 + claimWeeklyBeacon/claimChainReward actions - VLM 8/10, lint零错误, 5场景bun测试全PASS
This commit is contained in:
@@ -35,10 +35,14 @@ export const EXPEDITION_CONFIG = {
|
||||
baseHp: 100,
|
||||
/** 探险力基础 */
|
||||
basePower: 10,
|
||||
/** 战斗:胜率 = clamp(power / (power + difficulty*8), 0.25, 0.95) */
|
||||
combatDifficultyScale: 8,
|
||||
/** 能量恢复间隔(秒),每 interval 恢复 1 点 */
|
||||
/** 战斗:胜率 = clamp(power / (power + difficulty*scale), floor, 0.95)
|
||||
* v0.8.1 平衡:scale 8→4,floor 0.25→0.35,让基础探险力也能有合理胜率 */
|
||||
combatDifficultyScale: 4,
|
||||
combatWinRateFloor: 0.35,
|
||||
/** 能量恢复基础间隔(秒),可被技术/属性缩短 */
|
||||
energyRegenSec: 45,
|
||||
/** 能量恢复最短间隔(秒,技术+属性全满时) */
|
||||
energyRegenMinSec: 12,
|
||||
};
|
||||
|
||||
/** 节点类型权重(boss 固定末位,其余按权重随机) */
|
||||
@@ -147,7 +151,7 @@ export function generateExpedition(
|
||||
title: flavor.titles[fi],
|
||||
desc: flavor.descs[fi],
|
||||
cleared: false,
|
||||
difficulty: isBoss ? 5 + Math.floor(rng() * 3) : 1 + Math.floor(rng() * 4),
|
||||
difficulty: isBoss ? 3 + Math.floor(rng() * 3) : 1 + Math.floor(rng() * 4),
|
||||
position: i,
|
||||
});
|
||||
}
|
||||
@@ -203,10 +207,13 @@ export function computeExpeditionHp(state: GameState): number {
|
||||
return hp;
|
||||
}
|
||||
|
||||
/** 战斗胜率 */
|
||||
/** 战斗胜率
|
||||
* v0.8.1 平衡:scale 4 + floor 0.35,让基础探险力 10 对 BOSS(diff 3-5) 有 33-45% 胜率,
|
||||
* 配合技术/属性后可达 55-70%,告别"BOSS 必败"体验 */
|
||||
export function combatWinRate(power: number, difficulty: number): number {
|
||||
const scale = EXPEDITION_CONFIG.combatDifficultyScale;
|
||||
return Math.max(0.25, Math.min(0.95, power / (power + difficulty * scale)));
|
||||
const floor = EXPEDITION_CONFIG.combatWinRateFloor;
|
||||
return Math.max(floor, Math.min(0.95, power / (power + difficulty * scale)));
|
||||
}
|
||||
|
||||
/** 结算当前节点(自动结算,返回结果与日志) */
|
||||
@@ -358,14 +365,32 @@ export function advanceExpedition(expedition: Expedition): ExpeditionResult {
|
||||
return { log: `前进至节点 ${expedition.currentNode + 1}`, ended: false };
|
||||
}
|
||||
|
||||
/** 计算能量恢复(基于时间) */
|
||||
/** 计算实际能量恢复间隔(秒),由技术树 + 角色属性缩短
|
||||
* v0.8.1:exp_2 解锁 -30%,exp_3 解锁 -20%,探索力属性 -最高30%,下限 12s */
|
||||
export function computeEnergyRegenInterval(state: GameState): number {
|
||||
const base = EXPEDITION_CONFIG.energyRegenSec;
|
||||
let mult = 1;
|
||||
// 技术:遗迹图谱(exp_2)+ 维度信标(exp_3)
|
||||
if (state.tech?.exp_2) mult *= 0.7;
|
||||
if (state.tech?.exp_3) mult *= 0.8;
|
||||
// 角色属性:探索力(exploration)每点缩短少量,高探索力最高 -30%
|
||||
const exploration = state.attributes?.exploration ?? 0;
|
||||
const explorationBonus = exploration >= 50
|
||||
? 0.15 + (Math.min(100, exploration) - 50) * 0.003 // 50点15%,100点30%
|
||||
: exploration * 0.003;
|
||||
mult *= 1 - explorationBonus;
|
||||
return Math.max(EXPEDITION_CONFIG.energyRegenMinSec, base * mult);
|
||||
}
|
||||
|
||||
/** 计算能量恢复(基于时间,支持动态间隔) */
|
||||
export function computeEnergyRegen(
|
||||
lastTick: number,
|
||||
now: number,
|
||||
current: number,
|
||||
max: number
|
||||
max: number,
|
||||
intervalSec: number = EXPEDITION_CONFIG.energyRegenSec
|
||||
): { energy: number; lastTick: number } {
|
||||
const interval = EXPEDITION_CONFIG.energyRegenSec * 1000;
|
||||
const interval = intervalSec * 1000;
|
||||
const elapsed = now - lastTick;
|
||||
const gained = Math.floor(elapsed / interval);
|
||||
if (gained <= 0) return { energy: current, lastTick };
|
||||
|
||||
Reference in New Issue
Block a user