fix death bug
This commit is contained in:
@@ -19,8 +19,8 @@ class Age:
|
||||
|
||||
def __init__(self, age: int, realm: Realm):
|
||||
self.age = age
|
||||
# 基础最大寿元(年),不含effects加成,初始化为 max(境界基线, 当前年龄+1)
|
||||
self.base_max_lifespan: int = max(self.get_base_expected_lifespan(realm), self.age + 1)
|
||||
# 基础最大寿元(年),不含effects加成
|
||||
self.base_max_lifespan: int = self.get_base_expected_lifespan(realm)
|
||||
# 实际最大寿元(年),包含effects加成,初始值与基础值相同
|
||||
self.max_lifespan: int = self.base_max_lifespan
|
||||
|
||||
@@ -38,8 +38,7 @@ class Age:
|
||||
|
||||
def set_initial_max_lifespan(self, realm: Realm) -> None:
|
||||
"""构造时已设置最大寿元,此处保持与构造策略一致。"""
|
||||
base = self.get_base_expected_lifespan(realm)
|
||||
self.base_max_lifespan = max(base, self.age + 1)
|
||||
self.base_max_lifespan = self.get_base_expected_lifespan(realm)
|
||||
self.max_lifespan = self.base_max_lifespan
|
||||
|
||||
def update_realm(self, new_realm: Realm) -> None:
|
||||
@@ -48,11 +47,10 @@ class Age:
|
||||
self.ensure_max_lifespan_at_least_realm_base(new_realm)
|
||||
|
||||
def ensure_max_lifespan_at_least_realm_base(self, realm: Realm) -> None:
|
||||
"""确保基础最大寿元至少达到 max(该境界基线, 当前年龄+1)。"""
|
||||
"""确保基础最大寿元至少达到该境界基线。"""
|
||||
base = self.get_base_expected_lifespan(realm)
|
||||
floor_value = max(base, self.age + 1)
|
||||
if self.base_max_lifespan < floor_value:
|
||||
self.base_max_lifespan = floor_value
|
||||
if self.base_max_lifespan < base:
|
||||
self.base_max_lifespan = base
|
||||
self.max_lifespan = self.base_max_lifespan
|
||||
|
||||
def increase_max_lifespan(self, years: int) -> None:
|
||||
@@ -85,7 +83,7 @@ class Age:
|
||||
|
||||
# 基础概率:每超过1年增加0.01的概率
|
||||
prob_add = 0.01
|
||||
death_probability = min(years_over_lifespan * prob_add, 0.1)
|
||||
death_probability = min(years_over_lifespan * prob_add, 0.01)
|
||||
|
||||
return death_probability
|
||||
|
||||
|
||||
@@ -14,6 +14,33 @@ class AvatarManager:
|
||||
avatars: Dict[str, "Avatar"] = field(default_factory=dict)
|
||||
# 存储已死亡的角色(归档)
|
||||
dead_avatars: Dict[str, "Avatar"] = field(default_factory=dict)
|
||||
|
||||
# --- 变更缓冲区 (不参与序列化) ---
|
||||
_newly_dead_buffer: List[str] = field(default_factory=list, init=False)
|
||||
_newly_born_buffer: List[str] = field(default_factory=list, init=False)
|
||||
|
||||
def register_avatar(self, avatar: "Avatar", is_newly_born: bool = False) -> None:
|
||||
"""
|
||||
注册一个角色到管理器中。
|
||||
Args:
|
||||
avatar: 角色对象
|
||||
is_newly_born: 是否为新出生的角色(若是,则加入变更缓冲供前端同步)
|
||||
"""
|
||||
self.avatars[str(avatar.id)] = avatar
|
||||
if is_newly_born:
|
||||
self._newly_born_buffer.append(str(avatar.id))
|
||||
|
||||
def pop_newly_dead(self) -> List[str]:
|
||||
"""获取并清空本帧刚死亡的角色ID列表"""
|
||||
res = list(self._newly_dead_buffer)
|
||||
self._newly_dead_buffer.clear()
|
||||
return res
|
||||
|
||||
def pop_newly_born(self) -> List[str]:
|
||||
"""获取并清空本帧刚出生的角色ID列表"""
|
||||
res = list(self._newly_born_buffer)
|
||||
self._newly_born_buffer.clear()
|
||||
return res
|
||||
|
||||
def get_avatar(self, avatar_id: str) -> "Avatar | None":
|
||||
"""
|
||||
@@ -33,6 +60,9 @@ class AvatarManager:
|
||||
# 断开地图连接,确保不出现在地图网格上
|
||||
if hasattr(avatar, "tile"):
|
||||
avatar.tile = None
|
||||
|
||||
# 记录变更
|
||||
self._newly_dead_buffer.append(aid)
|
||||
|
||||
def get_avatars_in_same_region(self, avatar: "Avatar") -> List["Avatar"]:
|
||||
"""
|
||||
|
||||
@@ -21,4 +21,7 @@ def handle_death(world: World, avatar: Avatar, reason: Union[str, DeathReason])
|
||||
# 标记为死亡(软删除)
|
||||
avatar.set_dead(reason_str, world.month_stamp)
|
||||
|
||||
# 从管理器中归档(硬移动),并记录变更
|
||||
world.avatar_manager.handle_death(avatar.id)
|
||||
|
||||
# 可以在这里触发其他逻辑,比如检查是否有继承人等
|
||||
|
||||
@@ -369,14 +369,9 @@ async def game_loop():
|
||||
# 执行一步
|
||||
events = await sim.step()
|
||||
|
||||
# 找出新诞生的角色 ID 和 刚死亡的角色 ID
|
||||
newly_born_ids = set()
|
||||
newly_dead_ids = set()
|
||||
for e in events:
|
||||
if "晋升为修士" in e.content and e.related_avatars:
|
||||
newly_born_ids.update(e.related_avatars)
|
||||
if ("身亡" in e.content or "老死" in e.content) and e.related_avatars:
|
||||
newly_dead_ids.update(e.related_avatars)
|
||||
# 获取状态变更 (Source of Truth: AvatarManager)
|
||||
newly_born_ids = world.avatar_manager.pop_newly_born()
|
||||
newly_dead_ids = world.avatar_manager.pop_newly_dead()
|
||||
|
||||
avatar_updates = []
|
||||
|
||||
@@ -411,8 +406,6 @@ async def game_loop():
|
||||
"is_dead": True,
|
||||
"action": "已故"
|
||||
})
|
||||
# 将死者归档到墓地,从活跃列表移除
|
||||
world.avatar_manager.handle_death(aid)
|
||||
|
||||
# 3. 常规位置更新(暂时只发前 50 个旧角色,减少数据量)
|
||||
limit = 50
|
||||
@@ -1063,7 +1056,7 @@ def create_avatar(req: CreateAvatarRequest):
|
||||
avatar.alignment = Alignment.from_str(req.alignment)
|
||||
|
||||
# 注册到管理器
|
||||
world.avatar_manager.avatars[avatar.id] = avatar
|
||||
world.avatar_manager.register_avatar(avatar, is_newly_born=True)
|
||||
|
||||
return {
|
||||
"status": "ok",
|
||||
|
||||
@@ -173,7 +173,7 @@ class Simulator:
|
||||
death_reason = DeathReason(DeathType.OLD_AGE)
|
||||
|
||||
if is_dead and death_reason:
|
||||
event = Event(self.world.month_stamp, str(death_reason), related_avatars=[avatar.id])
|
||||
event = Event(self.world.month_stamp, f"{avatar.name}{death_reason}", related_avatars=[avatar.id])
|
||||
events.append(event)
|
||||
handle_death(self.world, avatar, death_reason)
|
||||
|
||||
@@ -192,7 +192,7 @@ class Simulator:
|
||||
name = get_random_name(gender)
|
||||
# create_random_mortal 内部会获取 existing_avatars,需要确保它处理活人
|
||||
new_avatar = create_random_mortal(self.world, self.world.month_stamp, name, Age(age, Realm.Qi_Refinement))
|
||||
self.world.avatar_manager.avatars[new_avatar.id] = new_avatar
|
||||
self.world.avatar_manager.register_avatar(new_avatar, is_newly_born=True)
|
||||
event = Event(self.world.month_stamp, f"{new_avatar.name}晋升为修士了。", related_avatars=[new_avatar.id])
|
||||
events.append(event)
|
||||
return events
|
||||
|
||||
Reference in New Issue
Block a user