From f8c4f84c7a672cb2da921c76f78f4e4e3f5201c0 Mon Sep 17 00:00:00 2001 From: bridge Date: Thu, 13 Nov 2025 02:19:35 +0800 Subject: [PATCH] update treasure to weapon and auxiliary --- src/classes/action/nurture_weapon.py | 4 +- src/classes/avatar.py | 36 +++++++----- src/classes/effect.py | 86 ++++++++++++++++++++++++++-- src/classes/effects.py | 12 ++++ static/game_configs/persona.csv | 16 +++++- 5 files changed, 132 insertions(+), 22 deletions(-) diff --git a/src/classes/action/nurture_weapon.py b/src/classes/action/nurture_weapon.py index 02e8708..4097bb8 100644 --- a/src/classes/action/nurture_weapon.py +++ b/src/classes/action/nurture_weapon.py @@ -39,8 +39,8 @@ class NurtureWeapon(TimedAction): self.avatar.weapon_proficiency = old_proficiency # 记录升华事件 from src.classes.event import Event - self.avatar.world.add_event(Event( - self.avatar.world.month_stamp, + self.avatar.add_event(Event( + self.world.month_stamp, f"{self.avatar.name} 温养{old_weapon_name}时,兵器灵性大增,升华为{treasure_weapon.name}!", related_avatars=[self.avatar.id] )) diff --git a/src/classes/avatar.py b/src/classes/avatar.py index e657747..e32d926 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -24,7 +24,7 @@ from src.classes.age import Age from src.classes.event import NULL_EVENT, Event from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_NAME_PARAMS_PAIRS, ACTION_NAME_PARAMS_PAIR from src.classes.action_runtime import ActionPlan, ActionInstance -from src.classes.effect import _merge_effects +from src.classes.effect import _merge_effects, _evaluate_conditional_effect from src.classes.alignment import Alignment from src.classes.persona import Persona, personas_by_id, get_random_compatible_personas from src.classes.item import Item @@ -156,34 +156,41 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin): merged: dict[str, object] = defaultdict(str) # 来自宗门 if self.sect is not None: - merged = _merge_effects(merged, self.sect.effects) + evaluated = _evaluate_conditional_effect(self.sect.effects, self) + merged = _merge_effects(merged, evaluated) # 来自功法 - merged = _merge_effects(merged, self.technique.effects) + evaluated = _evaluate_conditional_effect(self.technique.effects, self) + merged = _merge_effects(merged, evaluated) # 来自灵根 - merged = _merge_effects(merged, self.root.effects) + evaluated = _evaluate_conditional_effect(self.root.effects, self) + merged = _merge_effects(merged, evaluated) # 来自特质(persona) for persona in self.personas: - merged = _merge_effects(merged, persona.effects) + evaluated = _evaluate_conditional_effect(persona.effects, self) + merged = _merge_effects(merged, evaluated) # 来自兵器 if self.weapon is not None: - merged = _merge_effects(merged, self.weapon.effects) + evaluated = _evaluate_conditional_effect(self.weapon.effects, self) + merged = _merge_effects(merged, evaluated) # 来自辅助装备 if self.auxiliary is not None: - merged = _merge_effects(merged, self.auxiliary.effects) + evaluated = _evaluate_conditional_effect(self.auxiliary.effects, self) + merged = _merge_effects(merged, evaluated) # 来自灵兽 if self.spirit_animal is not None: - merged = _merge_effects(merged, self.spirit_animal.effects) + evaluated = _evaluate_conditional_effect(self.spirit_animal.effects, self) + merged = _merge_effects(merged, evaluated) # 评估动态效果表达式:值以 "eval(...)" 形式给出 - evaluated: dict[str, object] = {} + final: dict[str, object] = {} for k, v in merged.items(): if isinstance(v, str): s = v.strip() if s.startswith("eval(") and s.endswith(")"): expr = s[5:-1] - evaluated[k] = eval(expr, {"__builtins__": {}}, {"avatar": self}) + final[k] = eval(expr, {"__builtins__": {}}, {"avatar": self}) continue - evaluated[k] = v - return evaluated + final[k] = v + return final def __hash__(self) -> int: @@ -790,6 +797,9 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin): Args: amount: 增加的熟练度值 """ - self.weapon_proficiency = min(100.0, self.weapon_proficiency + amount) + # 应用extra_weapon_proficiency_gain效果(倍率加成) + gain_multiplier = 1.0 + self.effects.get("extra_weapon_proficiency_gain", 0.0) + actual_amount = amount * gain_multiplier + self.weapon_proficiency = min(100.0, self.weapon_proficiency + actual_amount) diff --git a/src/classes/effect.py b/src/classes/effect.py index 0df3ae0..4fb0b6e 100644 --- a/src/classes/effect.py +++ b/src/classes/effect.py @@ -1,29 +1,103 @@ from __future__ import annotations import json -from typing import Any, Callable, Optional +from typing import Any, Callable, Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from src.classes.avatar import Avatar -def load_effect_from_str(value: object) -> dict[str, Any]: +def load_effect_from_str(value: object) -> dict[str, Any] | list[dict[str, Any]]: """ - 将 effects 字段解析为 dict(仅支持标准 JSON 字符串)。 + 将 effects 字段解析为 dict 或 list(仅支持标准 JSON 字符串)。 - value 为 None/空字符串/'nan' 时返回 {} - - 解析失败或结果非 dict 返回 {} + - 解析失败时返回 {} + - 支持返回 dict(单个effect)或 list[dict](多个条件effect) """ if value is None: return {} - if isinstance(value, dict): + if isinstance(value, (dict, list)): return value s = str(value).strip() if not s or s == "nan": return {} try: obj = json.loads(s) - return obj if isinstance(obj, dict) else {} + if isinstance(obj, (dict, list)): + return obj + return {} except Exception: return {} +def _evaluate_conditional_effect(effect: dict[str, Any] | list[dict[str, Any]], avatar: "Avatar") -> dict[str, Any]: + """ + 评估带条件的effect,返回实际生效的effect dict。 + + 支持三种格式: + 1. 普通dict(无条件): {"extra_battle_strength_points": 1} + 2. 带条件的dict: {"extra_battle_strength_points": 2, "when": "avatar.weapon.type == WeaponType.SWORD"} + 3. 条件数组: [{"extra_battle_strength_points": 2, "when": "..."}, {...}] + + Args: + effect: 原始effect配置(dict或list) + avatar: 当前角色对象 + + Returns: + 评估后实际生效的effect dict(合并所有满足条件的effects) + """ + from src.classes.weapon_type import WeaponType + from src.classes.equipment_grade import EquipmentGrade + from src.classes.alignment import Alignment + + # 构建安全的eval上下文 + safe_context = { + "__builtins__": {}, + "avatar": avatar, + "WeaponType": WeaponType, + "EquipmentGrade": EquipmentGrade, + "Alignment": Alignment, + } + + def _check_condition(when_expr: str) -> bool: + """检查条件表达式是否为真""" + if not when_expr: + return True + try: + return bool(eval(when_expr, safe_context, {})) + except Exception: + # 条件评估失败时视为False + return False + + def _process_single_effect(eff: dict[str, Any]) -> dict[str, Any]: + """处理单个effect dict,检查条件并返回生效的部分""" + if not isinstance(eff, dict): + return {} + + when_expr = eff.get("when") + if when_expr is None: + # 无条件effect,直接返回 + return eff + + # 有条件effect,检查条件 + if not _check_condition(when_expr): + return {} + + # 条件满足,返回除了when之外的所有字段 + return {k: v for k, v in eff.items() if k != "when"} + + # 处理list格式(多个条件effect) + if isinstance(effect, list): + result = {} + for item in effect: + evaluated = _process_single_effect(item) + result = _merge_effects(result, evaluated) + return result + + # 处理dict格式(单个effect) + return _process_single_effect(effect) + + def _merge_effects(base: dict[str, object], addition: dict[str, object]) -> dict[str, object]: """ 合并两个 effects 字典: diff --git a/src/classes/effects.py b/src/classes/effects.py index 472115f..0f1701a 100644 --- a/src/classes/effects.py +++ b/src/classes/effects.py @@ -129,6 +129,15 @@ EXTRA_FORTUNE_PROBABILITY = "extra_fortune_probability" 说明: 增加触发奇遇事件的概率 """ +# --- 兵器相关 --- +EXTRA_WEAPON_PROFICIENCY_GAIN = "extra_weapon_proficiency_gain" +""" +额外兵器熟练度增长速度 +类型: float (倍率,如 0.5 表示增加50%,1.0 表示翻倍) +结算: src/classes/action/nurture_weapon.py 和战斗相关代码 +说明: 提升兵器熟练度增长速度的倍率 +""" + # --- 特殊权限 --- LEGAL_ACTIONS = "legal_actions" """ @@ -198,6 +207,9 @@ ALL_EFFECTS = [ # 奇遇相关 "extra_fortune_probability", # float - 额外奇遇概率 + # 兵器相关 + "extra_weapon_proficiency_gain", # float - 额外兵器熟练度增长倍率 + # 特殊权限 "legal_actions", # list[str] - 合法动作列表 ] diff --git a/static/game_configs/persona.csv b/static/game_configs/persona.csv index 00a8658..8eb2a73 100644 --- a/static/game_configs/persona.csv +++ b/static/game_configs/persona.csv @@ -31,7 +31,7 @@ id,name,exclusion_names,desc,rarity,condition,effects 29,嫉妒,友爱;热情,你对在修为、外貌或财富等方面远超于你的人容易产生敌意,更倾向对其冷淡、挑衅或打压。,N, 30,穿越者,,你来自现代社会,怀念现代社会的一切,你的思考(thinking)必须是现代化的思考,SR, 31,气运之子,,天生气运加身,更易遇到奇遇,战斗力也略有提升,SSR,,"{""extra_fortune_probability"": 0.05, ""extra_battle_strength_points"": 2, ""extra_breakthrough_success_rate"": 0.05}" -32,剑痴,怠惰;胆小,以剑入道,剑即是命。你认为剑道至上,战力强悍,但对剑道之外的事物兴趣寥寥。,R, +32,剑痴,怠惰;胆小,以剑入道,剑即是命。你认为剑道至上,战力强悍,但对剑道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.SWORD""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.SWORD""}]" 33,散修,,无宗门庇护,四处寻找机缘,警惕性高,善于观察周围环境以自保求存。,N, 34,城府深,鲁莽;热情;外向,深藏不露,行事谨慎,善于算计。你不轻易暴露实力和想法,观察力敏锐,总在暗中盘算。,R, 35,忠诚,孤僻;淡漠;刻薄,重承诺守信义,对认定的人绝不背叛,愿为之赴死。你视背叛为最大耻辱。,R, @@ -41,3 +41,17 @@ id,name,exclusion_names,desc,rarity,condition,effects 39,体修,惜命;胆小,专注肉身淬炼,体魄强健,近战无敌。你相信肉身才是修行的根本,法术只是旁门左道。,R, 40,炼丹师,好斗,精通丹道,对灵药敏感,擅长炼制丹药。你认为丹药是修行的关键,战斗并非你的专长。,R, 41,福缘深厚,,天生福运,逢凶化吉。虽不如气运之子,但也常有小幸运眷顾。,SR,,"{""extra_fortune_probability"": 0.02}" +42,剑修,怠惰,对剑道有着深厚的兴趣和独特的天赋,持剑修炼时事半功倍。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.SWORD""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.SWORD""}]" +43,刀修,怠惰,专精刀法,对刀道有着独特的理解,持刀修炼时事半功倍。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.SABER""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.SABER""}]" +44,枪修,怠惰,精通枪法,百兵之王在手,修炼速度远超常人。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.SPEAR""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.SPEAR""}]" +45,棍修,怠惰,棍棒在手,天下我有。对棍法有着天生的悟性。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.STAFF""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.STAFF""}]" +46,音律大师,怠惰,精通音律之道,琴笛在手,可攻可守,修炼速度远超常人。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.ZITHER or avatar.weapon.type == WeaponType.FLUTE""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.ZITHER or avatar.weapon.type == WeaponType.FLUTE""}]" +47,暗器高手,怠惰,擅长使用暗器,出手诡秘莫测,修炼暗器技巧时事半功倍。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.HIDDEN_WEAPON""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.HIDDEN_WEAPON""}]" +48,扇修,怠惰,精通扇法,举手投足间尽显风流,持扇修炼时事半功倍。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.FAN""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.FAN""}]" +49,鞭修,怠惰,精通鞭法,软兵器在手,刚柔并济,修炼速度远超常人。,R,,"[{""extra_weapon_proficiency_gain"": 0.5, ""when"": ""avatar.weapon.type == WeaponType.WHIP""}, {""extra_battle_strength_points"": 1, ""when"": ""avatar.weapon.type == WeaponType.WHIP""}]" +50,刀痴,怠惰;胆小,以刀入道,刀即是命。你认为刀法至上,战力强悍,但对刀道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.SABER""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.SABER""}]" +51,枪痴,怠惰;胆小,以枪入道,枪即是命。你认为枪法至上,战力强悍,但对枪道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.SPEAR""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.SPEAR""}]" +52,棍圣,怠惰;胆小,以棍入道,棍即是命。棍法通神,一棍在手,天下无敌,但对棍道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.STAFF""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.STAFF""}]" +53,扇痴,怠惰;胆小,以扇入道,扇即是命。你认为扇法至上,战力强悍,但对扇道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.FAN""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.FAN""}]" +54,鞭痴,怠惰;胆小,以鞭入道,鞭即是命。你认为鞭法至上,战力强悍,但对鞭道之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.WHIP""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.WHIP""}]" +55,暗影宗师,怠惰;胆小,暗器之道登峰造极,杀人于无形。出手必见血,战力惊人,但对暗器之外的事物兴趣寥寥。,SR,,"[{""extra_weapon_proficiency_gain"": 1.0, ""when"": ""avatar.weapon.type == WeaponType.HIDDEN_WEAPON""}, {""extra_battle_strength_points"": 3, ""when"": ""avatar.weapon.type == WeaponType.HIDDEN_WEAPON""}]"