Files
cultivation-world-simulator/src/classes/celestial_phenomenon.py
2025-11-26 21:56:39 +08:00

116 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
天地灵机系统
=============
天地灵机是影响整个修仙世界的天象异动提供全局性的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, get_str, get_int
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]
effect_desc: str
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:
"""获取详细信息"""
effect_part = f" 效果:{self.effect_desc}" if self.effect_desc else ""
return f"{self.name}{self.desc}{effect_part}"
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:
# 解析稀有度
rarity_str = get_str(row, "rarity", "N").upper()
rarity = get_rarity_from_str(rarity_str) if rarity_str and rarity_str != "NAN" else get_rarity_from_str("N")
# 解析effects
effects = load_effect_from_str(get_str(row, "effects"))
from src.utils.effect_desc import format_effects_to_text
effect_desc = format_effects_to_text(effects)
phenomenon = CelestialPhenomenon(
id=get_int(row, "id"),
name=get_str(row, "name"),
rarity=rarity,
effects=effects,
effect_desc=effect_desc,
desc=get_str(row, "desc"),
duration_years=get_int(row, "duration_years", 5),
)
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]