update unittest

This commit is contained in:
bridge
2026-01-07 23:14:48 +08:00
parent ea9a873589
commit b53f428cbb
21 changed files with 492 additions and 252 deletions

View File

@@ -37,12 +37,11 @@ class NurtureWeapon(TimedAction):
if random.random() < total_chance:
treasure_weapon = get_random_weapon_by_realm(Realm.Foundation_Establishment, self.avatar.weapon.weapon_type)
if treasure_weapon:
import copy
old_weapon_name = self.avatar.weapon.name
old_proficiency = self.avatar.weapon_proficiency
# 深拷贝宝物兵器并更换(会重新计算长期效果)
# get_random_weapon_by_realm 已经返回了副本但再次copy也无妨
new_weapon = copy.deepcopy(treasure_weapon)
new_weapon = treasure_weapon.instantiate()
self.avatar.change_weapon(new_weapon)
# 恢复熟练度change_weapon 会归零,需要手动恢复)
self.avatar.weapon_proficiency = old_proficiency

View File

@@ -6,10 +6,11 @@ from typing import Optional, Dict
from src.utils.df import game_configs, get_str, get_int
from src.classes.effect import load_effect_from_str
from src.classes.cultivation import Realm
from src.classes.item import Item
@dataclass
class Auxiliary:
class Auxiliary(Item):
"""
辅助装备类:提供各种辅助功能的装备
字段与 static/game_configs/auxiliary.csv 对应:
@@ -107,8 +108,7 @@ auxiliaries_by_id, auxiliaries_by_name = _load_auxiliaries()
def get_random_auxiliary_by_realm(realm: Realm) -> Optional[Auxiliary]:
"""获取指定境界的随机辅助装备"""
import random
import copy
candidates = [a for a in auxiliaries_by_id.values() if a.realm == realm]
if not candidates:
return None
return copy.deepcopy(random.choice(candidates))
return random.choice(candidates).instantiate()

View File

@@ -207,7 +207,6 @@ class InventoryMixin:
包括扣款、获得物品(服用/入包/装备)、以旧换新。
返回交易报告 dict。
"""
import copy
from src.classes.elixir import Elixir
from src.classes.weapon import Weapon
from src.classes.auxiliary import Auxiliary
@@ -240,7 +239,7 @@ class InventoryMixin:
elif isinstance(obj, (Weapon, Auxiliary)):
# 装备需要深拷贝
new_equip = copy.deepcopy(obj)
new_equip = obj.instantiate()
# 尝试卖出旧装备并换上新装备
sold_name, refund = self._equip_and_trade_in(new_equip)

View File

@@ -26,13 +26,13 @@ class CirculationManager:
return
# 使用深拷贝存储,防止外部修改影响记录
# 注意:这里假设 weapon 对象是可以被 copy 的
self.sold_weapons.append(copy.deepcopy(weapon))
self.sold_weapons.append(weapon.instantiate())
def add_auxiliary(self, auxiliary: "Auxiliary") -> None:
"""记录一件流出的辅助装备"""
if auxiliary is None:
return
self.sold_auxiliaries.append(copy.deepcopy(auxiliary))
self.sold_auxiliaries.append(auxiliary.instantiate())
def to_save_dict(self) -> dict:
"""序列化为字典以便存档"""

View File

@@ -1,7 +1,6 @@
from __future__ import annotations
import random
import copy
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List, Union, Optional
@@ -9,6 +8,7 @@ from typing import Dict, List, Union, Optional
from src.utils.df import game_configs, get_str, get_int
from src.classes.effect import load_effect_from_str, format_effects_to_text
from src.classes.cultivation import Realm
from src.classes.item import Item
class ElixirType(Enum):
@@ -21,7 +21,7 @@ class ElixirType(Enum):
@dataclass
class Elixir:
class Elixir(Item):
"""
丹药类
字段与 static/game_configs/elixir.csv 对应
@@ -196,4 +196,6 @@ def get_elixirs_by_realm(realm: Realm) -> List[Elixir]:
def get_random_elixir_by_realm(realm: Realm) -> Optional[Elixir]:
"""获取指定境界的随机丹药"""
candidates = get_elixirs_by_realm(realm)
return copy.deepcopy(random.choice(candidates))
if not candidates:
return None
return random.choice(candidates).instantiate()

16
src/classes/item.py Normal file
View File

@@ -0,0 +1,16 @@
import copy
from typing import TypeVar, Any
T = TypeVar("T", bound="Item")
class Item:
"""所有物品的基类"""
def instantiate(self: T) -> T:
"""
创建该物品的一个新实例。
默认行为是深拷贝,适用于有独立状态的物品(如装备)。
子类如果是只读对象(如材料),可以重写此方法返回 self 以优化性能。
"""
return copy.deepcopy(self)

View File

@@ -1,10 +1,11 @@
from dataclasses import dataclass
from src.classes.item import Item
from src.utils.df import game_configs, get_str, get_int
from src.classes.cultivation import Realm
@dataclass
class Material:
class Material(Item):
"""
材料
"""
@@ -13,6 +14,9 @@ class Material:
desc: str
realm: Realm
def instantiate(self) -> "Material":
return self
def __hash__(self) -> int:
return hash(self.id)

View File

@@ -1,6 +1,5 @@
from __future__ import annotations
import copy
import random
from dataclasses import dataclass, field
from typing import Optional, Dict
@@ -9,10 +8,11 @@ from src.utils.df import game_configs, get_str, get_int
from src.classes.effect import load_effect_from_str
from src.classes.cultivation import Realm
from src.classes.weapon_type import WeaponType
from src.classes.item import Item
@dataclass
class Weapon:
class Weapon(Item):
"""
兵器类:用于战斗的装备
字段与 static/game_configs/weapon.csv 对应:
@@ -118,4 +118,4 @@ def get_random_weapon_by_realm(realm: Realm, weapon_type: Optional[WeaponType] =
if not candidates:
return None
return copy.deepcopy(random.choice(candidates))
return random.choice(candidates).instantiate()