179 lines
5.8 KiB
Python
179 lines
5.8 KiB
Python
"""
|
|
关键词管理器基类
|
|
为所有关键词效果管理器提供统一的基础架构
|
|
"""
|
|
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}") |