# coding: utf-8 import typing from synergine2.simulation import SubjectBehaviourSelector from synergine2.simulation import SubjectBehaviour from opencombat.user_action import UserAction from synergine2_xyz.move.intention import MoveToIntention from opencombat.const import COLLECTION_ALIVE from opencombat.const import COMBAT_MODE_DEFEND from opencombat.simulation.base import BaseSubject from opencombat.simulation.move import MoveBehaviour from opencombat.simulation.move import MoveWithRotationBehaviour from opencombat.simulation.behaviour import EngageOpponent from opencombat.simulation.behaviour import LookAroundBehaviour from synergine2.share import shared class TileBehaviourSelector(SubjectBehaviourSelector): def reduce_behaviours( self, behaviours: typing.Dict[typing.Type[SubjectBehaviour], object], ) -> typing.Dict[typing.Type[SubjectBehaviour], object]: return behaviours class TileSubject(BaseSubject): start_collections = [ COLLECTION_ALIVE, ] visible_opponent_ids = shared.create_self('visible_opponent_ids', lambda: []) combat_mode = shared.create_self('combat_mode', COMBAT_MODE_DEFEND) behaviour_selector_class = TileBehaviourSelector direction = shared.create_self('direction', 0) moving_to = shared.create_self('moving_to', (-1, -1)) move_duration = shared.create_self('move_duration', -1) start_move = shared.create_self('start_move', -1) rotate_to = shared.create_self('rotate_to', -1) rotate_duration = shared.create_self('rotate_duration', -1) start_rotation = shared.create_self('start_rotation', -1) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._walk_ref_time = float(self.config.resolve('game.move.walk_ref_time')) self._run_ref_time = float(self.config.resolve('game.move.run_ref_time')) self._crawl_ref_time = float(self.config.resolve('game.move.crawl_ref_time')) self._rotate_ref_time = float(self.config.resolve('game.move.rotate_ref_time')) self.direction = kwargs.get('direction', 0) @property def global_move_coeff(self) -> float: return 1 @property def run_duration(self) -> float: """ :return: move to tile time (s) when running """ return self._run_ref_time * self.global_move_coeff @property def walk_duration(self) -> float: """ :return: move to tile time (s) when walking """ return self._walk_ref_time * self.global_move_coeff @property def crawl_duration(self) -> float: """ :return: move to tile time (s) when crawling """ return self._crawl_ref_time * self.global_move_coeff def get_rotate_duration(self, angle: float) -> float: return angle * self._rotate_ref_time def get_move_duration(self, move: MoveToIntention) -> float: gui_action = move.gui_action if gui_action == UserAction.ORDER_MOVE: return self.walk_duration if gui_action == UserAction.ORDER_MOVE_FAST: return self.run_duration if gui_action == UserAction.ORDER_MOVE_CRAWL: return self.crawl_duration raise NotImplementedError( 'Gui action {} unknown'.format(move.gui_action) ) class ManSubject(TileSubject): behaviours_classes = [ MoveBehaviour, LookAroundBehaviour, EngageOpponent, ] # type: typing.List[SubjectBehaviour] class TankSubject(TileSubject): behaviours_classes = [ MoveWithRotationBehaviour, LookAroundBehaviour, EngageOpponent, ] # type: typing.List[SubjectBehaviour] def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) # TODO BS 2018-01-26: This coeff will be dependent of real # unit type (tiger 2, etc) self._global_move_coeff = self.config.resolve( 'game.move.subject.tank1.global_move_coeff', 3, ) self._rotate_ref_time = float(self.config.resolve( 'game.move.subject.tank1.rotate_ref_time', 0.1111, )) @property def global_move_coeff(self) -> float: return self._global_move_coeff