update celestial phenon
This commit is contained in:
@@ -180,6 +180,10 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
|
||||
if self.spirit_animal is not None:
|
||||
evaluated = _evaluate_conditional_effect(self.spirit_animal.effects, self)
|
||||
merged = _merge_effects(merged, evaluated)
|
||||
# 来自天地灵机(世界级buff/debuff)
|
||||
if self.world.current_phenomenon is not None:
|
||||
evaluated = _evaluate_conditional_effect(self.world.current_phenomenon.effects, self)
|
||||
merged = _merge_effects(merged, evaluated)
|
||||
# 评估动态效果表达式:值以 "eval(...)" 形式给出
|
||||
final: dict[str, object] = {}
|
||||
for k, v in merged.items():
|
||||
|
||||
116
src/classes/celestial_phenomenon.py
Normal file
116
src/classes/celestial_phenomenon.py
Normal file
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
天地灵机系统
|
||||
=============
|
||||
|
||||
天地灵机是影响整个修仙世界的天象异动,提供全局性的buff/debuff。
|
||||
|
||||
特点:
|
||||
- 不绑定任何角色,属于世界事件
|
||||
- 定期变化(默认5年一次)
|
||||
- 支持条件判断(如针对特定灵根、兵器类型等)
|
||||
- 使用effect系统,与角色自身effects合并
|
||||
|
||||
扩展性:
|
||||
- 未来可支持多天象并存(主天象+次天象)
|
||||
- 未来可支持特殊事件触发天象变化(如飞升、大战等)
|
||||
- 未来可支持地域性天象(只影响特定区域/宗门)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
from src.utils.df import game_configs
|
||||
from src.classes.effect import load_effect_from_str
|
||||
from src.classes.rarity import Rarity, get_rarity_from_str
|
||||
|
||||
|
||||
@dataclass
|
||||
class CelestialPhenomenon:
|
||||
"""
|
||||
天地灵机(天象异动)
|
||||
|
||||
字段与 static/game_configs/celestial_phenomenon.csv 对应:
|
||||
- id: 唯一标识符
|
||||
- name: 天象名称(修仙风格)
|
||||
- rarity: 稀有度(N/R/SR/SSR),决定显示颜色和出现概率
|
||||
- effects: JSON格式的效果配置,支持条件判断
|
||||
- desc: 天象描述文字(用于UI显示和事件生成)
|
||||
- duration_years: 持续年限(默认5年)
|
||||
"""
|
||||
id: int
|
||||
name: str
|
||||
rarity: Rarity
|
||||
effects: dict[str, object]
|
||||
desc: str
|
||||
duration_years: int
|
||||
|
||||
@property
|
||||
def weight(self) -> float:
|
||||
"""根据稀有度获取出现概率权重"""
|
||||
return self.rarity.weight
|
||||
|
||||
def get_info(self) -> str:
|
||||
"""获取简略信息"""
|
||||
return self.name
|
||||
|
||||
def get_detailed_info(self) -> str:
|
||||
"""获取详细信息"""
|
||||
return f"{self.name}({self.desc})"
|
||||
|
||||
|
||||
def _load_celestial_phenomena() -> dict[int, CelestialPhenomenon]:
|
||||
"""从配表加载天地灵机数据"""
|
||||
phenomena_by_id: dict[int, CelestialPhenomenon] = {}
|
||||
|
||||
if "celestial_phenomenon" not in game_configs:
|
||||
return phenomena_by_id
|
||||
|
||||
phenomenon_df = game_configs["celestial_phenomenon"]
|
||||
for _, row in phenomenon_df.iterrows():
|
||||
# 解析稀有度
|
||||
rarity_val = row.get("rarity", "N")
|
||||
rarity_str = str(rarity_val).strip().upper()
|
||||
rarity = get_rarity_from_str(rarity_str) if rarity_str and rarity_str != "NAN" else get_rarity_from_str("N")
|
||||
|
||||
# 解析effects
|
||||
raw_effects_val = row.get("effects", "")
|
||||
effects = load_effect_from_str(raw_effects_val)
|
||||
|
||||
# 解析持续年限(默认5年)
|
||||
duration_years = int(row.get("duration_years", 5))
|
||||
|
||||
phenomenon = CelestialPhenomenon(
|
||||
id=int(row["id"]),
|
||||
name=str(row["name"]),
|
||||
rarity=rarity,
|
||||
effects=effects,
|
||||
desc=str(row["desc"]),
|
||||
duration_years=duration_years,
|
||||
)
|
||||
phenomena_by_id[phenomenon.id] = phenomenon
|
||||
|
||||
return phenomena_by_id
|
||||
|
||||
|
||||
# 从配表加载天地灵机数据
|
||||
celestial_phenomena_by_id = _load_celestial_phenomena()
|
||||
|
||||
|
||||
def get_random_celestial_phenomenon() -> Optional[CelestialPhenomenon]:
|
||||
"""
|
||||
按权重随机选择一个天地灵机
|
||||
|
||||
Returns:
|
||||
CelestialPhenomenon 或 None(如果没有可用的天象)
|
||||
"""
|
||||
if not celestial_phenomena_by_id:
|
||||
return None
|
||||
|
||||
phenomena = list(celestial_phenomena_by_id.values())
|
||||
weights = [p.weight for p in phenomena]
|
||||
|
||||
return random.choices(phenomena, weights=weights, k=1)[0]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from src.classes.map import Map
|
||||
from src.classes.calendar import Year, Month, MonthStamp
|
||||
@@ -8,6 +8,7 @@ from src.classes.event_manager import EventManager
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.classes.avatar import Avatar
|
||||
from src.classes.celestial_phenomenon import CelestialPhenomenon
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -17,6 +18,10 @@ class World():
|
||||
avatar_manager: AvatarManager = field(default_factory=AvatarManager)
|
||||
# 全局事件管理器
|
||||
event_manager: EventManager = field(default_factory=EventManager)
|
||||
# 当前天地灵机(世界级buff/debuff)
|
||||
current_phenomenon: Optional["CelestialPhenomenon"] = None
|
||||
# 天地灵机开始年份(用于计算持续时间)
|
||||
phenomenon_start_year: int = 0
|
||||
|
||||
def get_info(self, detailed: bool = False) -> dict:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user