""" 关键词管理器基类 为所有关键词效果管理器提供统一的基础架构 """ from abc import ABC, abstractmethod from typing import List, Optional, Dict, Any import logging from ..event_system import EventSubscriber, EventType, GameEvent from ...core.enums import LineType # 避免循环导入 from typing import TYPE_CHECKING if TYPE_CHECKING: from ...units.unit import Unit class KeywordManager(EventSubscriber, ABC): """关键词管理器抽象基类""" def __init__(self, unit: 'Unit', keyword: str): """ 初始化关键词管理器 Args: unit: 管理的单位 keyword: 关键词名称 """ self.unit = unit self.keyword = keyword self.active = True self.logger = logging.getLogger(f"{self.__class__.__name__}") @abstractmethod def get_subscribed_events(self) -> List[EventType]: """返回此管理器关心的事件类型""" pass def can_handle_event(self, event: GameEvent) -> bool: """判断是否应该处理此事件""" # 只处理与自己单位相关的事件 if event.source == self.unit or event.target == self.unit: return self.active and super().can_handle_event(event) return False def deactivate(self, reason: str = ""): """停用此管理器""" if self.active: self.active = False self.logger.debug(f"Deactivated {self.keyword} manager for unit {self.unit.id}: {reason}") self._on_deactivate(reason) def activate(self, reason: str = ""): """激活此管理器""" if not self.active: self.active = True self.logger.debug(f"Activated {self.keyword} manager for unit {self.unit.id}: {reason}") self._on_activate(reason) def _on_deactivate(self, reason: str): """停用时的回调(子类可重写)""" pass def _on_activate(self, reason: str): """激活时的回调(子类可重写)""" pass def remove_keyword_from_unit(self, reason: str = ""): """从单位移除关键词并停用管理器""" if self.unit.has_keyword(self.keyword): self.unit.remove_keyword(self.keyword) self.logger.debug(f"Removed {self.keyword} from unit {self.unit.id}: {reason}") self.deactivate(reason) def is_unit_in_support_line(self) -> bool: """检查单位是否在支援线""" if not self.unit.position: return False line_type, _ = self.unit.position return line_type in [LineType.PLAYER1_SUPPORT, LineType.PLAYER2_SUPPORT] def is_unit_in_front_line(self) -> bool: """检查单位是否在前线""" if not self.unit.position: return False line_type, _ = self.unit.position return line_type == LineType.FRONT def __str__(self) -> str: return f"{self.__class__.__name__}({self.keyword}, unit={self.unit.id}, active={self.active})" def __repr__(self) -> str: return self.__str__() class ConditionalKeywordManager(KeywordManager): """ 条件性关键词管理器基类 适用于需要根据条件自动激活/停用的关键词 """ def __init__(self, unit: 'Unit', keyword: str): super().__init__(unit, keyword) @abstractmethod def check_conditions(self, event: GameEvent) -> bool: """ 检查条件是否满足 Returns: True: 条件满足,关键词应该生效 False: 条件不满足,关键词应该失效 """ pass def handle_event(self, event: GameEvent) -> None: """处理事件并根据条件更新状态""" # 先让子类处理特定逻辑 self.handle_specific_event(event) # 然后检查条件 should_be_active = self.check_conditions(event) if should_be_active and not self.active: self.activate(f"conditions met after {event.event_type}") elif not should_be_active and self.active: self.remove_keyword_from_unit(f"conditions not met after {event.event_type}") @abstractmethod def handle_specific_event(self, event: GameEvent) -> None: """处理特定事件的逻辑(子类实现)""" pass class ProtectiveKeywordManager(KeywordManager): """ 保护性关键词管理器基类 适用于阻止攻击等保护效果的关键词 """ def get_protection_priority(self) -> int: """返回保护效果的优先级(数字越小优先级越高)""" return 50 def get_priority(self, event_type: EventType) -> int: """保护性效果通常需要较高优先级""" if event_type == EventType.BEFORE_ATTACK_CHECK: return self.get_protection_priority() return super().get_priority(event_type) @abstractmethod def should_protect_from_attack(self, attacker: 'Unit', event: GameEvent) -> bool: """ 判断是否应该保护单位免受攻击 Args: attacker: 攻击者 event: 攻击检查事件 Returns: True: 应该保护,阻止攻击 False: 不保护,允许攻击 """ pass def handle_attack_check(self, event: GameEvent) -> None: """处理攻击检查事件""" if event.target != self.unit or not self.active: return attacker = event.source if not attacker: return if self.should_protect_from_attack(attacker, event): event.cancel(f"Protected by {self.keyword}") self.logger.debug(f"Protected {self.unit.id} from attack by {attacker.id}")