From 0ec534f8c1995163489a20ae5c8282f390625ab0 Mon Sep 17 00:00:00 2001 From: bridge Date: Thu, 16 Oct 2025 01:14:18 +0800 Subject: [PATCH] add breakthrough story --- src/classes/action/breakthrough.py | 75 ++++++++++++++++++++++++++---- static/game_configs/persona.csv | 2 +- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/classes/action/breakthrough.py b/src/classes/action/breakthrough.py index 398e12c..20d654b 100644 --- a/src/classes/action/breakthrough.py +++ b/src/classes/action/breakthrough.py @@ -3,6 +3,27 @@ from __future__ import annotations import random from src.classes.action import TimedAction from src.classes.event import Event +from src.classes.cultivation import Realm +from src.classes.story_teller import StoryTeller +from src.classes.relation import Relation + +# —— 配置:哪些“出发境界”会生成突破小故事(global var)—— +ALLOW_STORY_FROM_REALMS: list[Realm] = [ + Realm.Foundation_Establishment, # 筑基 + Realm.Core_Formation, # 金丹 +] + +# 故事提示词(global var) +STORY_PROMPT_BASE = "以古风、凝练、不炫技的笔触,描绘修士历经{calamity}劫时的心境与取舍,篇幅60~120字。" + +# 劫难说明(global var) +CALAMITY_DESCRIPTIONS: dict[str, str] = { + "心魔": "心念起伏,自我否定与执念缠斗,外寂而内喧。", + "雷劫": "天威如潮,电光凝成纹理,压迫骨血与神识。", + "肉身": "筋骨皮膜重塑,真气磨砺经脉,疼痛与新生并至。", + "仇家": "旧怨不散,刀光在心底回响,一念之差改写因果。", + "情劫": "柔情即刃,难舍难分,念头被拉回人间烟火。", +} from src.classes.hp_and_mp import HP_MAX_BY_REALM, MP_MAX_BY_REALM from src.classes.root import extra_breakthrough_success_rate @@ -17,6 +38,7 @@ class Breakthrough(TimedAction): COMMENT = "尝试突破境界(成功增加寿元上限,失败折损寿元上限;境界越高,成功率越低。)" DOABLES_REQUIREMENTS = "角色处于瓶颈时" PARAMS = {} + # 保留类级常量声明,实际读取模块级配置 def calc_success_rate(self) -> float: """ @@ -84,22 +106,59 @@ class Breakthrough(TimedAction): return self.avatar.cultivation_progress.can_break_through() def start(self) -> Event: - # 清理上次残留的结果状态(防御性) + # 清理状态 self._last_result = None self._success_rate_cached = None + # 预判是否生成故事与选择劫难 + old_realm = self.avatar.cultivation_progress.realm + # 仅基于出发境界判断是否生成故事 + self._gen_story = old_realm in ALLOW_STORY_FROM_REALMS + self._calamity = self._choose_calamity() + self._calamity_other = self._choose_related_avatar(self._calamity) return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界") # TimedAction 已统一 step 逻辑 def finish(self) -> list[Event]: - # 根据执行阶段记录的 _last_result 生成简洁完成事件 res = getattr(self, "_last_result", None) - if isinstance(res, tuple) and res: - if res[0] == "success": - return [Event(self.world.month_stamp, f"{self.avatar.name} 突破成功")] - elif res[0] == "fail": - return [Event(self.world.month_stamp, f"{self.avatar.name} 突破失败")] + if not (isinstance(res, tuple) and res): + return [] + calamity = getattr(self, "_calamity", "劫难") + result_ok = res[0] == "success" + core_text = f"{self.avatar.name} 遭遇了{calamity}劫难,突破{'成功' if result_ok else '失败'}" + events: list[Event] = [Event(self.world.month_stamp, core_text)] + + if getattr(self, "_gen_story", False): + # 故事参与者:本体 +(可选)相关角色 + if getattr(self, "_calamity_other", None) is not None: + avatar_infos = StoryTeller.build_avatar_infos(self.avatar, self._calamity_other) else: - raise ValueError(f"Unknown result: {res}") + avatar_infos = StoryTeller.build_avatar_infos(self.avatar) + desc = CALAMITY_DESCRIPTIONS.get(str(calamity), "") + prompt = (STORY_PROMPT_BASE.format(calamity=str(calamity)) + (" " + desc if desc else "")).strip() + story = StoryTeller.tell_story(avatar_infos, core_text, ("突破成功" if result_ok else "突破失败"), prompt) + events.append(Event(self.world.month_stamp, story)) + return events + + # ——— 内部:劫难选择与关联角色 ——— + def _choose_calamity(self) -> str: + base = ["心魔", "雷劫", "肉身"] + rels = getattr(self.avatar, "relations", {}) + has_enemy = any(rel is Relation.ENEMY for rel in rels.values()) + has_lover = any(rel is Relation.LOVERS for rel in rels.values()) + if has_enemy: + base.append("仇家") + if has_lover: + base.append("情劫") + return random.choice(base) + + def _choose_related_avatar(self, calamity: str): + if calamity not in ("仇家", "情劫"): + return None + target_rel = Relation.ENEMY if calamity == "仇家" else Relation.LOVERS + candidates = [other for other, rel in self.avatar.relations.items() if rel is target_rel] + if not candidates: + return None + return random.choice(candidates) diff --git a/static/game_configs/persona.csv b/static/game_configs/persona.csv index f82bcb3..84b53ad 100644 --- a/static/game_configs/persona.csv +++ b/static/game_configs/persona.csv @@ -11,7 +11,7 @@ id,name,exclusion_ids,desc,weight,condition 9,沉思,2,你总是会深思熟虑,思考问题比较有哲理。,1, 10,惜命,4;24;25,你总是会珍惜自己的生命,不会轻易冒险。,1, 11,友爱,13;14;15;12;24;25,你重视同伴与和谐,乐于助人,倾向通过协作与沟通化解矛盾。,1, -12,复仇,11;14,你绝不轻易放下仇怨,为了复仇愿意付出代价与时间。你必须立刻进行复仇行动。,1000, +12,复仇,11;14,你绝不轻易放下仇怨,为了复仇愿意付出代价与时间。你必须立刻进行复仇行动。,1, 13,孤僻,11,你喜欢独处,避免与人深交,更信赖自己的判断与行动。,1, 14,淡漠,11;12;15;24;25,你情感克制,对外界冷静疏离,不轻易被他人或事件影响。,1, 15,好斗,11;14;10;17,你直面冲突,偏好以力量与对抗解决问题,越挫越勇。,1,