diff --git a/EN_README.md b/EN_README.md
index ee09f4a..e8902d3 100644
--- a/EN_README.md
+++ b/EN_README.md
@@ -29,7 +29,7 @@
> **An AI-driven cultivation world simulator that aims to create a truly living, immersive xianxia world.**
-
+
diff --git a/README.md b/README.md
index 22b7065..d78d114 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@
> **一个AI驱动的修仙世界模拟器,旨在创造一个真正活着的、有沉浸感的仙侠世界。**
-
+
diff --git a/src/classes/avatar/info_presenter.py b/src/classes/avatar/info_presenter.py
index df2ffec..3d01a7c 100644
--- a/src/classes/avatar/info_presenter.py
+++ b/src/classes/avatar/info_presenter.py
@@ -110,6 +110,9 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
"""
获取结构化的角色信息,用于前端展示和交互。
"""
+ import time
+ t_start = time.time()
+
# 基础信息
from src.i18n import t
emoji = EMOTION_EMOJIS.get(avatar.emotion, EMOTION_EMOJIS[EmotionType.CALM])
@@ -193,6 +196,8 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
materials_list.append(m_info)
info["materials"] = materials_list
+ t_mid = time.time()
+
# 6. 关系 (Relations)
relations_list = []
for other, relation in avatar.relations.items():
@@ -206,6 +211,8 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
})
info["relations"] = relations_list
+ t_rel = time.time()
+
# 7. 外貌
info["appearance"] = avatar.appearance.get_info()
@@ -226,6 +233,9 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
# 当前效果
info[t("Current Effects")] = _get_effects_text(avatar)
+ t_end = time.time()
+ print(f"[Perf] Total: {t_end - t_start:.4f}s | Relations: {t_rel - t_mid:.4f}s | Effects: {t_end - t_rel:.4f}s | Other: {t_mid - t_start:.4f}s")
+
return info
diff --git a/src/classes/cultivation.py b/src/classes/cultivation.py
index 255a681..6ab34a0 100644
--- a/src/classes/cultivation.py
+++ b/src/classes/cultivation.py
@@ -288,6 +288,10 @@ class CultivationProgress:
"""
检查是否可以突破
"""
+ # 动态检测目前最高级别的修为:如果已经是最高境界的最高等级,则不能突破
+ max_level = len(REALM_ORDER) * LEVELS_PER_REALM
+ if self.level >= max_level:
+ return False
return self.is_in_bottleneck()
def can_cultivate(self) -> bool:
diff --git a/tests/test_breakthrough_logic.py b/tests/test_breakthrough_logic.py
new file mode 100644
index 0000000..d36a7e7
--- /dev/null
+++ b/tests/test_breakthrough_logic.py
@@ -0,0 +1,81 @@
+import pytest
+from src.classes.cultivation import CultivationProgress, Realm, Stage, REALM_ORDER, LEVELS_PER_REALM
+
+def test_breakthrough_normal(dummy_avatar):
+ """
+ 测试正常突破逻辑:从练气圆满突破到筑基前期
+ """
+ # 练气圆满是 30 级 (LEVELS_PER_REALM * 1)
+ qi_max_level = 30
+
+ # 设置角色状态
+ cp = CultivationProgress(level=qi_max_level, exp=0)
+ dummy_avatar.cultivation_progress = cp
+
+ # 验证当前状态
+ assert cp.realm == Realm.Qi_Refinement
+ assert cp.is_in_bottleneck() is True
+ assert cp.can_break_through() is True
+
+ # 执行突破
+ cp.break_through()
+
+ # 验证突破后状态
+ # 应该升级到 31 级
+ assert cp.level == 31
+ # 境界应该是 筑基
+ assert cp.realm == Realm.Foundation_Establishment
+ # 阶段应该是 前期
+ assert cp.stage == Stage.Early_Stage
+ # 不再处于瓶颈
+ assert cp.is_in_bottleneck() is False
+
+def test_breakthrough_max_realm_limit(dummy_avatar):
+ """
+ 测试最高境界限制:元婴圆满(目前最高等级)不能再突破
+ """
+ # 计算最高等级
+ # 目前有 4 个境界,每个 30 级,最高 120 级
+ max_level = len(REALM_ORDER) * LEVELS_PER_REALM
+
+ # 设置角色状态为最高等级
+ cp = CultivationProgress(level=max_level, exp=0)
+ dummy_avatar.cultivation_progress = cp
+
+ # 验证当前状态
+ assert cp.realm == Realm.Nascent_Soul
+ # 理论上它是 30/60/90/120,模 30 为 0,所以 is_in_bottleneck 会返回 True
+ assert cp.is_in_bottleneck() is True
+
+ # 关键测试点:can_break_through 应该返回 False,因为已经封顶了
+ assert cp.can_break_through() is False
+
+def test_not_in_bottleneck(dummy_avatar):
+ """
+ 测试非瓶颈期不能突破
+ """
+ # 随便设一个中间等级,比如 15 级(练气中期)
+ cp = CultivationProgress(level=15, exp=0)
+ dummy_avatar.cultivation_progress = cp
+
+ assert cp.is_in_bottleneck() is False
+ assert cp.can_break_through() is False
+
+def test_breakthrough_intermediate_bottleneck(dummy_avatar):
+ """
+ 测试中间境界的突破:筑基圆满 -> 金丹
+ """
+ # 筑基圆满是 60 级
+ foundation_max_level = 60
+
+ cp = CultivationProgress(level=foundation_max_level, exp=0)
+ dummy_avatar.cultivation_progress = cp
+
+ assert cp.realm == Realm.Foundation_Establishment
+ assert cp.can_break_through() is True
+
+ cp.break_through()
+
+ assert cp.level == 61
+ assert cp.realm == Realm.Core_Formation
+ assert cp.stage == Stage.Early_Stage