update treasure to weapon and auxiliary
This commit is contained in:
@@ -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]
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 字典:
|
||||||
|
|||||||
@@ -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] - 合法动作列表
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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.
|
Reference in New Issue
Block a user