""" 效果系统 定义各种游戏效果的实现 """ from abc import ABC, abstractmethod from typing import Any, Dict, List, Optional, TYPE_CHECKING from enum import Enum if TYPE_CHECKING: from ..units.unit import Unit from ..battlefield.battlefield import Battlefield from ..core.enums import UnitType class EffectType(Enum): """效果类型枚举""" DAMAGE = "damage" # 造成伤害 HEAL = "heal" # 治疗 BUFF_ATTACK = "buff_attack" # 增加攻击力 BUFF_DEFENSE = "buff_defense" # 增加防御力 DEBUFF_ATTACK = "debuff_attack" # 减少攻击力 DEBUFF_DEFENSE = "debuff_defense" # 减少防御力 ADD_KEYWORD = "add_keyword" # 添加关键词 REMOVE_KEYWORD = "remove_keyword" # 移除关键词 MOVE_UNIT = "move_unit" # 移动单位 DESTROY_UNIT = "destroy_unit" # 摧毁单位 SUMMON_UNIT = "summon_unit" # 召唤单位 DRAW_CARD = "draw_card" # 抽卡 GAIN_RESOURCE = "gain_resource" # 获得资源 class Effect(ABC): """效果基类""" def __init__(self, name: str, effect_type: EffectType, description: str = ""): self.name = name self.effect_type = effect_type self.description = description @abstractmethod def apply(self, source: 'Unit', target: Any, battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: """应用效果""" pass def can_apply(self, source: 'Unit', target: Any, battlefield: 'Battlefield') -> bool: """检查是否可以应用效果""" return True def __str__(self) -> str: return f"{self.name}: {self.description}" class DamageEffect(Effect): """伤害效果""" def __init__(self, damage: int, name: str = "DAMAGE"): super().__init__(name, EffectType.DAMAGE, f"造成{damage}点伤害") self.damage = damage def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: if not isinstance(target, type(source)): # 确保target是Unit类型 return {"success": False, "reason": "Invalid target type"} # 应用重甲减伤等效果 final_damage = self.damage # 检查重甲关键词 for keyword in target.keywords: if keyword.startswith("HEAVY_ARMOR_"): armor_value = int(keyword.split("_")[-1]) final_damage = max(0, final_damage - armor_value) break actual_damage = target.stats.take_damage(final_damage) result = { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "damage_dealt": actual_damage, "final_damage": final_damage, "target_destroyed": not target.stats.is_alive() } # 如果目标被摧毁,从战场移除 if not target.stats.is_alive(): battlefield.remove_unit(target) return result class HealEffect(Effect): """治疗效果""" def __init__(self, heal_amount: int, name: str = "HEAL"): super().__init__(name, EffectType.HEAL, f"治疗{heal_amount}点") self.heal_amount = heal_amount def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: actual_heal = target.stats.heal(self.heal_amount) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "heal_amount": actual_heal } class BuffAttackEffect(Effect): """攻击力增益效果""" def __init__(self, attack_bonus: int, duration: int = -1, name: str = "BUFF_ATTACK"): super().__init__(name, EffectType.BUFF_ATTACK, f"攻击力+{attack_bonus}") self.attack_bonus = attack_bonus self.duration = duration # -1表示永久 def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: target.stats.attack += self.attack_bonus # 如果有持续时间,添加到临时修正器 if self.duration > 0: if "temporary_buffs" not in target.temporary_modifiers: target.temporary_modifiers["temporary_buffs"] = [] target.temporary_modifiers["temporary_buffs"].append({ "type": "attack", "value": self.attack_bonus, "duration": self.duration }) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "attack_bonus": self.attack_bonus, "new_attack": target.stats.attack } class BuffDefenseEffect(Effect): """防御力增益效果""" def __init__(self, defense_bonus: int, duration: int = -1, name: str = "BUFF_DEFENSE"): super().__init__(name, EffectType.BUFF_DEFENSE, f"防御力+{defense_bonus}") self.defense_bonus = defense_bonus self.duration = duration def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: target.stats.defense += self.defense_bonus target.stats.current_defense += self.defense_bonus if self.duration > 0: if "temporary_buffs" not in target.temporary_modifiers: target.temporary_modifiers["temporary_buffs"] = [] target.temporary_modifiers["temporary_buffs"].append({ "type": "defense", "value": self.defense_bonus, "duration": self.duration }) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "defense_bonus": self.defense_bonus, "new_defense": target.stats.defense } class AddKeywordEffect(Effect): """添加关键词效果""" def __init__(self, keyword: str, name: str = "ADD_KEYWORD"): super().__init__(name, EffectType.ADD_KEYWORD, f"获得{keyword}") self.keyword = keyword def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: target.add_keyword(self.keyword) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "keyword_added": self.keyword } class RemoveKeywordEffect(Effect): """移除关键词效果""" def __init__(self, keyword: str, name: str = "REMOVE_KEYWORD"): super().__init__(name, EffectType.REMOVE_KEYWORD, f"失去{keyword}") self.keyword = keyword def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: had_keyword = target.has_keyword(self.keyword) target.remove_keyword(self.keyword) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "keyword_removed": self.keyword, "had_keyword": had_keyword } class DestroyUnitEffect(Effect): """摧毁单位效果""" def __init__(self, name: str = "DESTROY_UNIT"): super().__init__(name, EffectType.DESTROY_UNIT, "摧毁目标单位") def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: # 直接将单位防御力设为0 target.stats.current_defense = 0 battlefield.remove_unit(target) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "unit_destroyed": True } class MoveUnitEffect(Effect): """移动单位效果""" def __init__(self, from_line, to_line, name: str = "MOVE_UNIT"): super().__init__(name, EffectType.MOVE_UNIT, f"从{from_line}移动到{to_line}") self.from_line = from_line self.to_line = to_line def apply(self, source: 'Unit', target: 'Unit', battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: if not target.position: return {"success": False, "reason": "Target not on battlefield"} current_line_type, current_pos = target.position # 检查是否可以移动 if current_line_type != self.from_line: return {"success": False, "reason": "Target not on source line"} # 获取目标战线 target_line = battlefield.get_player_line(target.owner, self.to_line) if not target_line: return {"success": False, "reason": "Invalid target line"} # 查找空位 empty_positions = target_line.get_empty_positions() if not empty_positions: return {"success": False, "reason": "Target line is full"} # 从当前位置移除 current_line = battlefield.get_player_line(target.owner, current_line_type) if current_line: current_line.remove_unit(current_pos) # 移动到新位置(选择第一个空位) new_pos = empty_positions[0] target_line.deploy_unit(target, new_pos) return { "success": True, "effect_type": self.effect_type.value, "target_id": target.id, "from_position": (current_line_type, current_pos), "to_position": (self.to_line, new_pos) } class CompositeEffect(Effect): """复合效果 - 可以包含多个子效果""" def __init__(self, effects: List[Effect], name: str = "COMPOSITE_EFFECT"): descriptions = [effect.description for effect in effects] description = "; ".join(descriptions) super().__init__(name, EffectType.DAMAGE, description) # 使用DAMAGE作为默认类型 self.effects = effects def apply(self, source: 'Unit', target: Any, battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: results = [] for effect in self.effects: if effect.can_apply(source, target, battlefield): result = effect.apply(source, target, battlefield, context) results.append(result) # 如果目标已被摧毁,停止应用后续效果 if (isinstance(target, type(source)) and hasattr(target, 'stats') and not target.stats.is_alive()): break return { "success": True, "effect_type": "composite", "sub_effects": results } class ConditionalEffect(Effect): """条件效果 - 只在满足条件时应用""" def __init__(self, effect: Effect, condition: callable, name: str = "CONDITIONAL_EFFECT"): super().__init__(name, effect.effect_type, f"条件: {effect.description}") self.effect = effect self.condition = condition def can_apply(self, source: 'Unit', target: Any, battlefield: 'Battlefield') -> bool: return self.condition(source, target, battlefield) def apply(self, source: 'Unit', target: Any, battlefield: 'Battlefield', context: Dict[str, Any] = None) -> Dict[str, Any]: if not self.can_apply(source, target, battlefield): return { "success": False, "reason": "Condition not met", "effect_type": self.effect_type.value } return self.effect.apply(source, target, battlefield, context) class EffectBuilder: """效果构建器 - 用于创建复杂效果""" def __init__(self): self.effects = [] def add_damage(self, damage: int) -> 'EffectBuilder': """添加伤害效果""" self.effects.append(DamageEffect(damage)) return self def add_heal(self, heal_amount: int) -> 'EffectBuilder': """添加治疗效果""" self.effects.append(HealEffect(heal_amount)) return self def add_buff_attack(self, bonus: int, duration: int = -1) -> 'EffectBuilder': """添加攻击力增益""" self.effects.append(BuffAttackEffect(bonus, duration)) return self def add_buff_defense(self, bonus: int, duration: int = -1) -> 'EffectBuilder': """添加防御力增益""" self.effects.append(BuffDefenseEffect(bonus, duration)) return self def add_keyword(self, keyword: str) -> 'EffectBuilder': """添加关键词""" self.effects.append(AddKeywordEffect(keyword)) return self def remove_keyword(self, keyword: str) -> 'EffectBuilder': """移除关键词""" self.effects.append(RemoveKeywordEffect(keyword)) return self def add_conditional(self, effect: Effect, condition: callable) -> 'EffectBuilder': """添加条件效果""" self.effects.append(ConditionalEffect(effect, condition)) return self def build_single(self) -> Optional[Effect]: """构建单个效果(如果只有一个)""" if len(self.effects) == 1: return self.effects[0] elif len(self.effects) > 1: return CompositeEffect(self.effects) return None def build_composite(self, name: str = "COMPOSITE_EFFECT") -> CompositeEffect: """构建复合效果""" return CompositeEffect(self.effects, name) def build_all(self) -> List[Effect]: """构建所有效果的列表""" return self.effects.copy()