update treasure to weapon and auxiliary

This commit is contained in:
bridge
2025-11-13 02:19:35 +08:00
parent 3d60df4dbf
commit f8c4f84c7a
5 changed files with 132 additions and 22 deletions

View File

@@ -39,8 +39,8 @@ class NurtureWeapon(TimedAction):
self.avatar.weapon_proficiency = old_proficiency self.avatar.weapon_proficiency = old_proficiency
# 记录升华事件 # 记录升华事件
from src.classes.event import Event from src.classes.event import Event
self.avatar.world.add_event(Event( self.avatar.add_event(Event(
self.avatar.world.month_stamp, self.world.month_stamp,
f"{self.avatar.name} 温养{old_weapon_name}时,兵器灵性大增,升华为{treasure_weapon.name}", f"{self.avatar.name} 温养{old_weapon_name}时,兵器灵性大增,升华为{treasure_weapon.name}",
related_avatars=[self.avatar.id] related_avatars=[self.avatar.id]
)) ))

View File

@@ -24,7 +24,7 @@ from src.classes.age import Age
from src.classes.event import NULL_EVENT, Event 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.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.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.alignment import Alignment
from src.classes.persona import Persona, personas_by_id, get_random_compatible_personas from src.classes.persona import Persona, personas_by_id, get_random_compatible_personas
from src.classes.item import Item from src.classes.item import Item
@@ -156,34 +156,41 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
merged: dict[str, object] = defaultdict(str) merged: dict[str, object] = defaultdict(str)
# 来自宗门 # 来自宗门
if self.sect is not None: 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 # 来自特质persona
for persona in self.personas: 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: 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: 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: 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(...)" 形式给出 # 评估动态效果表达式:值以 "eval(...)" 形式给出
evaluated: dict[str, object] = {} final: dict[str, object] = {}
for k, v in merged.items(): for k, v in merged.items():
if isinstance(v, str): if isinstance(v, str):
s = v.strip() s = v.strip()
if s.startswith("eval(") and s.endswith(")"): if s.startswith("eval(") and s.endswith(")"):
expr = s[5:-1] expr = s[5:-1]
evaluated[k] = eval(expr, {"__builtins__": {}}, {"avatar": self}) final[k] = eval(expr, {"__builtins__": {}}, {"avatar": self})
continue continue
evaluated[k] = v final[k] = v
return evaluated return final
def __hash__(self) -> int: def __hash__(self) -> int:
@@ -790,6 +797,9 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
Args: Args:
amount: 增加的熟练度值 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)

View File

@@ -1,29 +1,103 @@
from __future__ import annotations from __future__ import annotations
import json 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' 时返回 {} - value 为 None/空字符串/'nan' 时返回 {}
- 解析失败或结果非 dict 返回 {} - 解析失败返回 {}
- 支持返回 dict单个effect或 list[dict]多个条件effect
""" """
if value is None: if value is None:
return {} return {}
if isinstance(value, dict): if isinstance(value, (dict, list)):
return value return value
s = str(value).strip() s = str(value).strip()
if not s or s == "nan": if not s or s == "nan":
return {} return {}
try: try:
obj = json.loads(s) obj = json.loads(s)
return obj if isinstance(obj, dict) else {} if isinstance(obj, (dict, list)):
return obj
return {}
except Exception: except Exception:
return {} 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]: def _merge_effects(base: dict[str, object], addition: dict[str, object]) -> dict[str, object]:
""" """
合并两个 effects 字典: 合并两个 effects 字典:

View File

@@ -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" LEGAL_ACTIONS = "legal_actions"
""" """
@@ -198,6 +207,9 @@ ALL_EFFECTS = [
# 奇遇相关 # 奇遇相关
"extra_fortune_probability", # float - 额外奇遇概率 "extra_fortune_probability", # float - 额外奇遇概率
# 兵器相关
"extra_weapon_proficiency_gain", # float - 额外兵器熟练度增长倍率
# 特殊权限 # 特殊权限
"legal_actions", # list[str] - 合法动作列表 "legal_actions", # list[str] - 合法动作列表
] ]

View File

@@ -31,7 +31,7 @@ id,name,exclusion_names,desc,rarity,condition,effects
29,嫉妒,友爱;热情,你对在修为、外貌或财富等方面远超于你的人容易产生敌意,更倾向对其冷淡、挑衅或打压。,N, 29,嫉妒,友爱;热情,你对在修为、外貌或财富等方面远超于你的人容易产生敌意,更倾向对其冷淡、挑衅或打压。,N,
30,穿越者,,你来自现代社会怀念现代社会的一切你的思考thinking必须是现代化的思考,SR, 30,穿越者,,你来自现代社会怀念现代社会的一切你的思考thinking必须是现代化的思考,SR,
31,气运之子,,天生气运加身,更易遇到奇遇,战斗力也略有提升,SSR,,"{""extra_fortune_probability"": 0.05, ""extra_battle_strength_points"": 2, ""extra_breakthrough_success_rate"": 0.05}" 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, 33,散修,,无宗门庇护,四处寻找机缘,警惕性高,善于观察周围环境以自保求存。,N,
34,城府深,鲁莽;热情;外向,深藏不露,行事谨慎,善于算计。你不轻易暴露实力和想法,观察力敏锐,总在暗中盘算。,R, 34,城府深,鲁莽;热情;外向,深藏不露,行事谨慎,善于算计。你不轻易暴露实力和想法,观察力敏锐,总在暗中盘算。,R,
35,忠诚,孤僻;淡漠;刻薄,重承诺守信义,对认定的人绝不背叛,愿为之赴死。你视背叛为最大耻辱。,R, 35,忠诚,孤僻;淡漠;刻薄,重承诺守信义,对认定的人绝不背叛,愿为之赴死。你视背叛为最大耻辱。,R,
@@ -41,3 +41,17 @@ id,name,exclusion_names,desc,rarity,condition,effects
39,体修,惜命;胆小,专注肉身淬炼,体魄强健,近战无敌。你相信肉身才是修行的根本,法术只是旁门左道。,R, 39,体修,惜命;胆小,专注肉身淬炼,体魄强健,近战无敌。你相信肉身才是修行的根本,法术只是旁门左道。,R,
40,炼丹师,好斗,精通丹道,对灵药敏感,擅长炼制丹药。你认为丹药是修行的关键,战斗并非你的专长。,R, 40,炼丹师,好斗,精通丹道,对灵药敏感,擅长炼制丹药。你认为丹药是修行的关键,战斗并非你的专长。,R,
41,福缘深厚,,天生福运,逢凶化吉。虽不如气运之子,但也常有小幸运眷顾。,SR,,"{""extra_fortune_probability"": 0.02}" 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""}]"
Can't render this file because it contains an unexpected character in line 26 and column 136.