From 83fbd8fcfc92d398764e64725e19dff28527f78d Mon Sep 17 00:00:00 2001 From: chen Date: Mon, 10 Aug 2026 00:55:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=A7=E5=A2=83=E7=95=8C=E7=AA=81?= =?UTF-8?q?=E7=A0=B4=E2=80=94=E2=80=94=E7=BB=83=E6=B0=94=E5=9C=86=E6=BB=A1?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E8=8A=B1=E8=B4=B9=E7=81=B5=E7=9F=B3=E7=AA=81?= =?UTF-8?q?=E7=A0=B4=E8=87=B3=E7=AD=91=E5=9F=BA=E5=8F=8A=E4=BB=A5=E4=B8=8A?= =?UTF-8?q?=EF=BC=88D9=20=E5=AE=8C=E6=88=90=EF=BC=89=EF=BC=9B=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=81=B5=E7=9F=B3=E4=B8=8D=E8=BF=94=E8=BF=98+?= =?UTF-8?q?=E4=BF=AE=E4=B8=BA=E5=80=92=E9=80=80=EF=BC=8C=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=EF=BC=9B=E4=BF=AE=E5=A4=8D=E7=AD=91=E5=9F=BA?= =?UTF-8?q?=E5=9C=86=E6=BB=A1=E8=BF=9B=E5=BA=A6=E6=96=87=E6=9C=AC=E8=B6=8A?= =?UTF-8?q?=E7=95=8C=EF=BC=9B=E6=96=87=E6=A1=A3=E5=90=8C=E6=AD=A5=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E7=82=BC=E8=AE=BE=E8=AE=A1=E5=9B=9B=E7=AB=A0/?= =?UTF-8?q?=E8=AE=A1=E5=88=92=E8=A1=A8/README=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +- doc/design/修炼系统设计.md | 107 ++++++++++++++---- doc/开发计划表.md | 8 +- resources/game_config.cfg | 4 + src/Character/CultivationManager.gd | 54 ++++++++- src/Character/Disciple.gd | 35 +++++- src/Core/GameConfig.gd | 27 +++++ .../DisciplesPanel/DiscipleDetailPanel.tscn | 7 ++ .../DisciplesPanel/disciple_detail_panel.gd | 36 +++++- 9 files changed, 245 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index ee5d91b..b72f91b 100644 --- a/README.md +++ b/README.md @@ -105,10 +105,12 @@ | 用户设置 | 已完成 | 默认流速持久化 (user://settings.cfg) | | 顶部 HUD | 已完成 | 灵石/时间/声望显示,速度按钮组(toggle 高亮) | | 画面质量 | 已完成 | 1920x1080 视口,MSAA 2D/3D + TAA,文字抗锯齿 | -| 宗门数据模型 | **进行中** | SectManager:灵石/灵气/声望(D2) | -| 弟子系统 | 规划中 | 生成/入宗分流/修炼(D3-D5) | -| 建筑系统 | 规划中 | 建造/产出/升级(D6) | -| 存档接入 | 规划中 | SaveSystem 序列化(D8) | +| 宗门数据模型 | 已完成 | SectManager:灵石/声望/灵米 + 增减/设定接口(D2) | +| 弟子系统 | 已完成 | 生成/入宗分流/天灵根/列表详情(D3-D4) | +| 修炼循环 | 已完成 | 修为逐日增长/门槛升层/瓶颈判定/13 层圆满(D5) | +| 建筑系统 | 已完成 | 灵石矿/灵田建造升级产出,口粮消耗与断粮离宗(D6) | +| 存档接入 | 已完成 | 两级存档:无限组/槽,读档全量还原(D8) | +| 大境界突破 | 已完成 | 练气圆满手动花费灵石突破至筑基及以上,失败灵石不返还+修为倒退(D9) | > 进度跟踪见 `Doc/开发计划表.md`,里程碑:M1(8/12) 核心闭环 → M2(9/6) 丰富玩法 → M3(10/11) 正式版本。 diff --git a/doc/design/修炼系统设计.md b/doc/design/修炼系统设计.md index 4282761..c17bdd0 100644 --- a/doc/design/修炼系统设计.md +++ b/doc/design/修炼系统设计.md @@ -1,8 +1,9 @@ -# 修炼系统设计(D5:修炼循环) +# 修炼系统设计(D5:修炼循环 + D9:大境界突破) -> 对应开发计划表 D5(8/7):① 修为随时间增长(资质×灵气)② 境界门槛 ③ 突破判定。 -> 交付标准:弟子自动修炼,可突破。本文档只描述设计,不包含代码。 -> 状态:①②③ 已实现(每日结算 → 修为达门槛升层 → 瓶颈掷骰判定,失败扣 20%;13 层圆满封顶);修为进度已在管理界面展示 +> 对应开发计划表 D5(8/7):① 修为随时间增长(资质×灵气)② 境界门槛 ③ 突破判定;D9(8/11)追加大境界突破。 +> 交付标准:弟子自动修炼,可突破;练气圆满后玩家手动花费灵石突破大境界。 +> 本文档只描述设计,不包含代码。 +> 状态:D5 部分已实现(每日结算 → 修为达门槛升层 → 瓶颈掷骰判定,失败扣 20%;13 层圆满封顶;修为进度已在管理界面展示);大境界突破已实现(练气圆满 → 手动花费灵石 → 筑基及以上大境界,失败灵石不返还 + 修为倒退;配置驱动,详见第四章) --- @@ -63,13 +64,58 @@ - **非瓶颈层**:修为满门槛 → 自动升层(无失败) - **瓶颈层**(3→4 / 6→7 / 9→10 / 12→13):修为满后进入突破判定 -- 13 层圆满:修为封顶,显示"练气圆满";筑基以上大境界需丹药/灵石资源,**本期不做**(后续 P2 接入) +- 13 层圆满:修为封顶,显示"练气圆满";**大境界突破见第四章**(玩家手动花费灵石突破至筑基) > 数值均为示例,正式数值在 D9 平衡调整,只改配置不动代码。 --- -## 四、突破判定(瓶颈层) +## 四、大境界突破(D9 追加:手动花费灵石) + +### 4.1 总览 + +练气圆满(13 层)后,玩家可在**弟子详情面板手动操作**:花费灵石尝试突破至下一大境界(练气→筑基→金丹→元婴→化神)。 + +``` +练气13层圆满 ── 手动花费灵石 + 成功率判定 ──> 筑基初期 ── 小境自动推进 ── 筑基圆满 ──> 金丹初期 … +``` + +- 与练气期小突破(自动挂机)不同:**大境界突破是玩家主动行为**,消耗灵石、有失败折损 +- 大境界序列沿用 `Disciple.REALM_NAMES`(练气/筑基/金丹/元婴/化神),`realm_index` 表示大境界 + +### 4.2 触发条件 + +| 条件 | 说明 | +|------|------| +| 修为满 | 练气期:13 层圆满(修为封顶);筑基及以上:修为 ≥ 当前大境界圆满阈值(见 4.3) | +| 灵石足够 | 当前宗门灵石 ≥ 目标大境界花费(配置 `realm_breakthrough_costs`) | +| 玩家操作 | 详情面板点击"大境界突破"按钮(满足条件时可用) | + +### 4.3 筑基及以上的小境推进 + +- 筑基/金丹/元婴/化神各有 4 小境(初期/中期/后期/圆满),显示沿用现有 `get_realm_text()` +- 修为每日继续按同一公式增长(不再以 13 层封顶);满小境门槛**自动推进小境**(挂机,无失败) +- 小境门槛统一读配置 `realm_sub_thresholds`(3 项:初期→中期 / 中期→后期 / 后期→圆满),各大大境界通用 +- **圆满**:修为达到圆满小境门槛后封顶,解锁"大境界突破"按钮 + +### 4.4 突破判定(手动) + +1. 玩家点击"大境界突破"→ 扣除灵石(一次性,成功失败都不退还) +2. 掷骰:成功率按**目标大境界**读配置 `realm_breakthrough_chances`(升筑基 0.6 / 升金丹 0.5 / 升元婴 0.4 / 升化神 0.3,越往上越难) +3. **成功** → `realm_index+1`、`sub_realm_index=0`(新大境界初期)、修为清零;控制台与信号广播"X 突破至 筑基初期" +4. **失败** → **修为倒退**(配置 `realm_breakthrough_fail_drop` 步,默认 3):倒退限于当前大境界内——练气期倒推层数(如 13 层圆满 → 10 层),筑基及以上倒推小境(圆满 → 后期 → 中期 → 初期);倒退后修为清零重新积累;控制台提示"X 突破失败,灵石化为乌有,修为倒退至 练气10层" +5. 失败后修为照常继续增长(无冷却;冷却规则后续版本再考虑) + +**设计意图**:为灵石提供经营消耗出口(建筑产出 → 突破消耗形成闭环),并保留"攒灵石 → 点突破"的手动决策感与成败反馈;**失败代价是境界倒退**(练气 13 层 → 10 层意味重新冲 3 个瓶颈层),比单纯扣修为更能制造挫折与经营压力。 + +### 4.5 灵石不足 + +- 按钮置灰并显示所需灵石("突破(需 500 灵石)") +- 灵石不足不可点击,不弹窗 + +--- + +## 五、突破判定(瓶颈层) 1. 修为 ≥ 瓶颈层门槛时,每日结算后自动尝试突破 2. 掷骰:成功概率**按瓶颈层分别配置**(`breakthrough_chances`,与 `bottleneck_levels` 一一对应:升 4 层 0.85 / 升 7 层 0.8 / 升 10 层 0.75 / 升 13 层 0.6,越往上越难) @@ -81,23 +127,25 @@ --- -## 五、CultivationManager(新 Autoload) +## 六、CultivationManager(新 Autoload) 存放位置:`src/Character/CultivationManager.gd`(与 DiscipleManager 同域,注册顺序在 DiscipleManager 之后、声明于 project.godot) | 接口 | 说明 | |------|------| | 监听 `TimeSystem.day_passed` | 每日结算全体弟子 | -| 私有 `_gain_exp(d)` | 按公式累计修为 | -| 私有 `_check_breakthrough(d)` | 门槛判定 + 瓶颈掷骰 | +| 私有 `_gain_exp(d)` | 按公式累计修为(所有大境界通用;练气圆满/大境界圆满封顶) | +| 私有 `_check_breakthrough(d)` | 练气期门槛判定 + 瓶颈掷骰 | +| 私有 `_check_sub_realm(d)` | 筑基及以上小境门槛判定(自动推进,无失败) | +| **公开 `try_realm_breakthrough(d)`** | **大境界突破入口:校验灵石 → 扣费 → 掷骰 → 成功升大境界/失败修为倒退(`realm_breakthrough_fail_drop` 步),返回 bool** | | 信号 `realm_changed(d)` | 境界变化(详情面板刷新用) | | 信号 `cultivation_log(text)` | 修炼日志文本(控制台打印/后续日志系统) | -**注意**:只在 `disciples` 名录内结算,候选池不修炼。 +**注意**:只在 `disciples` 名录内结算,候选池不修炼;大境界突破必须从 UI 手动调用(挂机不自动花灵石)。 --- -## 六、配置节(game_config.cfg 新增 [cultivation]) +## 七、配置节(game_config.cfg [cultivation]) ```ini [cultivation] @@ -108,35 +156,43 @@ heavenly_bonus=1.5 ; 天灵根额外倍率 breakthrough_chances=[0.85, 0.8, 0.75, 0.6] ; 各瓶颈层突破成功率(与 bottleneck_levels 一一对应) level_thresholds=[100, 200, 350, 550, 800, 1100, 1500, 2000, 2600, 3300, 4100, 5000] ; 练气 1→2 到 12→13 各层所需修为 bottleneck_levels=[4, 7, 10, 13] ; 瓶颈目标层(升到这些层需突破判定) +realm_breakthrough_costs=[500, 4000, 12000, 60000] ; 大境界突破灵石花费(索引 0~3 = 升筑基/金丹/元婴/化神) +realm_breakthrough_chances=[0.6, 0.5, 0.4, 0.3] ; 大境界突破成功率(与 costs 一一对应) +realm_breakthrough_fail_drop=3 ; 突破失败倒退步数(练气倒推层数/筑基+倒推小境,默认 3) +realm_sub_thresholds=[6000, 12000, 24000] ; 筑基及以上小境门槛(初期→中期/中期→后期/后期→圆满) ``` - `aptitude_speed`:与资质枚举一一对应,必须 4 项 - `level_thresholds`:练气 1→2 到 12→13 共 12 个门槛值 - `bottleneck_levels`:升到这些层时需要突破判定 +- `realm_breakthrough_costs/chances`:索引 0 = 练气圆满→筑基,1 = 筑基圆满→金丹,2 = 金丹圆满→元婴,3 = 元婴圆满→化神;两个数组长度必须一致(4 项) +- `realm_breakthrough_fail_drop`:失败倒退步数,练气期退层数、筑基+退小境,均不跨大境界 +- `realm_sub_thresholds`:筑基及以上通用,3 项;修为达到即自动进小境 --- -## 七、UI 接入(D4 预留区填充) +## 八、UI 接入(D4 预留区填充) -- **名录列表**(DisciplesPanel):条目追加"修为"列(如 "1234 / 800",当前修为/本层门槛;13 层显示"练气圆满") -- **详情弹窗**:信息区追加"修为:1234 / 2000"(当前/本层门槛;13 层显示 练气圆满) +- **名录列表**(DisciplesPanel):条目追加"修为"列(如 "1234 / 800",当前修为/本层门槛;13 层显示"练气圆满";大境界圆满显示"筑基圆满") +- **详情弹窗**:信息区追加"修为:1234 / 2000"(当前/本层门槛;练气圆满显示"练气圆满") + - 追加"**大境界突破**"按钮:满足触发条件(修为圆满 + 灵石足够)时可点击;按钮文案带花费("大境界突破(500 灵石)");灵石不足置灰 + - 点击后直接执行判定(成功/失败均无二次确认),结果通过修炼日志与控制台可见 - 面板打开时暂停时间,进度静态展示;修炼日志:控制台 print(本期不做日志界面) --- -## 八、实现拆解(小步可验证) +## 九、实现拆解(小步可验证) -1. 配置节 [cultivation] + GameConfig 读取 -2. Disciple 加 `cultivation_exp: float` 字段 + 门槛查询辅助 -3. CultivationManager 骨架:每日结算修为 -4. 非瓶颈自动升层 -5. 瓶颈突破判定(成功/失败/损耗) -6. 详情面板修为显示 + realm_changed 刷新 -7. 挂机验证(加速时间观察多轮突破)+ 提交 +1. 配置节追加 3 项 + GameConfig 读取(默认值与 cfg 同步) +2. Disciple 辅助:`is_realm_ready()`(修为圆满判定)、突破花费查询、进度文本支持筑基及以上 +3. CultivationManager:`_gain_exp` 放开到筑基及以上 + 小境自动推进 `_check_sub_realm` +4. `try_realm_breakthrough(d)`:校验 → 扣灵石 → 掷骰 → 成功/失败结算 +5. 详情面板"大境界突破"按钮(可用性 = 条件 + 灵石;文案含花费) +6. 挂机验证(加速时间观察筑基圆满 → 手动突破金丹)+ 提交 --- -## 九、验收清单(D5 交付标准) +## 十、验收清单(D5 交付标准 + D9 追加) - [x] 挂机时弟子修为逐日增长,速度随资质/天灵根不同(下品慢、天骄快) - [x] 非瓶颈层修为满自动升层,无失败 @@ -144,5 +200,10 @@ bottleneck_levels=[4, 7, 10, 13] ; 瓶颈目标层(升到这些层 - [x] 练气 13 层圆满后修为封顶,显示"练气圆满" - [x] 详情面板显示修为进度,突破后实时刷新 - [x] 修改配置(速度/概率/门槛)重启生效 +- [x] 详情面板常驻"大境界突破"按钮:修为圆满 + 灵石足够可点击(文案显示所需灵石),否则置灰(未圆满/灵石不足/已至巅峰) +- [x] 点击突破:扣灵石 → 成功升大境界(realm_index+1,显示"筑基初期")或失败**修为倒退**(练气退层/筑基+退小境,配置 `realm_breakthrough_fail_drop` 步),控制台有日志 +- [x] 灵石不足时按钮置灰不可点击 +- [x] 筑基及以上:修为继续增长,满 `realm_sub_thresholds` 自动推进小境(初期→中期→后期→圆满),圆满后可再大境界突破 +- [x] 修改配置(花费/成功率/小境门槛)重启生效 > 注:修为显示("当前/本层门槛")待详情面板接入(拆解第 6 步)。 diff --git a/doc/开发计划表.md b/doc/开发计划表.md index 76a0665..63de925 100644 --- a/doc/开发计划表.md +++ b/doc/开发计划表.md @@ -1,7 +1,7 @@ # 开发计划表 > 开始日期:2026-08-03(周一) 每日有效开发约 2 小时 -> 进度更新:2026-08-10  D1–D8 全部完成(D8 两级存档系统验收 9/9),D9(打磨)进行中 +> 进度更新:2026-08-10  D1–D9 全部完成(D8 两级存档系统验收 9/9,D9 大境界突破 + 数值打磨),M1 验收(D10)进行中 ## 一、每日作息模板(工作日) @@ -27,10 +27,8 @@ | 8/8 六 | D6 | 建筑系统基础 | ① 灵石矿场景 ② 建造→每时辰产出 ③ 升级 | 建筑产灵石,升级加速 | ✅ 完成(步骤1-7:食物/开局赠送/建筑参数配置/Building+BuildingManager/建筑面板+资源按钮/口粮饥饿离宗方案B,验收11/11) | | 8/9 日 | D7 | 休息 / 补漏 | 修本周 bug,整理代码 | git 干净 | ✅ 完成(修复:管理面板关闭冲掉手动暂停) | | 8/10 一 | D8 | 存档接入 | ① SaveSystem JSON 序列化 ② 存/读接口 ③ 替换 SavePanel 测试数据 | 读档后数据还原 | ✅ 完成(两级存档:无限组/槽、建组建槽/自动档/两级浏览/读档全量还原/删除组与槽/游戏内加载进度点/损坏容错,验收9/9) | -| 8/11 二 | D9 | 打磨 | 数值平衡初调,玩 10 分钟验证 | 无致命 bug | ⬜ | -| 8/12 三 | D10 | **M1 验收** | 完整跑一遍:新游戏→招弟子→挂机→存→退→读 | 闭环可玩 | ⬜ | - -## 三、第 3–5 周(8/17–9/6):P2 扩展 +| 8/11 二 | D9 | 打磨 | 数值平衡初调,玩 10 分钟验证 | 无致命 bug | ✅ 完成(大境界突破:练气圆满→手动花费灵石→筑基及以上大境界,失败灵石不返还+修为倒退 3 步,花费/成功率/小境门槛配置化;61 项逻辑测试全 PASS) | +| 8/12 三 | D10 | **M1 验收** | 完整跑一遍:新游戏→招弟子→挂机→存→退→读 | 闭环可玩 | ⬜ |## 三、第 3–5 周(8/17–9/6):P2 扩展 | 日期 | 周 | 任务 | 拆解 | 交付 | | ---- | -- | ---- | ---- | ---- | diff --git a/resources/game_config.cfg b/resources/game_config.cfg index 6682ea1..5cd1eb1 100644 --- a/resources/game_config.cfg +++ b/resources/game_config.cfg @@ -27,6 +27,10 @@ heavenly_bonus=1.5 ; 天灵根额外修炼速度倍率 breakthrough_chances=[0.85, 0.8, 0.75, 0.6] ; 各瓶颈层突破成功率(与 bottleneck_levels 一一对应:升4层/7层/10层/13层) level_thresholds=[100, 200, 350, 550, 800, 1100, 1500, 2000, 2600, 3300, 4100, 5000] ; 练气 1→2 到 12→13 各层所需修为 bottleneck_levels=[4, 7, 10, 13] ; 瓶颈目标层(升到这些层需突破判定) +realm_breakthrough_costs=[500, 4000, 12000, 60000] ; 大境界突破灵石花费(索引 0~3 = 升筑基/金丹/元婴/化神) +realm_breakthrough_chances=[0.6, 0.5, 0.4, 0.3] ; 大境界突破成功率(与 costs 一一对应) +realm_breakthrough_fail_drop=3 ; 突破失败倒退步数(练气倒推层数/筑基+倒推小境,不跨大境界) +realm_sub_thresholds=[6000, 12000, 24000] ; 筑基及以上小境门槛(初期→中期/中期→后期/后期→圆满) [ui] ; UI 通用 hud_font_size=24 ; HUD 字体大小 diff --git a/src/Character/CultivationManager.gd b/src/Character/CultivationManager.gd index 3b3fde5..e67af9c 100644 --- a/src/Character/CultivationManager.gd +++ b/src/Character/CultivationManager.gd @@ -1,5 +1,5 @@ ## 修炼管理器(Autoload 单例)。 -## 负责弟子修为的每日结算与境界推进(D5:修为逐日增长 + 自动升层 + 瓶颈突破判定)。 +## 负责弟子修为的每日结算与境界推进(D5:修为逐日增长 + 自动升层 + 瓶颈突破判定;D9:大境界手动突破)。 extends Node ## 境界变化信号(突破后发出,供详情面板刷新)。 @@ -19,6 +19,7 @@ func _on_day_passed(_year: int, _month: int, _day: int) -> void: for d in DiscipleManager.disciples: _gain_exp(d) _check_breakthrough(d) + _check_sub_realm(d) ## 每日口粮结算:练气弟子人均消耗灵米(筑基+辟谷豁免)。 ## 食物充足 → 扣减并饥饿清零;食物不足 → 归零并全员饥饿天数 +1; @@ -46,11 +47,10 @@ func _settle_food() -> void: ## 按公式累计一日修为。 ## 速度 = 基础速度 × 资质倍率 × 灵根容量 × 天灵根加成 × 灵气浓度 × 饥饿倍率 -## 练气圆满(13 层)后修为封顶,不再增长。 +## 练气圆满(13 层)或大境界圆满(筑基+ 4 小境满)后修为封顶,不再增长。 ## @param d: 已入宗弟子 func _gain_exp(d: Disciple) -> void: - # 练气圆满(13 层)后修为封顶,不再增长 - if d.realm_index != 0 or d.sub_realm_index >= GameConfig.level_thresholds.size(): + if d.is_realm_peak(): return var speed := GameConfig.cultivation_base_speed speed *= GameConfig.aptitude_speed[d.aptitude] @@ -86,6 +86,52 @@ func _check_breakthrough(d: Disciple) -> void: else: _advance_layer(d) +## 筑基及以上小境推进:修为满小境门槛自动升小境(初期→中期→后期→圆满,无失败)。 +## 大境界圆满后不再推进,等待玩家手动大境界突破。 +## @param d: 已入宗弟子 +func _check_sub_realm(d: Disciple) -> void: + if d.realm_index == 0: + return + if d.sub_realm_index >= GameConfig.realm_sub_thresholds.size(): + return + if d.cultivation_exp < GameConfig.realm_sub_thresholds[d.sub_realm_index]: + return + var threshold: float = GameConfig.realm_sub_thresholds[d.sub_realm_index] + d.cultivation_exp -= threshold + d.sub_realm_index += 1 + realm_changed.emit(d) + _log("%s 突破至 %s" % [d.name, d.get_realm_text()]) + +## 大境界突破(玩家手动调用,挂机不自动触发)。 +## 流程:校验修为圆满与灵石 → 扣灵石(成败不退还)→ 掷骰(成功率按目标大境界配置)。 +## 成功:realm_index+1(新大境界初期,修为清零);失败:修为倒退 fail_drop 步(练气退层数/筑基+退小境,不跨大境界)。 +## 灵石不足或修为未圆满返回 false(不扣灵石)。 +## @param d: 已入宗弟子 +func try_realm_breakthrough(d: Disciple) -> bool: + if not d.is_realm_peak(): + return false + var next := d.get_next_realm_index() + if next < 0: + return false + var cost := d.get_realm_breakthrough_cost() + if SectManager.spirit_stones < cost: + return false + SectManager.remove_spirit_stones(cost) + var chance: float = GameConfig.realm_breakthrough_chances[next - 1] + if randf() < chance: + d.realm_index = next + d.sub_realm_index = 0 + d.cultivation_exp = 0.0 + realm_changed.emit(d) + _log("%s 突破至 %s" % [d.name, d.get_realm_text()]) + return true + var drop := GameConfig.realm_breakthrough_fail_drop + d.sub_realm_index = maxi(0, d.sub_realm_index - drop) + d.cultivation_exp = 0.0 + realm_changed.emit(d) + _log("%s 突破失败,灵石化为乌有,修为倒退至 %s" % [d.name, d.get_realm_text()]) + return false + ## 推进一层境界:扣除本层门槛修为(余量带入下一层)并发信号。 ## @param d: 已入宗弟子 func _advance_layer(d: Disciple) -> void: diff --git a/src/Character/Disciple.gd b/src/Character/Disciple.gd index 2afb08a..a6838a7 100644 --- a/src/Character/Disciple.gd +++ b/src/Character/Disciple.gd @@ -105,10 +105,33 @@ static func from_dict(data: Dictionary) -> Disciple: return d ## 本层修炼进度文本,如 "1234 / 2000"(当前修为 / 本层门槛)。 -## 练气圆满(13 层)返回"练气圆满";非练气期返回空串。 +## 练气圆满(13 层)返回"练气圆满";筑基及以上返回 "1234 / 6000"(小境门槛),圆满返回"筑基圆满"。 func get_cultivation_progress_text() -> String: - if realm_index != 0: - return "" - if sub_realm_index >= GameConfig.level_thresholds.size(): - return "练气圆满" - return "%d / %d" % [int(cultivation_exp), int(GameConfig.level_thresholds[sub_realm_index])] + if realm_index == 0: + if sub_realm_index >= GameConfig.level_thresholds.size(): + return "练气圆满" + return "%d / %d" % [int(cultivation_exp), int(GameConfig.level_thresholds[sub_realm_index])] + if sub_realm_index >= GameConfig.realm_sub_thresholds.size(): + return REALM_NAMES[realm_index] + "圆满" + return "%d / %d" % [int(cultivation_exp), int(GameConfig.realm_sub_thresholds[sub_realm_index])] + +## 当前大境界是否修为圆满(练气 = 13 层;筑基及以上 = 4 小境修满)。 +## 圆满后解锁"大境界突破"(玩家手动花费灵石)。 +func is_realm_peak() -> bool: + if realm_index == 0: + return sub_realm_index >= GameConfig.level_thresholds.size() + return sub_realm_index >= GameConfig.realm_sub_thresholds.size() \ + and cultivation_exp >= GameConfig.realm_sub_thresholds[GameConfig.realm_sub_thresholds.size() - 1] + +## 目标大境界索引(realm_index+1);化神圆满(最高)返回 -1 表示无可突破。 +func get_next_realm_index() -> int: + if realm_index + 1 >= REALM_NAMES.size(): + return -1 + return realm_index + 1 + +## 大境界突破所需灵石(按目标大境界索引读配置);无可突破返回 -1。 +func get_realm_breakthrough_cost() -> int: + var next := get_next_realm_index() + if next < 0: + return -1 + return GameConfig.realm_breakthrough_costs[next - 1] diff --git a/src/Core/GameConfig.gd b/src/Core/GameConfig.gd index 821124f..51fbfd6 100644 --- a/src/Core/GameConfig.gd +++ b/src/Core/GameConfig.gd @@ -38,6 +38,14 @@ var bottleneck_chances: Array[float] = [0.85, 0.8, 0.75, 0.6] var level_thresholds: Array[float] = [100.0, 200.0, 350.0, 550.0, 800.0, 1100.0, 1500.0, 2000.0, 2600.0, 3300.0, 4100.0, 5000.0] ## 瓶颈目标层(升到这些层需突破判定)。 var bottleneck_levels: Array[int] = [4, 7, 10, 13] +## 大境界突破灵石花费(索引 0~3 = 升筑基/金丹/元婴/化神)。 +var realm_breakthrough_costs: Array[int] = [500, 4000, 12000, 60000] +## 大境界突破成功率(与 realm_breakthrough_costs 一一对应,越往上越难)。 +var realm_breakthrough_chances: Array[float] = [0.6, 0.5, 0.4, 0.3] +## 大境界突破失败倒退步数(练气退层数/筑基+退小境,不跨大境界)。 +var realm_breakthrough_fail_drop := 3 +## 筑基及以上小境门槛(初期→中期/中期→后期/后期→圆满,各大大境界通用)。 +var realm_sub_thresholds: Array[float] = [6000.0, 12000.0, 24000.0] # —— UI 通用(对应 cfg 的 [ui] 节)—— ## HUD 字体大小(导出版用默认值,与 cfg 保持同步)。 @@ -117,6 +125,25 @@ func _load_config() -> void: for v in bn_raw: arr_bn.append(int(v)) bottleneck_levels = arr_bn + var rb_cost_raw: Variant = cfg.get_value("cultivation", "realm_breakthrough_costs", []) + if rb_cost_raw is Array and rb_cost_raw.size() == realm_breakthrough_costs.size(): + var arr_rb: Array[int] = [] + for v in rb_cost_raw: + arr_rb.append(int(v)) + realm_breakthrough_costs = arr_rb + var rb_ch_raw: Variant = cfg.get_value("cultivation", "realm_breakthrough_chances", []) + if rb_ch_raw is Array and rb_ch_raw.size() == realm_breakthrough_chances.size(): + var arr_rch: Array[float] = [] + for v in rb_ch_raw: + arr_rch.append(float(v)) + realm_breakthrough_chances = arr_rch + realm_breakthrough_fail_drop = cfg.get_value("cultivation", "realm_breakthrough_fail_drop", realm_breakthrough_fail_drop) + var sub_raw: Variant = cfg.get_value("cultivation", "realm_sub_thresholds", []) + if sub_raw is Array and sub_raw.size() == realm_sub_thresholds.size(): + var arr_sub: Array[float] = [] + for v in sub_raw: + arr_sub.append(float(v)) + realm_sub_thresholds = arr_sub # UI 通用 hud_font_size = cfg.get_value("ui", "hud_font_size", hud_font_size) # 建筑系统 diff --git a/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn b/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn index 0c51b7f..e8410b5 100644 --- a/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn +++ b/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn @@ -66,6 +66,12 @@ text = "" [node name="ButtonRow" type="HBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=781000009] +[node name="Button_RealmBreakthrough" type="Button" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=781000012] +unique_name_in_owner = true +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 22 +text = "大境界突破" + [node name="Spacer" type="Control" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=781000010] layout_mode = 2 size_flags_horizontal = 3 @@ -77,3 +83,4 @@ theme_override_font_sizes/font_size = 22 text = "关闭" [connection signal="button_up" from="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow/Button_Close" to="." method="_on_button_close_button_up"] +[connection signal="button_up" from="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow/Button_RealmBreakthrough" to="." method="_on_button_realm_breakthrough_button_up"] diff --git a/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd index 5e281e6..5e390ba 100644 --- a/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd +++ b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd @@ -1,10 +1,13 @@ ## 弟子详情弹窗(挂载于 DiscipleDetailPanel.tscn)。 ## 静态展示弟子信息(资质/年龄/灵根/境界/编号/入宗时间), -## 修炼进度等动态内容留待 D5 修炼循环填充。 +## 修炼进度、大境界突破按钮(手动花费灵石)等动态内容。 extends Control @onready var title_label: Label = %TitleLabel @onready var info_label: Label = %InfoLabel +@onready var breakthrough_button: Button = %Button_RealmBreakthrough + +var _current_disciple: Disciple = null ## 默认隐藏。 @@ -14,6 +17,7 @@ func _ready() -> void: ## 显示指定弟子的详情。 ## @param d: 要展示的弟子 func show_detail(d: Disciple) -> void: + _current_disciple = d title_label.text = d.name + ("(天灵根)" if d.is_heavenly else "") info_label.text = "名字:%s\n资质:%s\n年龄:%d岁\n灵根:%s\n境界:%s\n修为:%s\n入宗时间:%s" % [ d.name, @@ -24,8 +28,38 @@ func show_detail(d: Disciple) -> void: d.get_cultivation_progress_text(), d.get_join_date_text(), ] + _refresh_breakthrough_button() visible = true +## 刷新大境界突破按钮的文案与可用状态。 +## 修为未圆满 / 灵石不足 / 已至巅峰 → 置灰;否则可点击(文案显示所需灵石)。 +func _refresh_breakthrough_button() -> void: + if _current_disciple == null: + return + var next := _current_disciple.get_next_realm_index() + if next < 0: + breakthrough_button.text = "已至巅峰" + breakthrough_button.disabled = true + return + var cost := _current_disciple.get_realm_breakthrough_cost() + if not _current_disciple.is_realm_peak(): + breakthrough_button.text = "大境界突破(修为未圆满)" + breakthrough_button.disabled = true + return + if SectManager.spirit_stones < cost: + breakthrough_button.text = "大境界突破(需 %d 灵石)" % cost + breakthrough_button.disabled = true + return + breakthrough_button.text = "大境界突破(需 %d 灵石)" % cost + breakthrough_button.disabled = false + +## 点击"大境界突破"按钮:执行突破判定(扣灵石 → 成功升大境界/失败修为倒退),随后刷新面板。 +func _on_button_realm_breakthrough_button_up() -> void: + if _current_disciple == null: + return + CultivationManager.try_realm_breakthrough(_current_disciple) + show_detail(_current_disciple) + ## 点击"关闭"按钮。 func _on_button_close_button_up() -> void: visible = false