add relationship

This commit is contained in:
bridge
2025-09-18 23:37:19 +08:00
parent 5edb58400d
commit 938f85db9a
4 changed files with 106 additions and 1 deletions

View File

@@ -21,6 +21,7 @@ from src.classes.magic_stone import MagicStone
from src.classes.hp_and_mp import HP, MP, HP_MAX_BY_REALM, MP_MAX_BY_REALM
from src.utils.id_generator import get_avatar_id
from src.utils.config import CONFIG
from src.classes.relation import Relation
persona_num = CONFIG.avatar.persona_num
@@ -67,6 +68,7 @@ class Avatar:
items: dict[Item, int] = field(default_factory=dict)
hp: HP = field(default_factory=lambda: HP(0, 0)) # 将在__post_init__中初始化
mp: MP = field(default_factory=lambda: MP(0, 0)) # 将在__post_init__中初始化
relations: dict["Avatar", Relation] = field(default_factory=dict)
def __post_init__(self):
"""
@@ -369,8 +371,60 @@ class Avatar:
else:
items_info = "物品持有情况:无"
# 关系摘要
relations_summary = self._get_relations_summary_str()
personas_count = len(self.personas)
return f"{info}\n{personas_info}\n{magic_stone_info}\n{items_info}\n决策时需参考这个角色的{personas_count}个个性特点。\n该角色的目前暂时的合法动作为:{action_space}"
return f"{info}\n{personas_info}\n{magic_stone_info}\n{items_info}\n关系:{relations_summary}\n决策时需参考这个角色的{personas_count}个个性特点。\n该角色的目前暂时的合法动作为:{action_space}"
def set_relation(self, other: "Avatar", relation: Relation) -> None:
"""
设置与另一个角色的关系(对称)。
"""
if other is self:
return
self.relations[other] = relation
# 保持对称
if getattr(other, "relations", None) is not None:
other.relations[self] = relation
def get_relation(self, other: "Avatar") -> Optional[Relation]:
return self.relations.get(other)
def clear_relation(self, other: "Avatar") -> None:
self.relations.pop(other, None)
if getattr(other, "relations", None) is not None:
other.relations.pop(self, None)
def _get_relations_summary_str(self, max_count: int = 8) -> str:
entries: list[str] = []
for other in self.relations.keys():
entries.append(self.get_other_avatar_info(other))
if not entries:
return ""
return "".join(entries[:max_count])
def get_co_region_avatars(self, avatars: List["Avatar"]) -> List["Avatar"]:
"""
返回与自己处于同一区域的角色列表(不含自己)。
"""
if self.tile is None:
return []
same_region: list[Avatar] = []
for other in avatars:
if other is self or other.tile is None:
continue
if other.tile.region == self.tile.region:
same_region.append(other)
return same_region
def get_other_avatar_info(self, other_avatar: "Avatar") -> str:
"""
仅显示三个字段:名字、境界、关系。
"""
relation = self.get_relation(other_avatar)
relation_str = str(relation)
return f"{other_avatar.name},境界:{str(other_avatar.cultivation_progress)},关系:{relation_str}"
@property
def move_step_length(self) -> int:

25
src/classes/relation.py Normal file
View File

@@ -0,0 +1,25 @@
from __future__ import annotations
from enum import Enum
class Relation(Enum):
KINSHIP = "kinship" # 亲子/亲属
LOVERS = "lovers" # 情侣/道侣
MASTER_APPRENTICE = "mentorship" # 师徒
FRIEND = "friend" # 朋友
ENEMY = "enemy" # 仇人
def __str__(self) -> str:
return relation_strs.get(self, self.value)
relation_strs = {
Relation.KINSHIP: "亲属",
Relation.LOVERS: "情侣",
Relation.MASTER_APPRENTICE: "师徒",
Relation.FRIEND: "朋友",
Relation.ENEMY: "仇人",
}

View File

@@ -3,6 +3,7 @@ from typing import List, Optional, Tuple, Callable
from src.classes.avatar import Avatar, Gender
from src.classes.tile import TileType
from src.utils.text_wrap import wrap_text
from src.classes.relation import Relation
def draw_grid(pygame_mod, screen, colors, map_obj, ts: int, m: int):
@@ -164,6 +165,16 @@ def draw_tooltip_for_avatar(pygame_mod, screen, colors, font, avatar: Avatar):
lines.append("目标:")
objective_lines = wrap_text(avatar.objective, 20)
lines.extend(objective_lines)
# 关系信息
relations_list = [f"{other.name}({str(relation)})" for other, relation in getattr(avatar, "relations", {}).items()]
lines.append("")
if relations_list:
lines.append("关系:")
for s in relations_list[:6]:
lines.append(f" {s}")
else:
lines.append("关系: 无")
draw_tooltip(pygame_mod, screen, colors, lines, *pygame_mod.mouse.get_pos(), font)

View File

@@ -23,6 +23,7 @@ from src.utils.names import get_random_name
from src.utils.id_generator import get_avatar_id
from src.utils.config import CONFIG
from src.run.log import get_logger
from src.classes.relation import Relation
def clamp(value: int, lo: int, hi: int) -> int:
@@ -85,6 +86,20 @@ def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp
)
avatar.tile = world.map.get_tile(x, y)
avatars[avatar.id] = avatar
# —— 为演示添加少量示例关系 ——
avatar_list = list(avatars.values())
if len(avatar_list) >= 2:
# 朋友
avatar_list[0].set_relation(avatar_list[1], Relation.FRIEND)
if len(avatar_list) >= 4:
# 仇人
avatar_list[2].set_relation(avatar_list[3], Relation.ENEMY)
if len(avatar_list) >= 6:
# 师徒(随意指派方向,关系对称)
avatar_list[4].set_relation(avatar_list[5], Relation.MASTER_APPRENTICE)
if len(avatar_list) >= 6:
# 情侣
avatar_list[6].set_relation(avatar_list[7], Relation.LOVERS)
return avatars