add appearence

This commit is contained in:
bridge
2025-10-13 00:09:02 +08:00
parent 0d2cc2c3d3
commit d4590a1794
2 changed files with 74 additions and 0 deletions

67
src/classes/appearance.py Normal file
View File

@@ -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",
]

View File

@@ -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}",