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
# 记录升华事件
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]
))

View File

@@ -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)

View File

@@ -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 字典:

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