update events
This commit is contained in:
@@ -41,7 +41,13 @@ class Battle(InstantAction):
|
||||
target_name = target.name if target is not None else avatar_name
|
||||
# 展示双方折算战斗力(基于对手、含克制)
|
||||
s_att, s_def = get_effective_strength_pair(self.avatar, target)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起战斗(战斗力:{self.avatar.name} {int(s_att)} vs {target_name} {int(s_def)})")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
try:
|
||||
rel_ids.append(target.id)
|
||||
except Exception:
|
||||
pass
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起战斗(战斗力:{self.avatar.name} {int(s_att)} vs {target_name} {int(s_def)})", related_avatars=rel_ids)
|
||||
# 记录开始事件内容,供故事生成使用
|
||||
self._start_event_content = event.content
|
||||
return event
|
||||
@@ -55,13 +61,20 @@ class Battle(InstantAction):
|
||||
winner, loser = res[0], res[1]
|
||||
loser_damage, winner_damage = res[2], res[3]
|
||||
result_text = f"{winner} 战胜了 {loser},{loser} 受伤{loser_damage}点,{winner} 也受伤{winner_damage}点"
|
||||
result_event = Event(self.world.month_stamp, result_text)
|
||||
rel_ids = [self.avatar.id]
|
||||
try:
|
||||
t = self._get_target(avatar_name)
|
||||
if t is not None:
|
||||
rel_ids.append(t.id)
|
||||
except Exception:
|
||||
pass
|
||||
result_event = Event(self.world.month_stamp, result_text, related_avatars=rel_ids)
|
||||
|
||||
# 生成战斗小故事:使用便捷方法从参与者直接生成
|
||||
target = self._get_target(avatar_name)
|
||||
start_text = getattr(self, "_start_event_content", "") or result_event.content
|
||||
story = StoryTeller.tell_from_actors(start_text, result_event.content, self.avatar, target, prompt=self.STORY_PROMPT)
|
||||
story_event = Event(self.world.month_stamp, story)
|
||||
story_event = Event(self.world.month_stamp, story, related_avatars=rel_ids)
|
||||
return [result_event, story_event]
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ class Breakthrough(TimedAction):
|
||||
else:
|
||||
self._calamity = None
|
||||
self._calamity_other = None
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界", related_avatars=[self.avatar.id])
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
@@ -132,18 +132,25 @@ class Breakthrough(TimedAction):
|
||||
if not getattr(self, "_gen_story", False):
|
||||
# 不生成故事:不出现劫难,仅简单结果
|
||||
core_text = f"{self.avatar.name} 突破{'成功' if result_ok else '失败'}"
|
||||
return [Event(self.world.month_stamp, core_text)]
|
||||
return [Event(self.world.month_stamp, core_text, related_avatars=[self.avatar.id])]
|
||||
|
||||
calamity = getattr(self, "_calamity", "劫难")
|
||||
core_text = f"{self.avatar.name} 遭遇了{calamity}劫难,突破{'成功' if result_ok else '失败'}"
|
||||
events: list[Event] = [Event(self.world.month_stamp, core_text)]
|
||||
rel_ids = [self.avatar.id]
|
||||
other = getattr(self, "_calamity_other", None)
|
||||
if other is not None:
|
||||
try:
|
||||
rel_ids.append(other.id)
|
||||
except Exception:
|
||||
pass
|
||||
events: list[Event] = [Event(self.world.month_stamp, core_text, related_avatars=rel_ids)]
|
||||
|
||||
if True:
|
||||
# 故事参与者:本体 +(可选)相关角色
|
||||
desc = CALAMITY_DESCRIPTIONS.get(str(calamity), "")
|
||||
prompt = (STORY_PROMPT_BASE.format(calamity=str(calamity)) + (" " + desc if desc else "")).strip()
|
||||
story = StoryTeller.tell_from_actors(core_text, ("突破成功" if result_ok else "突破失败"), self.avatar, getattr(self, "_calamity_other", None), prompt=prompt)
|
||||
events.append(Event(self.world.month_stamp, story))
|
||||
events.append(Event(self.world.month_stamp, story, related_avatars=rel_ids))
|
||||
return events
|
||||
|
||||
# ——— 内部:劫难选择与关联角色 ———
|
||||
|
||||
@@ -58,7 +58,7 @@ class Cultivate(TimedAction):
|
||||
return True
|
||||
|
||||
def start(self) -> Event:
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {self.avatar.tile.region.name} 开始修炼")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {self.avatar.tile.region.name} 开始修炼", related_avatars=[self.avatar.id])
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class DevourMortals(TimedAction):
|
||||
return "DevourMortals" in legal
|
||||
|
||||
def start(self) -> Event:
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇开始吞噬凡人")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇开始吞噬凡人", related_avatars=[self.avatar.id])
|
||||
|
||||
def finish(self) -> list[Event]:
|
||||
return []
|
||||
|
||||
@@ -41,7 +41,7 @@ class Escape(InstantAction):
|
||||
|
||||
success = _r.random() < escape_rate
|
||||
result_text = "成功" if success else "失败"
|
||||
result_event = Event(self.world.month_stamp, f"{self.avatar.name} 试图从 {target.name} 逃离:{result_text}")
|
||||
result_event = Event(self.world.month_stamp, f"{self.avatar.name} 试图从 {target.name} 逃离:{result_text}", related_avatars=[self.avatar.id, target.id])
|
||||
EventHelper.push_pair(result_event, initiator=self.avatar, target=target, to_sidebar_once=True)
|
||||
if success:
|
||||
self._preempt_avatar(self.avatar)
|
||||
@@ -62,7 +62,10 @@ class Escape(InstantAction):
|
||||
def start(self, avatar_name: str) -> Event:
|
||||
target = self._find_avatar_by_name(avatar_name)
|
||||
target_name = target.name if target is not None else avatar_name
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 尝试从 {target_name} 逃离")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
rel_ids.append(target.id)
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 尝试从 {target_name} 逃离", related_avatars=rel_ids)
|
||||
|
||||
# InstantAction 已实现 step 完成
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class Harvest(TimedAction):
|
||||
|
||||
def start(self) -> Event:
|
||||
region = self.avatar.tile.region
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {region.name} 开始采集")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {region.name} 开始采集", related_avatars=[self.avatar.id])
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
|
||||
@@ -50,7 +50,14 @@ class MoveAwayFromAvatar(TimedAction):
|
||||
target_name = t.name
|
||||
except Exception:
|
||||
pass
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始远离 {target_name}")
|
||||
rel_ids = [self.avatar.id]
|
||||
try:
|
||||
t = self._find_avatar_by_name(avatar_name)
|
||||
if t is not None:
|
||||
rel_ids.append(t.id)
|
||||
except Exception:
|
||||
pass
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始远离 {target_name}", related_avatars=rel_ids)
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class MoveAwayFromRegion(InstantAction):
|
||||
return True
|
||||
|
||||
def start(self, region: str) -> Event:
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始离开 {region}")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始离开 {region}", related_avatars=[self.avatar.id])
|
||||
|
||||
# InstantAction 已实现 step 完成
|
||||
|
||||
|
||||
@@ -43,7 +43,10 @@ class MoveToAvatar(DefineAction, ActualActionMixin):
|
||||
def start(self, avatar_name: str) -> Event:
|
||||
target = self._get_target(avatar_name)
|
||||
target_name = target.name if target is not None else avatar_name
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始移动向 {target_name}")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
rel_ids.append(target.id)
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始移动向 {target_name}", related_avatars=rel_ids)
|
||||
|
||||
def step(self, avatar_name: str) -> ActionResult:
|
||||
self.execute(avatar_name=avatar_name)
|
||||
|
||||
@@ -109,7 +109,7 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
def start(self, region: Region | str) -> Event:
|
||||
r = self._resolve_region(region)
|
||||
region_name = r.name # 仅使用规范化后的区域名
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始移动向 {region_name}")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始移动向 {region_name}", related_avatars=[self.avatar.id])
|
||||
|
||||
def step(self, region: Region | str) -> ActionResult:
|
||||
self.execute(region=region)
|
||||
|
||||
@@ -33,7 +33,7 @@ class PlunderMortals(TimedAction):
|
||||
return self.avatar.alignment == Alignment.EVIL
|
||||
|
||||
def start(self) -> Event:
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇开始搜刮凡人")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇开始搜刮凡人", related_avatars=[self.avatar.id])
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
|
||||
@@ -53,13 +53,13 @@ class SelfHeal(TimedAction):
|
||||
region_name = getattr(region, "name", "宗门总部")
|
||||
# 重置累计量
|
||||
self._healed_total = 0
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {region_name} 开始静养疗伤")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {region_name} 开始静养疗伤", related_avatars=[self.avatar.id])
|
||||
|
||||
# TimedAction 已统一 step 逻辑
|
||||
|
||||
def finish(self) -> list[Event]:
|
||||
healed_total = int(getattr(self, "_healed_total", 0))
|
||||
# 统一用一次事件简要反馈
|
||||
return [Event(self.world.month_stamp, f"{self.avatar.name} 疗伤完成,HP已回满(本次恢复{healed_total}点,当前HP {self.avatar.hp})")]
|
||||
return [Event(self.world.month_stamp, f"{self.avatar.name} 疗伤完成,HP已回满(本次恢复{healed_total}点,当前HP {self.avatar.hp})", related_avatars=[self.avatar.id])]
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class Talk(InstantAction):
|
||||
def start(self) -> Event:
|
||||
self.observed_others = self._get_observed_others()
|
||||
# 记录开始事件
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 尝试与感知范围内的他人攀谈")
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 尝试与感知范围内的他人攀谈", related_avatars=[self.avatar.id])
|
||||
|
||||
def step(self) -> ActionResult:
|
||||
import random
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
event class
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
|
||||
from src.classes.calendar import Month, Year, MonthStamp
|
||||
|
||||
@@ -9,6 +10,8 @@ from src.classes.calendar import Month, Year, MonthStamp
|
||||
class Event:
|
||||
month_stamp: MonthStamp
|
||||
content: str
|
||||
# 相关角色ID列表;若与任何角色无关则为 None
|
||||
related_avatars: Optional[List[str]] = None
|
||||
|
||||
def __str__(self) -> str:
|
||||
year = self.month_stamp.get_year()
|
||||
|
||||
@@ -115,8 +115,8 @@ def try_trigger_fortune(avatar: Avatar) -> list[Event]:
|
||||
story = StoryTeller.tell_from_actors(event_text, res_text, avatar, prompt=story_prompt)
|
||||
|
||||
events: list[Event] = [
|
||||
Event(avatar.world.month_stamp, event_text),
|
||||
Event(avatar.world.month_stamp, story),
|
||||
Event(avatar.world.month_stamp, event_text, related_avatars=[avatar.id]),
|
||||
Event(avatar.world.month_stamp, story, related_avatars=[avatar.id]),
|
||||
]
|
||||
return events
|
||||
|
||||
|
||||
@@ -63,7 +63,10 @@ class Conversation(MutualAction):
|
||||
def start(self, target_avatar: "Avatar|str", **kwargs) -> Event:
|
||||
target = self._get_target_avatar(target_avatar)
|
||||
target_name = target.name if target is not None else str(target_avatar)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target_name} 开始交谈")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
rel_ids.append(target.id)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target_name} 开始交谈", related_avatars=rel_ids)
|
||||
# 写入历史即可,内容事件稍后生成
|
||||
self.avatar.add_event(event, to_sidebar=False)
|
||||
if target is not None:
|
||||
@@ -89,7 +92,7 @@ class Conversation(MutualAction):
|
||||
# 仅当明确接受时才记录对话与关系;其余一律视为拒绝
|
||||
if fb == "Talk":
|
||||
if talk_content:
|
||||
content_event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target.name} 的交谈:{talk_content}")
|
||||
content_event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target.name} 的交谈:{talk_content}", related_avatars=[self.avatar.id, target.id])
|
||||
# 进入侧栏一次,并写入双方历史
|
||||
EventHelper.push_pair(content_event, initiator=self.avatar, target=target, to_sidebar_once=True)
|
||||
|
||||
@@ -97,12 +100,12 @@ class Conversation(MutualAction):
|
||||
rel = Relation.from_chinese(into_relation_str)
|
||||
if rel is not None:
|
||||
self.avatar.set_relation(target, rel)
|
||||
set_event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target.name} 的关系变为:{relation_display_names.get(rel, str(rel))}")
|
||||
set_event = Event(self.world.month_stamp, f"{self.avatar.name} 与 {target.name} 的关系变为:{relation_display_names.get(rel, str(rel))}", related_avatars=[self.avatar.id, target.id])
|
||||
EventHelper.push_pair(set_event, initiator=self.avatar, target=target, to_sidebar_once=True)
|
||||
|
||||
return ActionResult(status=ActionStatus.COMPLETED, events=[])
|
||||
else:
|
||||
feedback_event = Event(self.world.month_stamp, f"{target.name} 拒绝与 {self.avatar.name} 交谈")
|
||||
feedback_event = Event(self.world.month_stamp, f"{target.name} 拒绝与 {self.avatar.name} 交谈", related_avatars=[self.avatar.id, target.id])
|
||||
EventHelper.push_pair(feedback_event, initiator=self.avatar, target=target, to_sidebar_once=True)
|
||||
return ActionResult(status=ActionStatus.COMPLETED, events=[])
|
||||
|
||||
|
||||
@@ -51,7 +51,10 @@ class DualCultivation(MutualAction):
|
||||
def start(self, target_avatar: "Avatar|str") -> Event:
|
||||
target = self._get_target_avatar(target_avatar)
|
||||
target_name = target.name if target is not None else str(target_avatar)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 邀请 {target_name} 进行双修")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
rel_ids.append(target.id)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 邀请 {target_name} 进行双修", related_avatars=rel_ids)
|
||||
# 仅写入历史
|
||||
self.avatar.add_event(event, to_sidebar=False)
|
||||
if target is not None:
|
||||
@@ -102,17 +105,17 @@ class DualCultivation(MutualAction):
|
||||
if success:
|
||||
gain = int(self._dual_exp_gain)
|
||||
result_text = f"{self.avatar.name} 与 {target.name} 成功双修,{self.avatar.name} 获得修为经验 +{gain} 点"
|
||||
result_event = Event(self.world.month_stamp, result_text)
|
||||
result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id])
|
||||
events.append(result_event)
|
||||
|
||||
# 生成恋爱/双修小故事:使用 StoryTeller 便捷方法
|
||||
start_text = self._start_event_content or result_event.content
|
||||
story = StoryTeller.tell_from_actors(start_text, result_event.content, self.avatar, target, prompt=self.STORY_PROMPT)
|
||||
story_event = Event(self.world.month_stamp, story)
|
||||
story_event = Event(self.world.month_stamp, story, related_avatars=[self.avatar.id, target.id])
|
||||
events.append(story_event)
|
||||
else:
|
||||
result_text = f"{target.name} 拒绝了与 {self.avatar.name} 的双修"
|
||||
result_event = Event(self.world.month_stamp, result_text)
|
||||
result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id])
|
||||
events.append(result_event)
|
||||
|
||||
return events
|
||||
|
||||
@@ -134,7 +134,7 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin):
|
||||
self._settle_feedback(target_avatar, feedback)
|
||||
# 3) 反馈事件(进入侧边栏与双方历史,中文化文案)
|
||||
fb_label = self.FEEDBACK_LABELS.get(str(feedback).strip(), str(feedback))
|
||||
feedback_event = Event(self.world.month_stamp, f"{target_avatar.name} 对 {self.avatar.name} 的反馈:{fb_label}")
|
||||
feedback_event = Event(self.world.month_stamp, f"{target_avatar.name} 对 {self.avatar.name} 的反馈:{fb_label}", related_avatars=[self.avatar.id, target_avatar.id])
|
||||
# 侧边栏仅推送一次,另一侧仅写入历史,避免重复
|
||||
EventHelper.push_pair(feedback_event, initiator=self.avatar, target=target_avatar, to_sidebar_once=True)
|
||||
# 4) 记录历史(文本记录)
|
||||
@@ -160,7 +160,10 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin):
|
||||
target = self._get_target_avatar(target_avatar)
|
||||
target_name = target.name if target is not None else str(target_avatar)
|
||||
action_name = getattr(self, 'ACTION_NAME', self.name)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起 {action_name}")
|
||||
rel_ids = [self.avatar.id]
|
||||
if target is not None:
|
||||
rel_ids.append(target.id)
|
||||
event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起 {action_name}", related_avatars=rel_ids)
|
||||
# 仅写入历史,避免与提交阶段重复推送到侧边栏
|
||||
self.avatar.add_event(event, to_sidebar=False)
|
||||
if target is not None:
|
||||
|
||||
Reference in New Issue
Block a user