fix: use str() instead of .value for realm i18n display (#98)

* fix: use str() instead of .value for realm i18n display

Fix bug where user-facing messages displayed raw enum values like
"FOUNDATION_ESTABLISHMENT" instead of translated names like "筑基".

The Realm and Stage classes already have __str__ methods that return
i18n translated text, but several places were incorrectly using
.value which returns the raw enum string.

Changed files:
- src/classes/single_choice.py: item exchange messages
- src/classes/kill_and_grab.py: loot messages
- src/classes/fortune.py: fortune discovery messages
- src/classes/avatar/inventory_mixin.py: purchase error messages

Also added unit tests and integration tests to prevent regression.

* test: add integration tests for all modified files

Add tests covering:
- kill_and_grab.py: context string realm display
- fortune.py: weapon/auxiliary intro realm display
- inventory_mixin.py: can_buy_item error message realm display
This commit is contained in:
Zihao Xu
2026-01-25 02:44:13 -08:00
committed by GitHub
parent 2b5ec24455
commit aaa636a08e
7 changed files with 312 additions and 7 deletions

View File

@@ -190,7 +190,8 @@ class InventoryMixin:
if isinstance(obj, Elixir):
# 境界限制
if obj.realm > self.cultivation_progress.realm:
return False, f"境界不足,无法承受药力 ({obj.realm.value})"
# 使用 str() 来触发 Realm 的 __str__ 方法进行 i18n 翻译。
return False, f"境界不足,无法承受药力 ({str(obj.realm)})"
# 耐药性/生效中检查
for consumed in self.elixirs:

View File

@@ -412,8 +412,9 @@ async def try_trigger_fortune(avatar: Avatar) -> list[Event]:
theme = _pick_theme(kind)
else:
from src.i18n import t
intro = t("You discovered a {realm} weapon『{weapon_name}』in your fortune.",
realm=weapon.realm.value, weapon_name=weapon.name)
# 使用 str() 来触发 Realm 的 __str__ 方法进行 i18n 翻译。
intro = t("You discovered a {realm} weapon『{weapon_name}』in your fortune.",
realm=str(weapon.realm), weapon_name=weapon.name)
if avatar.weapon:
intro += t(" But you already have『{weapon_name}』.", weapon_name=avatar.weapon.name)
@@ -435,8 +436,9 @@ async def try_trigger_fortune(avatar: Avatar) -> list[Event]:
theme = _pick_theme(kind)
else:
from src.i18n import t
# 使用 str() 来触发 Realm 的 __str__ 方法进行 i18n 翻译。
intro = t("You discovered a {realm} auxiliary『{auxiliary_name}』in your fortune.",
realm=auxiliary.realm.value, auxiliary_name=auxiliary.name)
realm=str(auxiliary.realm), auxiliary_name=auxiliary.name)
if avatar.auxiliary:
intro += t(" But you already have『{auxiliary_name}』.", auxiliary_name=avatar.auxiliary.name)

View File

@@ -41,7 +41,8 @@ async def kill_and_grab(winner: Avatar, loser: Avatar) -> str:
# 判定是否夺取
item_label = '兵器' if loot_type == 'weapon' else '辅助装备'
context = f"战斗胜利,{loser.name} 身死道消,留下了一件{loot_item.realm.value}{item_label}{loot_item.name}』。"
# 使用 str() 来触发 Realm 的 __str__ 方法进行 i18n 翻译。
context = f"战斗胜利,{loser.name} 身死道消,留下了一件{str(loot_item.realm)}{item_label}{loot_item.name}』。"
swapped, log_text = await handle_item_exchange(
avatar=winner,

View File

@@ -153,7 +153,8 @@ async def handle_item_exchange(
current_item = ops["get_current"]()
new_name = new_item.name
new_grade = getattr(new_item, "realm", getattr(new_item, "grade", None)).value
# 使用 str() 来触发 Realm/Stage 的 __str__ 方法进行 i18n 翻译。
new_grade = str(getattr(new_item, "realm", getattr(new_item, "grade", None)))
# 1. 自动装备:当前无装备且不强制考虑卖新
if current_item is None and not can_sell_new: