From d4590a1794df3597ff8b478b62fb7d70f0a74fde Mon Sep 17 00:00:00 2001 From: bridge Date: Mon, 13 Oct 2025 00:09:02 +0800 Subject: [PATCH] add appearence --- src/classes/appearance.py | 67 +++++++++++++++++++++++++++++++++++++++ src/classes/avatar.py | 7 ++++ 2 files changed, 74 insertions(+) create mode 100644 src/classes/appearance.py diff --git a/src/classes/appearance.py b/src/classes/appearance.py new file mode 100644 index 0000000..38569d1 --- /dev/null +++ b/src/classes/appearance.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +import random +from dataclasses import dataclass +from typing import Iterable, List, Tuple + + +@dataclass +class Appearance: + level: int # 1~10 + name: str + desc_male: str + desc_female: str + + def get_info(self) -> str: + return f"{self.name}({self.level})" + + def get_detailed_info(self, gender: object | None = None) -> str: + """ + 根据性别返回更贴切的描述;若未提供性别或无法识别,则默认使用男性描述。 + 不依赖具体 Gender 类型,避免循环导入。 + """ + g = str(gender) if gender is not None else "" + s = g.lower() + use_female = (g == "女") or (s == "female") + desc = self.desc_female if use_female else self.desc_male + return f"{self.name}({self.level}) - {desc}" + + +_LEVEL_DATA: Tuple[Tuple[int, str, str, str], ...] = ( + # level, name, desc_male, desc_female + (1, "奇丑", "你相貌奇丑,难掩瑕疵,路人避之。", "你容貌奇丑,难掩瑕疵,旁人多避。"), + (2, "丑陋", "你五官粗劣,谈不上顺眼。", "你五官粗劣,称不上好看。"), + (3, "粗陋", "你面貌粗陋,胜在耐看尚欠。", "你面貌粗陋,略显刻薄之相。"), + (4, "寒素", "你相貌寒素,平平无奇。", "你容颜寒素,谈不上出众。"), + (5, "清秀", "你眉目尚算清秀。", "你眉眼清秀,颇为耐看。"), + (6, "秀致", "你神情秀致,气质端正。", "你姿容秀致,气韵娴雅。"), + (7, "俊美", "你面如冠玉,俊美非常。", "你明眸皓齿,艳若桃李。"), + (8, "倾城", "你丰神俊朗,姿容可称倾城。", "你貌若倾城,一笑百媚生。"), + (9, "绝色", "你风采绝伦,行止如玉,令人侧目。", "你美绝人寰,风华绝代,惊艳四座。"), + (10, "惊艳", "你容止惊艳,如谪仙临尘。", "你美若天仙,惊鸿一瞥,群芳失色。"), +) + + +def _build_pool(data: Iterable[Tuple[int, str, str, str]]) -> List[Appearance]: + pool: List[Appearance] = [] + for level, name, dm, df in data: + pool.append(Appearance(level=level, name=name, desc_male=dm, desc_female=df)) + return pool + + +_APPEARANCE_POOL: List[Appearance] = _build_pool(_LEVEL_DATA) + + +def get_random_appearance() -> Appearance: + """返回一个随机外貌实例。""" + # 重新构造实例,避免共享同一个对象引用 + base = random.choice(_APPEARANCE_POOL) + return Appearance(level=base.level, name=base.name, desc_male=base.desc_male, desc_female=base.desc_female) + + +__all__ = [ + "Appearance", + "get_random_appearance", +] + + diff --git a/src/classes/avatar.py b/src/classes/avatar.py index 29121e3..19222e4 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -30,6 +30,7 @@ from src.run.log import get_logger from src.classes.alignment import Alignment from src.utils.params import filter_kwargs_for_callable from src.classes.sect import Sect +from src.classes.appearance import Appearance, get_random_appearance persona_num = CONFIG.avatar.persona_num @@ -82,6 +83,8 @@ class Avatar: alignment: Alignment | None = None # 所属宗门(可为空,表示散修/无门无派) sect: Sect | None = None + # 外貌(1~10级),创建时随机生成 + appearance: Appearance = field(default_factory=get_random_appearance) # 当月/当步新设动作标记:在 commit_next_plan 设为 True,首次 tick_action 后清为 False _new_action_set_this_step: bool = False @@ -137,6 +140,7 @@ class Avatar: cultivation_info = self.cultivation_progress.get_detailed_info() personas_info = ", ".join([p.get_detailed_info() for p in self.personas]) if self.personas else "无" items_info = ",".join([f"{item.get_detailed_info()}x{quantity}" for item, quantity in self.items.items()]) if self.items else "无" + appearance_info = self.appearance.get_detailed_info(self.gender) else: # personas和sect一致返回detailed,因为这俩太重要了 sect_info = self.sect.get_detailed_info() if self.sect is not None else "散修" @@ -147,6 +151,7 @@ class Avatar: cultivation_info = self.cultivation_progress.get_info() personas_info = ", ".join([p.get_detailed_info() for p in self.personas]) if self.personas else "无" items_info = ",".join([f"{item.get_info()}x{quantity}" for item, quantity in self.items.items()]) if self.items else "无" + appearance_info = self.appearance.get_info() return { "id": self.id, @@ -165,6 +170,7 @@ class Avatar: "境界": cultivation_info, "个性": personas_info, "物品": items_info, + "外貌": appearance_info, } def __str__(self) -> str: @@ -451,6 +457,7 @@ class Avatar: f"{self.name}", f"性别: {self.gender}", f"年龄: {self.age}", + f"外貌: {self.appearance.get_info()}", f"阵营: {self.alignment}", f"境界: {str(self.cultivation_progress)}", f"HP: {self.hp}",