add relationship
This commit is contained in:
@@ -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
25
src/classes/relation.py
Normal 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: "仇人",
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user