2025-11-10 14:59:07 +08:00
|
|
|
|
"""战斗系统基础插件类"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from typing import List, Type
|
|
|
|
|
|
|
|
|
|
|
|
from PWF.Convention.Runtime.Architecture import Architecture
|
|
|
|
|
|
from PWF.Convention.Runtime.GlobalConfig import ConsoleFrontColor, ProjectConfig
|
|
|
|
|
|
from PWF.CoreModules.plugin_interface import DatabaseModel
|
|
|
|
|
|
|
|
|
|
|
|
from Plugins.WPSAPI import WPSAPI
|
|
|
|
|
|
from Plugins.WPSBackpackSystem import BackpackItemTier, WPSBackpackSystem
|
|
|
|
|
|
from Plugins.WPSStoreSystem import WPSStoreSystem
|
|
|
|
|
|
from Plugins.WPSConfigSystem import WPSConfigAPI
|
|
|
|
|
|
from Plugins.WPSFortuneSystem import WPSFortuneSystem
|
|
|
|
|
|
|
|
|
|
|
|
from .combat_models import (
|
|
|
|
|
|
ADVENTURE_MATERIALS,
|
|
|
|
|
|
ADVENTURE_SEEDS,
|
|
|
|
|
|
ADVENTURE_SOUVENIRS,
|
|
|
|
|
|
COMBAT_POTIONS,
|
|
|
|
|
|
EQUIPMENT_REGISTRY,
|
2025-11-12 14:36:50 +08:00
|
|
|
|
SKILL_REGISTRY,
|
|
|
|
|
|
EquipmentDefinition,
|
2025-11-10 14:59:07 +08:00
|
|
|
|
get_combat_db_models,
|
|
|
|
|
|
)
|
|
|
|
|
|
from .combat_service import CombatService, get_combat_service
|
|
|
|
|
|
|
2025-11-11 20:31:46 +08:00
|
|
|
|
# 尝试导入菜园系统(可选依赖)
|
|
|
|
|
|
try:
|
|
|
|
|
|
from Plugins.WPSGardenSystem import (
|
|
|
|
|
|
GardenCropDefinition,
|
|
|
|
|
|
GardenExtraReward,
|
|
|
|
|
|
register_crop,
|
|
|
|
|
|
)
|
|
|
|
|
|
GARDEN_SYSTEM_AVAILABLE = True
|
|
|
|
|
|
except ImportError:
|
|
|
|
|
|
GARDEN_SYSTEM_AVAILABLE = False
|
|
|
|
|
|
|
2025-11-10 14:59:07 +08:00
|
|
|
|
|
|
|
|
|
|
logger: ProjectConfig = Architecture.Get(ProjectConfig)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WPSCombatBase(WPSAPI):
|
|
|
|
|
|
"""战斗系统基础插件类"""
|
|
|
|
|
|
|
|
|
|
|
|
_service: CombatService | None = None
|
|
|
|
|
|
_initialized: bool = False
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
def service(cls) -> CombatService:
|
|
|
|
|
|
"""获取共享的战斗服务实例"""
|
|
|
|
|
|
if cls._service is None:
|
|
|
|
|
|
cls._service = get_combat_service()
|
|
|
|
|
|
return cls._service
|
|
|
|
|
|
|
|
|
|
|
|
def dependencies(self) -> List[Type]:
|
|
|
|
|
|
"""声明依赖的插件"""
|
|
|
|
|
|
return [
|
|
|
|
|
|
WPSAPI,
|
|
|
|
|
|
WPSConfigAPI,
|
|
|
|
|
|
WPSBackpackSystem,
|
|
|
|
|
|
WPSStoreSystem,
|
|
|
|
|
|
WPSFortuneSystem,
|
|
|
|
|
|
# 注:不强制依赖 WPSGardenSystem,果酒buff配置在 combat_models.py 中
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def register_db_model(self) -> List[DatabaseModel]:
|
|
|
|
|
|
"""注册数据库表"""
|
|
|
|
|
|
return get_combat_db_models()
|
|
|
|
|
|
|
|
|
|
|
|
def wake_up(self) -> None:
|
|
|
|
|
|
"""插件初始化(只执行一次)"""
|
|
|
|
|
|
if WPSCombatBase._initialized:
|
|
|
|
|
|
return
|
|
|
|
|
|
WPSCombatBase._initialized = True
|
|
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Info",
|
|
|
|
|
|
f"{ConsoleFrontColor.GREEN}WPSCombat 系统开始初始化{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
|
|
|
|
|
|
store: WPSStoreSystem = Architecture.Get(WPSStoreSystem)
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 注册所有装备
|
|
|
|
|
|
for equipment in EQUIPMENT_REGISTRY.values():
|
2025-11-12 14:36:50 +08:00
|
|
|
|
# 生成包含属性数值和技能信息的描述
|
|
|
|
|
|
enhanced_description = self._generate_equipment_description(equipment)
|
2025-11-10 22:30:16 +08:00
|
|
|
|
self._safe_register_item(
|
|
|
|
|
|
backpack,
|
|
|
|
|
|
equipment.item_id,
|
|
|
|
|
|
equipment.name,
|
|
|
|
|
|
equipment.tier,
|
2025-11-12 14:36:50 +08:00
|
|
|
|
enhanced_description,
|
2025-11-10 22:30:16 +08:00
|
|
|
|
)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 装备价格根据品质和属性计算
|
|
|
|
|
|
price = self._calculate_equipment_price(equipment)
|
|
|
|
|
|
self._safe_register_store(store, equipment.item_id, price, limit=3)
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 注册材料
|
2025-11-10 22:30:16 +08:00
|
|
|
|
for item_id, (name, tier, desc) in ADVENTURE_MATERIALS.items():
|
|
|
|
|
|
self._safe_register_item(backpack, item_id, name, tier, desc)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 材料可以在商店出售(但不购买)
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 注册纪念品
|
2025-11-10 22:30:16 +08:00
|
|
|
|
for item_id, (name, tier, sell_price, desc) in ADVENTURE_SOUVENIRS.items():
|
|
|
|
|
|
self._safe_register_item(backpack, item_id, name, tier, desc)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 纪念品只能出售
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 注册药剂
|
|
|
|
|
|
for item_id, (name, tier, desc) in COMBAT_POTIONS.items():
|
2025-11-10 22:30:16 +08:00
|
|
|
|
self._safe_register_item(backpack, item_id, name, tier, desc)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 药剂价格根据品质
|
|
|
|
|
|
potion_prices = {
|
|
|
|
|
|
BackpackItemTier.COMMON: 50,
|
|
|
|
|
|
BackpackItemTier.RARE: 150,
|
|
|
|
|
|
BackpackItemTier.EPIC: 500,
|
|
|
|
|
|
}
|
|
|
|
|
|
price = potion_prices.get(tier, 100)
|
|
|
|
|
|
self._safe_register_store(store, item_id, price, limit=10)
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 注册冒险种子
|
2025-11-10 22:30:16 +08:00
|
|
|
|
for item_id, (name, tier, desc) in ADVENTURE_SEEDS.items():
|
|
|
|
|
|
self._safe_register_item(backpack, item_id, name, tier, desc)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 种子只能通过冒险获得
|
2025-11-11 20:31:46 +08:00
|
|
|
|
|
|
|
|
|
|
# 5.1. 注册冒险种子到菜园系统(如果可用)
|
|
|
|
|
|
if GARDEN_SYSTEM_AVAILABLE:
|
|
|
|
|
|
self._register_adventure_seeds_to_garden()
|
|
|
|
|
|
|
2025-11-10 14:59:07 +08:00
|
|
|
|
# 6. 恢复过期任务和超时战斗
|
|
|
|
|
|
try:
|
|
|
|
|
|
service = self.service()
|
|
|
|
|
|
service.recover_overdue_adventures()
|
|
|
|
|
|
service.check_battle_timeout()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Warning",
|
|
|
|
|
|
f"{ConsoleFrontColor.YELLOW}恢复任务时出错: {e}{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Info",
|
|
|
|
|
|
f"{ConsoleFrontColor.GREEN}WPSCombat 系统初始化完成:{len(EQUIPMENT_REGISTRY)}件装备、"
|
|
|
|
|
|
f"{len(COMBAT_POTIONS)}种药剂已注册{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ========================================================================
|
|
|
|
|
|
# 辅助方法
|
|
|
|
|
|
# ========================================================================
|
|
|
|
|
|
|
|
|
|
|
|
def _safe_register_item(
|
|
|
|
|
|
self,
|
|
|
|
|
|
backpack: WPSBackpackSystem,
|
|
|
|
|
|
item_id: str,
|
|
|
|
|
|
name: str,
|
|
|
|
|
|
tier: BackpackItemTier,
|
2025-11-10 22:30:16 +08:00
|
|
|
|
description: str,
|
2025-11-10 14:59:07 +08:00
|
|
|
|
) -> None:
|
|
|
|
|
|
"""安全注册物品到背包系统"""
|
|
|
|
|
|
try:
|
2025-11-10 22:30:16 +08:00
|
|
|
|
backpack.register_item(item_id, name, tier, description)
|
2025-11-10 14:59:07 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Warning",
|
|
|
|
|
|
f"{ConsoleFrontColor.YELLOW}注册物品 {item_id} 时出错: {e}{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def _safe_register_store(
|
|
|
|
|
|
self,
|
|
|
|
|
|
store: WPSStoreSystem,
|
|
|
|
|
|
item_id: str,
|
|
|
|
|
|
price: int,
|
|
|
|
|
|
*,
|
|
|
|
|
|
limit: int = 5,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""安全注册物品到商店系统"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
store.register_mode(
|
|
|
|
|
|
item_id=item_id,
|
|
|
|
|
|
price=price,
|
|
|
|
|
|
limit_amount=limit,
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Warning",
|
|
|
|
|
|
f"{ConsoleFrontColor.YELLOW}注册商店物品 {item_id} 时出错: {e}{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-11-12 14:36:50 +08:00
|
|
|
|
def _generate_equipment_description(self, equipment:EquipmentDefinition) -> str:
|
|
|
|
|
|
"""生成包含属性数值和技能信息的装备描述"""
|
|
|
|
|
|
parts = []
|
|
|
|
|
|
|
|
|
|
|
|
# 基础描述
|
|
|
|
|
|
if equipment.description:
|
|
|
|
|
|
parts.append(equipment.description)
|
|
|
|
|
|
|
|
|
|
|
|
# 属性信息
|
|
|
|
|
|
if equipment.attributes:
|
|
|
|
|
|
attr_parts = []
|
|
|
|
|
|
attr_names = {
|
|
|
|
|
|
"HP": "生命值",
|
|
|
|
|
|
"ATK": "攻击力",
|
|
|
|
|
|
"DEF": "防御力",
|
|
|
|
|
|
"SPD": "速度",
|
|
|
|
|
|
"CRIT": "暴击率",
|
|
|
|
|
|
"CRIT_DMG": "暴击伤害",
|
|
|
|
|
|
}
|
|
|
|
|
|
for attr_key, attr_value in sorted(equipment.attributes.items()):
|
|
|
|
|
|
attr_name = attr_names.get(attr_key, attr_key)
|
|
|
|
|
|
if attr_key in ["CRIT", "CRIT_DMG"]:
|
|
|
|
|
|
attr_parts.append(f"{attr_name}+{attr_value}%")
|
|
|
|
|
|
else:
|
|
|
|
|
|
attr_parts.append(f"{attr_name}+{attr_value}")
|
|
|
|
|
|
if attr_parts:
|
|
|
|
|
|
parts.append(f"属性:{', '.join(attr_parts)}")
|
|
|
|
|
|
|
|
|
|
|
|
# 技能信息
|
|
|
|
|
|
if equipment.skill_ids:
|
|
|
|
|
|
skill_names = []
|
|
|
|
|
|
for skill_id in equipment.skill_ids:
|
|
|
|
|
|
skill = SKILL_REGISTRY.get(skill_id)
|
|
|
|
|
|
if skill:
|
|
|
|
|
|
skill_names.append(skill.name)
|
|
|
|
|
|
if skill_names:
|
|
|
|
|
|
parts.append(f"附带技能:{', '.join(skill_names)}")
|
|
|
|
|
|
|
|
|
|
|
|
return " | ".join(parts) if parts else equipment.description
|
|
|
|
|
|
|
2025-11-10 14:59:07 +08:00
|
|
|
|
def _calculate_equipment_price(self, equipment) -> int:
|
|
|
|
|
|
"""根据装备品质和属性计算价格"""
|
|
|
|
|
|
# 基础价格
|
|
|
|
|
|
base_prices = {
|
|
|
|
|
|
BackpackItemTier.COMMON: 100,
|
|
|
|
|
|
BackpackItemTier.RARE: 500,
|
|
|
|
|
|
BackpackItemTier.EPIC: 2000,
|
|
|
|
|
|
BackpackItemTier.LEGENDARY: 10000,
|
|
|
|
|
|
}
|
|
|
|
|
|
base_price = base_prices.get(equipment.tier, 100)
|
|
|
|
|
|
|
|
|
|
|
|
# 属性加成
|
|
|
|
|
|
attr_sum = sum(equipment.attributes.values())
|
|
|
|
|
|
price = base_price + attr_sum * 5
|
|
|
|
|
|
|
|
|
|
|
|
# 技能加成
|
|
|
|
|
|
skill_bonus = len(equipment.skill_ids) * 200
|
|
|
|
|
|
|
|
|
|
|
|
return price + skill_bonus
|
|
|
|
|
|
|
2025-11-11 20:31:46 +08:00
|
|
|
|
def _register_adventure_seeds_to_garden(self) -> None:
|
|
|
|
|
|
"""注册冒险种子到菜园系统"""
|
|
|
|
|
|
if not GARDEN_SYSTEM_AVAILABLE:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
|
|
|
|
|
|
|
|
|
|
|
|
# 战斗之花种子(EPIC)
|
|
|
|
|
|
battle_flower_crop = GardenCropDefinition(
|
|
|
|
|
|
seed_id="combat_seed_battle_flower",
|
|
|
|
|
|
fruit_id="combat_fruit_battle_flower",
|
|
|
|
|
|
display_name="战斗之花",
|
|
|
|
|
|
tier="epic",
|
|
|
|
|
|
growth_minutes=240, # 4小时,比稀有树木更长
|
|
|
|
|
|
seed_price=300, # 比稀有树木更贵
|
|
|
|
|
|
base_yield=2, # 产量较低,体现稀有性
|
|
|
|
|
|
extra_reward=GardenExtraReward(
|
|
|
|
|
|
kind="points",
|
|
|
|
|
|
payload={"min": 500, "max": 2000},
|
|
|
|
|
|
base_rate=0.35, # 较低的基础概率,体现稀有性
|
|
|
|
|
|
),
|
|
|
|
|
|
wine_item_id=None, # 暂不设置果酒
|
|
|
|
|
|
wine_tier=None,
|
|
|
|
|
|
)
|
|
|
|
|
|
register_crop(battle_flower_crop)
|
|
|
|
|
|
# 注册果实到背包系统
|
|
|
|
|
|
self._safe_register_item(
|
|
|
|
|
|
backpack,
|
|
|
|
|
|
battle_flower_crop.fruit_id,
|
|
|
|
|
|
"战斗之花的果实",
|
|
|
|
|
|
BackpackItemTier.EPIC,
|
|
|
|
|
|
"战斗之花成熟后的果实,可食用或售出换取积分。",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 胜利之树种子(LEGENDARY)
|
|
|
|
|
|
victory_tree_crop = GardenCropDefinition(
|
|
|
|
|
|
seed_id="combat_seed_victory_tree",
|
|
|
|
|
|
fruit_id="combat_fruit_victory_tree",
|
|
|
|
|
|
display_name="胜利之树",
|
|
|
|
|
|
tier="legendary",
|
|
|
|
|
|
growth_minutes=480, # 8小时,最长的生长时间
|
|
|
|
|
|
seed_price=800, # 最贵的种子
|
|
|
|
|
|
base_yield=1, # 最低产量,体现传说级稀有性
|
|
|
|
|
|
extra_reward=GardenExtraReward(
|
|
|
|
|
|
kind="points",
|
|
|
|
|
|
payload={"min": 2000, "max": 5000},
|
|
|
|
|
|
base_rate=0.25, # 最低的基础概率
|
|
|
|
|
|
),
|
|
|
|
|
|
wine_item_id=None, # 暂不设置果酒
|
|
|
|
|
|
wine_tier=None,
|
|
|
|
|
|
)
|
|
|
|
|
|
register_crop(victory_tree_crop)
|
|
|
|
|
|
# 注册果实到背包系统
|
|
|
|
|
|
self._safe_register_item(
|
|
|
|
|
|
backpack,
|
|
|
|
|
|
victory_tree_crop.fruit_id,
|
|
|
|
|
|
"胜利之树的果实",
|
|
|
|
|
|
BackpackItemTier.LEGENDARY,
|
|
|
|
|
|
"胜利之树成熟后的果实,可食用或售出换取积分。",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Info",
|
|
|
|
|
|
f"{ConsoleFrontColor.GREEN}成功注册 {len(ADVENTURE_SEEDS)} 种冒险种子到菜园系统{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.Log(
|
|
|
|
|
|
"Warning",
|
|
|
|
|
|
f"{ConsoleFrontColor.YELLOW}注册冒险种子到菜园系统时出错: {e}{ConsoleFrontColor.RESET}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-11-10 14:59:07 +08:00
|
|
|
|
|
|
|
|
|
|
__all__ = ["WPSCombatBase"]
|