"""战斗系统数据模型和配置定义""" from __future__ import annotations from dataclasses import dataclass, field from typing import Any, Dict, List, Optional, Tuple from enum import Enum from PWF.Convention.Runtime.Architecture import Architecture from PWF.Convention.Runtime.GlobalConfig import ProjectConfig from PWF.CoreModules.plugin_interface import DatabaseModel from Plugins.WPSBackpackSystem import BackpackItemTier # ============================================================================ # 配置管理 # ============================================================================ _config: ProjectConfig = Architecture.Get(ProjectConfig) # 基础属性配置 COMBAT_CONFIG_DEFAULTS = { # 玩家基础属性 "combat_base_hp": 100, "combat_base_atk": 10, "combat_base_def": 5, "combat_base_spd": 10, "combat_base_crit": 5, # 百分比 "combat_base_crit_dmg": 150, # 百分比 # 装备强度权重 "combat_weight_atk": 1.0, "combat_weight_def": 0.8, "combat_weight_hp": 0.1, "combat_weight_spd": 0.5, "combat_weight_crit": 2.0, "combat_weight_crit_dmg": 0.01, } # 冒险系统配置 COMBAT_ADVENTURE_CONFIG = { # 阶段时间配置 "combat_adventure_base_time": 15, # 第一阶段基础时间(分钟) "combat_adventure_max_time": 1440, # 最大时间上限(24小时) "combat_food_support_time": 15, # 每个食物支持时间(分钟) # 成功率配置 "combat_adventure_base_success_rate": 0.80, # 第一阶段基础成功率(80%) "combat_adventure_stage_penalty": 0.05, # 每阶段递减(5%) "combat_adventure_min_success_rate": 0.10, # 最低成功率(10%) "combat_adventure_max_success_rate": 0.95, # 最高成功率(95%) # 加成系数配置 "combat_adventure_equipment_coeff": 0.01, # 装备强度加成系数(每100强度+1%) "combat_adventure_fortune_coeff": 0.10, # 运势加成系数(运势值*10) # 时间缩减配置 "combat_time_reduction_divisor": 100, # 时间缩减除数(用于对数函数) # 受伤与治疗 "combat_heal_cost": 100, # 治疗费用(积分) } # PVP战斗配置 COMBAT_PVP_CONFIG = { # 挑战配置 "combat_challenge_timeout": 15, # 挑战超时时间(分钟) "combat_pvp_reward": 1000, # PVP胜利奖励(积分) "combat_pvp_penalty": 1000, # PVP失败惩罚(积分) "combat_battle_action_timeout": 5, # 战斗操作超时(分钟) # 战斗计算配置 "combat_damage_def_ratio": 0.5, # 防御减伤系数 "combat_damage_random_min": 0.9, # 伤害随机系数最小值 "combat_damage_random_max": 1.1, # 伤害随机系数最大值 "combat_block_reduction": 0.5, # 格挡减伤比例(50%) # 技能配置 "combat_default_attack_power": 1.0, # 普通攻击威力倍率 "combat_skill_cooldown_default": 3, # 默认技能冷却回合 } # 果酒Buff配置 COMBAT_WINE_BUFFS_CONFIG = { # 普通草药果酒(RARE) "combat_buff_mint_time_reduction": 0.10, # 薄荷:-10%时间 "combat_buff_basil_reward_boost": 0.10, # 罗勒:+10%收益 "combat_buff_sage_success_rate": 0.05, # 鼠尾草:+5%成功率 "combat_buff_rosemary_atk_boost": 0.10, # 迷迭香:+10% ATK # 稀有树木果酒(EPIC) "combat_buff_ginkgo_time_reduction": 0.20, # 银杏:-20%时间 "combat_buff_sakura_reward_boost": 0.20, # 樱花:+20%收益 "combat_buff_sakura_def_boost": 0.10, # 樱花:+10% DEF "combat_buff_maple_success_rate": 0.10, # 红枫:+10%成功率 "combat_buff_maple_crit_boost": 0.15, # 红枫:+15% CRIT } # 掉落系统配置 COMBAT_LOOT_CONFIG = { # 掉落概率权重 "combat_loot_weight_points": 40, # 积分掉落权重 "combat_loot_weight_equipment": 20, # 装备掉落权重 "combat_loot_weight_material": 25, # 材料掉落权重 "combat_loot_weight_souvenir": 5, # 纪念品掉落权重 "combat_loot_weight_potion": 8, # 药剂掉落权重 "combat_loot_weight_seed": 2, # 种子掉落权重 # 掉落数量配置 "combat_loot_points_base": 100, # 基础积分奖励 "combat_loot_points_per_stage": 50, # 每阶段额外积分 "combat_loot_fortune_multiplier": 0.5, # 运势影响掉落倍率系数 } # 合并所有配置 COMBAT_CONFIG_ALL = { **COMBAT_CONFIG_DEFAULTS, **COMBAT_ADVENTURE_CONFIG, **COMBAT_PVP_CONFIG, **COMBAT_WINE_BUFFS_CONFIG, **COMBAT_LOOT_CONFIG, } # 初始化配置(读取或创建默认值) for key, default_value in COMBAT_CONFIG_ALL.items(): COMBAT_CONFIG_ALL[key] = _config.FindItem(key, default_value) _config.SaveProperties() class CombatConfig: """配置访问类""" @staticmethod def get(key: str, default: Any = None) -> Any: """获取配置项""" return COMBAT_CONFIG_ALL.get(key, default) @staticmethod def get_int(key: str, default: int = 0) -> int: """获取整数配置""" try: return int(COMBAT_CONFIG_ALL.get(key, default)) except (TypeError, ValueError): return default @staticmethod def get_float(key: str, default: float = 0.0) -> float: """获取浮点数配置""" try: return float(COMBAT_CONFIG_ALL.get(key, default)) except (TypeError, ValueError): return default # ============================================================================ # 数据模型定义 # ============================================================================ @dataclass(frozen=True) class EquipmentDefinition: """装备定义""" item_id: str name: str tier: BackpackItemTier slot: str # weapon/helmet/armor/boots/accessory/virtual attributes: Dict[str, int] # HP, ATK, DEF, SPD, CRIT, CRIT_DMG skill_ids: List[str] = field(default_factory=list) description: str = "" @dataclass(frozen=True) class SkillDefinition: """技能定义(DSL格式)""" skill_id: str name: str description: str effects: List[Dict[str, Any]] # DSL效果列表 cooldown: int = 0 icon: str = "⚔️" @dataclass class PlayerStats: """玩家完整属性(基础+装备)""" user_id: int hp: int atk: int def_: int # defense spd: int crit: int crit_dmg: int equipment_strength: float = 0.0 available_skills: List[SkillDefinition] = field(default_factory=list) @dataclass class BattleState: """战斗中的玩家状态""" user_id: int name: str current_hp: int max_hp: int atk: int def_: int spd: int crit: int crit_dmg: int buffs: List[Dict[str, Any]] = field(default_factory=list) # [{stat: "ATK", value: 0.2, remaining: 2}] skill_cooldowns: Dict[str, int] = field(default_factory=dict) # {skill_id: remaining_turns} available_skills: List[SkillDefinition] = field(default_factory=list) def to_dict(self) -> Dict[str, Any]: """序列化为字典(用于存储到数据库)""" return { "user_id": self.user_id, "name": self.name, "current_hp": self.current_hp, "max_hp": self.max_hp, "atk": self.atk, "def_": self.def_, "spd": self.spd, "crit": self.crit, "crit_dmg": self.crit_dmg, "buffs": self.buffs, "skill_cooldowns": self.skill_cooldowns, "available_skills": [s.skill_id for s in self.available_skills] } @staticmethod def from_dict(data: Dict[str, Any], skill_registry: Dict[str, SkillDefinition]) -> "BattleState": """从字典反序列化""" skills = [skill_registry[sid] for sid in data.get("available_skills", []) if sid in skill_registry] return BattleState( user_id=data["user_id"], name=data["name"], current_hp=data["current_hp"], max_hp=data["max_hp"], atk=data["atk"], def_=data["def_"], spd=data["spd"], crit=data["crit"], crit_dmg=data["crit_dmg"], buffs=data.get("buffs", []), skill_cooldowns=data.get("skill_cooldowns", {}), available_skills=skills ) # ============================================================================ # 预定义内容 # ============================================================================ # 技能注册表 SKILL_REGISTRY: Dict[str, SkillDefinition] = { # 默认技能 "skill_basic_attack": SkillDefinition( skill_id="skill_basic_attack", name="普通攻击", description="基础攻击,造成100%攻击力的伤害", effects=[ {"type": "damage", "power": 1.0, "can_crit": True} ], cooldown=0, icon="⚔️" ), "skill_block": SkillDefinition( skill_id="skill_block", name="格挡", description="防御姿态,本回合受到伤害减少50%", effects=[ {"type": "buff", "target": "self", "stat": "block", "value": 0.5, "duration": 1} ], cooldown=2, icon="🛡️" ), # 装备技能 "skill_power_strike": SkillDefinition( skill_id="skill_power_strike", name="力劈", description="强力一击,造成130%伤害", effects=[ {"type": "damage", "power": 1.3, "can_crit": True} ], cooldown=2, icon="💥" ), "skill_heavy_strike": SkillDefinition( skill_id="skill_heavy_strike", name="重击", description="强力攻击,造成150%伤害,但降低自身10%防御2回合", effects=[ {"type": "damage", "power": 1.5, "can_crit": True}, {"type": "buff", "target": "self", "stat": "DEF", "value": -0.1, "duration": 2} ], cooldown=3, icon="⚡" ), "skill_devastating_blow": SkillDefinition( skill_id="skill_devastating_blow", name="毁灭打击", description="传说技能,造成200%伤害,必定暴击", effects=[ {"type": "damage", "power": 2.0, "can_crit": True, "force_crit": True} ], cooldown=5, icon="💀" ), "skill_magic_bolt": SkillDefinition( skill_id="skill_magic_bolt", name="魔法箭", description="魔法攻击,造成120%伤害,无视20%防御", effects=[ {"type": "damage", "power": 1.2, "can_crit": True, "ignore_def": 0.2} ], cooldown=2, icon="✨" ), "skill_iron_wall": SkillDefinition( skill_id="skill_iron_wall", name="铁壁", description="防御姿态,3回合内防御提升30%", effects=[ {"type": "buff", "target": "self", "stat": "DEF", "value": 0.3, "duration": 3} ], cooldown=4, icon="🏰" ), "skill_swift_move": SkillDefinition( skill_id="skill_swift_move", name="疾风步", description="快速移动,本回合必定先手,2回合内速度提升20%", effects=[ {"type": "special", "effect": "priority"}, {"type": "buff", "target": "self", "stat": "SPD", "value": 0.2, "duration": 2} ], cooldown=4, icon="💨" ), "skill_dragon_roar": SkillDefinition( skill_id="skill_dragon_roar", name="龙吼", description="发出龙之咆哮,3回合内攻击和防御各提升15%", effects=[ {"type": "buff", "target": "self", "stat": "ATK", "value": 0.15, "duration": 3}, {"type": "buff", "target": "self", "stat": "DEF", "value": 0.15, "duration": 3} ], cooldown=5, icon="🐉" ), "skill_protect": SkillDefinition( skill_id="skill_protect", name="守护", description="护符之力,回复30HP并提升10%防御2回合", effects=[ {"type": "heal", "value": 30}, {"type": "buff", "target": "self", "stat": "DEF", "value": 0.1, "duration": 2} ], cooldown=3, icon="✝️" ), } # 虚拟装备(提供默认技能) VIRTUAL_EQUIPMENT: Dict[str, EquipmentDefinition] = { "virtual_default_skills": EquipmentDefinition( item_id="virtual_default_skills", name="基础战斗技能", tier=BackpackItemTier.COMMON, slot="virtual", attributes={}, skill_ids=["skill_basic_attack", "skill_block"], description="所有玩家的默认战斗技能" ) } # 装备注册表 EQUIPMENT_REGISTRY: Dict[str, EquipmentDefinition] = { # ===== 武器 ===== "combat_weapon_wood_sword": EquipmentDefinition( item_id="combat_weapon_wood_sword", name="木剑", tier=BackpackItemTier.COMMON, slot="weapon", attributes={"ATK": 15}, skill_ids=[], description="最基础的木制武器" ), "combat_weapon_iron_sword": EquipmentDefinition( item_id="combat_weapon_iron_sword", name="铁剑", tier=BackpackItemTier.RARE, slot="weapon", attributes={"ATK": 35}, skill_ids=["skill_power_strike"], description="坚固的铁制剑,附带力劈技能" ), "combat_weapon_steel_sword": EquipmentDefinition( item_id="combat_weapon_steel_sword", name="钢剑", tier=BackpackItemTier.EPIC, slot="weapon", attributes={"ATK": 60, "CRIT": 5}, skill_ids=["skill_heavy_strike"], description="精钢打造,锋利无比" ), "combat_weapon_legend_sword": EquipmentDefinition( item_id="combat_weapon_legend_sword", name="传说之剑", tier=BackpackItemTier.LEGENDARY, slot="weapon", attributes={"ATK": 100, "CRIT": 10, "CRIT_DMG": 50}, skill_ids=["skill_devastating_blow"], description="传说中的神兵利器" ), "combat_weapon_magic_staff": EquipmentDefinition( item_id="combat_weapon_magic_staff", name="魔法杖", tier=BackpackItemTier.EPIC, slot="weapon", attributes={"ATK": 50, "SPD": 10}, skill_ids=["skill_magic_bolt"], description="蕴含魔力的法杖" ), # ===== 头盔 ===== "combat_helmet_leather": EquipmentDefinition( item_id="combat_helmet_leather", name="皮帽", tier=BackpackItemTier.COMMON, slot="helmet", attributes={"HP": 20, "DEF": 5}, skill_ids=[], description="简单的皮革头饰" ), "combat_helmet_iron": EquipmentDefinition( item_id="combat_helmet_iron", name="铁盔", tier=BackpackItemTier.RARE, slot="helmet", attributes={"HP": 50, "DEF": 15}, skill_ids=[], description="厚重的铁制头盔" ), "combat_helmet_dragon": EquipmentDefinition( item_id="combat_helmet_dragon", name="龙鳞头盔", tier=BackpackItemTier.LEGENDARY, slot="helmet", attributes={"HP": 120, "DEF": 40, "ATK": 20}, skill_ids=["skill_dragon_roar"], description="龙鳞打造的传奇头盔" ), # ===== 护甲 ===== "combat_armor_cloth": EquipmentDefinition( item_id="combat_armor_cloth", name="布衣", tier=BackpackItemTier.COMMON, slot="armor", attributes={"HP": 30, "DEF": 8}, skill_ids=[], description="简单的布质防具" ), "combat_armor_chain": EquipmentDefinition( item_id="combat_armor_chain", name="锁子甲", tier=BackpackItemTier.RARE, slot="armor", attributes={"HP": 70, "DEF": 25}, skill_ids=[], description="环环相扣的金属铠甲" ), "combat_armor_plate": EquipmentDefinition( item_id="combat_armor_plate", name="板甲", tier=BackpackItemTier.EPIC, slot="armor", attributes={"HP": 120, "DEF": 50}, skill_ids=["skill_iron_wall"], description="厚重的全身板甲" ), # ===== 鞋子 ===== "combat_boots_leather": EquipmentDefinition( item_id="combat_boots_leather", name="皮靴", tier=BackpackItemTier.COMMON, slot="boots", attributes={"SPD": 5}, skill_ids=[], description="轻便的皮制靴子" ), "combat_boots_wind": EquipmentDefinition( item_id="combat_boots_wind", name="疾风之靴", tier=BackpackItemTier.EPIC, slot="boots", attributes={"SPD": 20, "DEF": 10}, skill_ids=["skill_swift_move"], description="蕴含风之力的靴子" ), # ===== 饰品 ===== "combat_accessory_ring_str": EquipmentDefinition( item_id="combat_accessory_ring_str", name="力量戒指", tier=BackpackItemTier.RARE, slot="accessory", attributes={"ATK": 20, "HP": 30}, skill_ids=[], description="增强力量的魔法戒指" ), "combat_accessory_amulet": EquipmentDefinition( item_id="combat_accessory_amulet", name="守护护符", tier=BackpackItemTier.EPIC, slot="accessory", attributes={"HP": 50, "DEF": 20, "CRIT": 5}, skill_ids=["skill_protect"], description="守护佩戴者的神秘护符" ), } # 果酒buff映射 WINE_BUFFS: Dict[str, Dict[str, float]] = { # 普通草药果酒 "garden_wine_mint": { "time_reduction": CombatConfig.get_float("combat_buff_mint_time_reduction", 0.10), }, "garden_wine_basil": { "reward_boost": CombatConfig.get_float("combat_buff_basil_reward_boost", 0.10), }, "garden_wine_sage": { "success_rate": CombatConfig.get_float("combat_buff_sage_success_rate", 0.05), }, "garden_wine_rosemary": { "atk_boost": CombatConfig.get_float("combat_buff_rosemary_atk_boost", 0.10), }, # 稀有树木果酒 "garden_wine_ginkgo": { "time_reduction": CombatConfig.get_float("combat_buff_ginkgo_time_reduction", 0.20), }, "garden_wine_sakura": { "reward_boost": CombatConfig.get_float("combat_buff_sakura_reward_boost", 0.20), "def_boost": CombatConfig.get_float("combat_buff_sakura_def_boost", 0.10), }, "garden_wine_maple": { "success_rate": CombatConfig.get_float("combat_buff_maple_success_rate", 0.10), "crit_boost": CombatConfig.get_float("combat_buff_maple_crit_boost", 0.15), }, } # 冒险材料(item_id -> (name, tier)) ADVENTURE_MATERIALS: Dict[str, Tuple[str, BackpackItemTier]] = { "combat_material_ore": ("矿石", BackpackItemTier.COMMON), "combat_material_gem": ("宝石", BackpackItemTier.RARE), "combat_material_crystal": ("水晶", BackpackItemTier.EPIC), "combat_material_essence": ("精华", BackpackItemTier.LEGENDARY), } # 纪念品(item_id -> (name, tier, sell_price)) ADVENTURE_SOUVENIRS: Dict[str, Tuple[str, BackpackItemTier, int]] = { "combat_souvenir_medal": ("英雄勋章", BackpackItemTier.RARE, 500), "combat_souvenir_trophy": ("战斗奖杯", BackpackItemTier.EPIC, 1500), "combat_souvenir_relic": ("远古遗物", BackpackItemTier.LEGENDARY, 5000), } # 药剂(item_id -> (name, tier, description)) COMBAT_POTIONS: Dict[str, Tuple[str, BackpackItemTier, str]] = { "combat_potion_hp_small": ("小型治疗药水", BackpackItemTier.COMMON, "回复50HP"), "combat_potion_hp_medium": ("中型治疗药水", BackpackItemTier.RARE, "回复150HP"), "combat_potion_hp_large": ("大型治疗药水", BackpackItemTier.EPIC, "回复全部HP"), "combat_potion_atk": ("力量药水", BackpackItemTier.RARE, "3回合ATK+20%"), "combat_potion_def": ("防御药水", BackpackItemTier.RARE, "3回合DEF+20%"), } # 冒险独有种子(item_id -> (name, tier)) ADVENTURE_SEEDS: Dict[str, Tuple[str, BackpackItemTier]] = { "combat_seed_battle_flower": ("战斗之花种子", BackpackItemTier.EPIC), "combat_seed_victory_tree": ("胜利之树种子", BackpackItemTier.LEGENDARY), } # ============================================================================ # 数据库模型 # ============================================================================ def get_combat_db_models() -> List[DatabaseModel]: """返回战斗系统所需的数据库表定义""" return [ # 玩家状态表 DatabaseModel( table_name="combat_player_status", column_defs={ "user_id": "INTEGER PRIMARY KEY", "base_hp": "INTEGER NOT NULL DEFAULT 100", "base_atk": "INTEGER NOT NULL DEFAULT 10", "base_def": "INTEGER NOT NULL DEFAULT 5", "base_spd": "INTEGER NOT NULL DEFAULT 10", "base_crit": "INTEGER NOT NULL DEFAULT 5", "base_crit_dmg": "INTEGER NOT NULL DEFAULT 150", "equipped_weapon": "TEXT", "equipped_helmet": "TEXT", "equipped_armor": "TEXT", "equipped_boots": "TEXT", "equipped_accessory": "TEXT", "is_injured": "INTEGER NOT NULL DEFAULT 0", "current_adventure_id": "INTEGER DEFAULT NULL", "current_battle_id": "INTEGER DEFAULT NULL", }, ), # 装备实例表 DatabaseModel( table_name="combat_equipment_instances", column_defs={ "instance_id": "INTEGER PRIMARY KEY AUTOINCREMENT", "item_id": "TEXT NOT NULL", "owner_id": "INTEGER NOT NULL", "custom_attributes": "TEXT", "modifications": "TEXT", "created_at": "TEXT NOT NULL", }, ), # 冒险记录表 DatabaseModel( table_name="combat_adventure_records", column_defs={ "adventure_id": "INTEGER PRIMARY KEY AUTOINCREMENT", "user_id": "INTEGER NOT NULL", "chat_id": "INTEGER NOT NULL", "stage": "INTEGER NOT NULL", "equipment_snapshot": "TEXT NOT NULL", "foods_used": "TEXT NOT NULL", "start_time": "TEXT NOT NULL", "expected_end_time": "TEXT NOT NULL", "status": "TEXT NOT NULL", "rewards": "TEXT", "fortune_value": "REAL", "equipment_strength": "REAL", "success_rate": "REAL", "scheduled_task_id": "INTEGER", }, ), # PVP挑战表 DatabaseModel( table_name="combat_pvp_challenges", column_defs={ "challenge_id": "INTEGER PRIMARY KEY AUTOINCREMENT", "challenger_id": "INTEGER NOT NULL", "target_id": "INTEGER NOT NULL", "chat_id": "INTEGER NOT NULL", "status": "TEXT NOT NULL", "created_at": "TEXT NOT NULL", "expires_at": "TEXT NOT NULL", }, ), # PVP战斗表 DatabaseModel( table_name="combat_pvp_battles", column_defs={ "battle_id": "INTEGER PRIMARY KEY AUTOINCREMENT", "challenge_id": "INTEGER NOT NULL", "player1_id": "INTEGER NOT NULL", "player2_id": "INTEGER NOT NULL", "chat_id": "INTEGER NOT NULL", "current_turn_player": "INTEGER NOT NULL", "turn_number": "INTEGER NOT NULL DEFAULT 1", "player1_state": "TEXT NOT NULL", "player2_state": "TEXT NOT NULL", "battle_log": "TEXT NOT NULL", "last_action_time": "TEXT NOT NULL", "action_timeout_minutes": "INTEGER NOT NULL DEFAULT 5", "winner_id": "INTEGER", "status": "TEXT NOT NULL", "created_at": "TEXT NOT NULL", "finished_at": "TEXT", }, ), ]