def start(self, startCtx=None):
     """
     Battle session is started.
     :param startCtx: instance of BattleSessionProviderStartCtx.
     :return:
     """
     isReplayRecording = startCtx.replayCtrl.isRecording
     isReplayPlaying = startCtx.replayCtrl.isPlaying
     self.__arenaDP = ArenaDataProvider(avatar=startCtx.avatar)
     self.__ctx.start(self.__arenaDP)
     self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying,
                                                  isReplayRecording)
     self.__equipmentsCtrl = consumables.createEquipmentCtrl(
         isReplayPlaying)
     self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
     self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(
         isReplayRecording)
     self.__arenaLoadCtrl = ArenaLoadController()
     self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
     self.__periodCtrl = createPeriodCtrl(isReplayPlaying,
                                          isReplayRecording)
     self.__respawnsCtrl = RespawnsController(startCtx)
     self.__repairCtrl = RepairController()
     self.__dynSquadFunctional = DynSquadFunctional(isReplayPlaying)
     self.__notificationsCtrl = NotificationsController(self.__arenaDP)
     self.__gasAttackCtrl = GasAttackController(startCtx)
     ctx = weakref.proxy(self.__ctx)
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
     self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
     self.__arenaListeners.addController(ctx, self.__periodCtrl)
     self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
     self.__arenaListeners.addController(ctx, self.__dynSquadFunctional)
     self.__arenaListeners.start(startCtx.avatar.arena,
                                 arenaDP=self.__arenaDP)
     self.__feedback = createFeedbackAdaptor(isReplayPlaying)
     self.__feedback.start(self.__arenaDP)
     self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
     self.__messagesCtrl.start(ctx)
     self.__drrScaleCtrl = DRRScaleController()
     self.__drrScaleCtrl.start(self.__messagesCtrl)
     self.__hitDirectionCtrl = HitDirectionController()
     self.__hitDirectionCtrl.start()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
     self.__chatCommands = ChatCommandsController()
     self.__chatCommands.start(self.__arenaDP, self.__feedback)
     self.__requestsCtrl = AvatarRequestsController()
     self.__avatarStatsCtrl = AvatarStatsController()
     self.__debugCtrl = DebugController()
     self.__debugCtrl.start()
     self.__viewComponentsBridge = createComponentsBridge()
     self.__viewComponentsBridge.registerControllers(
         (BATTLE_CTRL.PERIOD, self.__periodCtrl),
         (BATTLE_CTRL.TEAM_BASES, self.__arenaTeamsBasesCtrl),
         (BATTLE_CTRL.DEBUG, self.__debugCtrl),
         (BATTLE_CTRL.HIT_DIRECTION, self.__hitDirectionCtrl))
Пример #2
0
 def start(self):
     import BattleReplay
     replayCtrl = BattleReplay.g_replayCtrl
     if isEventBattle():
         replayCtrl.enableAutoRecordingBattles(0)
     isReplayRecording = replayCtrl.isRecording
     isReplayPlaying = replayCtrl.isPlaying
     self.__arenaDP = ArenaDataProvider()
     self.__ctx.start(self.__arenaDP)
     self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
     self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
     self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
     self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
     self.__chatCommands = ChatCommandsController()
     self.__arenaLoadCtrl = ArenaLoadController()
     self.__drrScaleCtrl = DRRScaleController()
     self.__respawnsCtrl = RespawnsController()
     self.__notificationsCtrl = NotificationsController()
     self.__repairCtrl = RepairController()
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.addController(weakref.proxy(self.__ctx), self.__arenaLoadCtrl)
     self.__arenaListeners.addController(weakref.proxy(self.__ctx), self.__respawnsCtrl)
     self.__arenaListeners.start(arenaDP=self.__arenaDP)
     self.__feedback = createFeedbackAdaptor(isReplayPlaying)
     self.__feedback.start(self.__arenaDP)
     self.__requestsCtrl = AvatarRequestsController()
 def start(self, setup):
     self.__isReplayPlaying = setup.isReplayPlaying
     self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
     setup.sessionProvider = weakref.proxy(self)
     self.__arenaDP = ArenaDataProvider(setup)
     self.__ctx.start(self.__arenaDP)
     self.__battleCache.load()
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.start(setup)
     self.__viewComponentsBridge = createComponentsBridge()
     setup.sessionProvider = weakref.proxy(self)
     self.__sharedRepo = controllers.createShared(setup)
     self.__dynamicRepo = controllers.createDynamic(setup)
     self.__requestsCtrl = AvatarRequestsController()
     self.__invitations = invitations.createInvitationsHandler(setup)
     setup.clear()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
Пример #4
0
 def start(self, avatar=None):
     import BattleReplay
     replayCtrl = BattleReplay.g_replayCtrl
     isReplayRecording = replayCtrl.isRecording
     isReplayPlaying = replayCtrl.isPlaying
     self.__arenaDP = ArenaDataProvider(avatar=avatar)
     self.__ctx.start(self.__arenaDP)
     self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying,
                                                  isReplayRecording)
     self.__equipmentsCtrl = consumables.createEquipmentCtrl(
         isReplayPlaying)
     self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
     self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(
         isReplayRecording)
     isMultiTeam = self.__arenaDP.isMultipleTeams()
     self.__arenaLoadCtrl = ArenaLoadController(isMultiTeam)
     self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
     self.__periodCtrl = createPeriodCtrl(isReplayPlaying,
                                          isReplayRecording)
     self.__drrScaleCtrl = DRRScaleController()
     self.__respawnsCtrl = RespawnsController()
     self.__repairCtrl = RepairController()
     self.__dynSquadFunctional = DynSquadFunctional()
     self.__notificationsCtrl = NotificationsController(self.__arenaDP)
     ctx = weakref.proxy(self.__ctx)
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
     self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
     self.__arenaListeners.addController(ctx, self.__periodCtrl)
     self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
     self.__arenaListeners.start(getClientArena(avatar=avatar),
                                 arenaDP=self.__arenaDP)
     self.__feedback = createFeedbackAdaptor(isReplayPlaying)
     self.__feedback.start(self.__arenaDP)
     self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
     self.__messagesCtrl.start(ctx)
     self.__hitDirectionCtrl = HitDirectionController()
     self.__hitDirectionCtrl.start()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
     self.__chatCommands = ChatCommandsController()
     self.__chatCommands.start(self.__arenaDP, self.__feedback)
     self.__requestsCtrl = AvatarRequestsController()
     self.__avatarStatsCtrl = AvatarStatsController()
Пример #5
0
 def start(self, setup):
     """
     Battle session is started.
     :param setup: instance of BattleSessionSetup.
     :return:
     """
     raise isinstance(setup,
                      controllers.BattleSessionSetup) or AssertionError
     self.__isReplayPlaying = setup.isReplayPlaying
     self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
     setup.sessionProvider = weakref.proxy(self)
     self.__arenaDP = ArenaDataProvider(setup)
     self.__ctx.start(self.__arenaDP)
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.start(setup)
     self.__viewComponentsBridge = createComponentsBridge()
     setup.sessionProvider = weakref.proxy(self)
     self.__sharedRepo = controllers.createShared(setup)
     self.__dynamicRepo = controllers.createDynamic(setup)
     self.__requestsCtrl = AvatarRequestsController()
     self.__invitations = invitations.createInvitationsHandler(setup)
     setup.clear()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
 def start(self, startCtx = None):
     """
     Battle session is started.
     :param startCtx: instance of BattleSessionProviderStartCtx.
     :return:
     """
     isReplayRecording = startCtx.replayCtrl.isRecording
     isReplayPlaying = startCtx.replayCtrl.isPlaying
     self.__arenaDP = ArenaDataProvider(avatar=startCtx.avatar)
     self.__ctx.start(self.__arenaDP)
     self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
     self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
     self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
     self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
     self.__arenaLoadCtrl = ArenaLoadController()
     self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
     self.__periodCtrl = createPeriodCtrl(isReplayPlaying, isReplayRecording)
     self.__respawnsCtrl = RespawnsController(startCtx)
     self.__repairCtrl = RepairController()
     self.__dynSquadFunctional = DynSquadFunctional(isReplayPlaying)
     self.__notificationsCtrl = NotificationsController(self.__arenaDP)
     self.__gasAttackCtrl = GasAttackController(startCtx)
     ctx = weakref.proxy(self.__ctx)
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
     self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
     self.__arenaListeners.addController(ctx, self.__periodCtrl)
     self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
     self.__arenaListeners.addController(ctx, self.__dynSquadFunctional)
     self.__arenaListeners.start(startCtx.avatar.arena, arenaDP=self.__arenaDP)
     self.__feedback = createFeedbackAdaptor(isReplayPlaying)
     self.__feedback.start(self.__arenaDP)
     self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
     self.__messagesCtrl.start(ctx)
     self.__drrScaleCtrl = DRRScaleController()
     self.__drrScaleCtrl.start(self.__messagesCtrl)
     self.__hitDirectionCtrl = HitDirectionController()
     self.__hitDirectionCtrl.start()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
     self.__chatCommands = ChatCommandsController()
     self.__chatCommands.start(self.__arenaDP, self.__feedback)
     self.__requestsCtrl = AvatarRequestsController()
     self.__avatarStatsCtrl = AvatarStatsController()
     self.__debugCtrl = DebugController()
     self.__debugCtrl.start()
     self.__viewComponentsBridge = createComponentsBridge()
     self.__viewComponentsBridge.registerControllers((BATTLE_CTRL.PERIOD, self.__periodCtrl), (BATTLE_CTRL.TEAM_BASES, self.__arenaTeamsBasesCtrl), (BATTLE_CTRL.DEBUG, self.__debugCtrl), (BATTLE_CTRL.HIT_DIRECTION, self.__hitDirectionCtrl))
Пример #7
0
 def start(self, setup):
     """
     Battle session is started.
     :param setup: instance of BattleSessionSetup.
     :return:
     """
     raise isinstance(setup, controllers.BattleSessionSetup) or AssertionError
     self.__isReplayPlaying = setup.isReplayPlaying
     self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
     setup.sessionProvider = weakref.proxy(self)
     self.__arenaDP = ArenaDataProvider(setup)
     self.__ctx.start(self.__arenaDP)
     self.__arenaListeners = ListenersCollection()
     self.__arenaListeners.start(setup)
     self.__viewComponentsBridge = createComponentsBridge()
     setup.sessionProvider = weakref.proxy(self)
     self.__sharedRepo = controllers.createShared(setup)
     self.__dynamicRepo = controllers.createDynamic(setup)
     self.__requestsCtrl = AvatarRequestsController()
     self.__invitations = invitations.createInvitationsHandler(setup)
     setup.clear()
     g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
Пример #8
0
    def start(self, avatar=None):
        import BattleReplay

        replayCtrl = BattleReplay.g_replayCtrl
        isReplayRecording = replayCtrl.isRecording
        isReplayPlaying = replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider(avatar=avatar)
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
        isMultiTeam = self.__arenaDP.isMultipleTeams()
        self.__arenaLoadCtrl = ArenaLoadController(isMultiTeam)
        self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
        self.__periodCtrl = createPeriodCtrl(isReplayPlaying, isReplayRecording)
        self.__drrScaleCtrl = DRRScaleController()
        self.__respawnsCtrl = RespawnsController()
        self.__repairCtrl = RepairController()
        self.__dynSquadFunctional = DynSquadFunctional()
        self.__notificationsCtrl = NotificationsController(self.__arenaDP)
        ctx = weakref.proxy(self.__ctx)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
        self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
        self.__arenaListeners.addController(ctx, self.__periodCtrl)
        self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
        self.__arenaListeners.start(getClientArena(avatar=avatar), arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
        self.__messagesCtrl.start(ctx)
        self.__hitDirectionCtrl = HitDirectionController()
        self.__hitDirectionCtrl.start()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.__chatCommands = ChatCommandsController()
        self.__chatCommands.start(self.__arenaDP, self.__feedback)
        self.__requestsCtrl = AvatarRequestsController()
        self.__avatarStatsCtrl = AvatarStatsController()
Пример #9
0
class BattleSessionProvider(object):
    """This class is backend of GUI for one battle session."""
    __slots__ = ('__ctx', '__sharedRepo', '__dynamicRepo', '__requestsCtrl', '__arenaDP', '__arenaListeners', '__viewComponentsBridge', '__weakref__', '__arenaVisitor', '__invitations', '__isReplayPlaying')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__sharedRepo = controllers.SharedControllersLocator()
        self.__dynamicRepo = controllers.DynamicControllersLocator()
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__arenaListeners = None
        self.__viewComponentsBridge = None
        self.__invitations = None
        self.__isReplayPlaying = False
        return

    @property
    def shared(self):
        """ Returns reference to repository of shared controllers
        that are created for all game sessions.
        :return: instance of SharedControllersLocator.
        """
        return self.__sharedRepo

    @property
    def dynamic(self):
        """ Returns reference to repository of controllers
        that are created for some game sessions.
        :return: instance of DynamicControllersLocator.
        """
        return self.__dynamicRepo

    @property
    def arenaVisitor(self):
        """ Returns reference to visitor that has safe access to properties of arena.
        :return: instance of _ClientArenaVisitor.
        """
        return self.__arenaVisitor

    @property
    def invitations(self):
        """ Returns reference to invitations handler.
        :return: instance of _SquadInvitationsHandler.
        """
        return self.__invitations

    def getCtx(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ctx

    @async
    def sendRequest(self, ctx, callback, allowDelay = None):
        """
        Sends request to the server.
        :param ctx: avatar request context object,
            @see gui.battle_control.request.context.
        :param callback: function that is invoked when response is received.
        :param allowDelay: bool.
        """
        self.__requestsCtrl.request(ctx, callback=callback, allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.setGunSettings(vDesc.gun)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.spawnVehicle(vID)
        g_tankActiveCamouflage[vDesc.type.compactDescr] = self.__arenaVisitor.type.getVehicleCamouflageKind()
        return

    def getArenaDP(self):
        """Gets instance of arena data provider.
        :return: instance of ArenaDataProvider.
        """
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        """Adds arena controller. For additional information see
            gui.arena_info.IArenaController.
        :param controller: object that implements IArenaController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__arenaListeners is not None:
            return self.__arenaListeners.addController(controller)
        else:
            return False
            return

    def removeArenaCtrl(self, controller):
        """Removes arena controller.
        :param controller: object extends IArenaController.
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def registerViewComponentsCtrl(self, controller):
        """Registers controller in the bridge of view components.
        :param controller: object that implements IViewComponentsController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerController(controller)
            return True
        else:
            return False
            return

    def registerViewComponents(self, *data):
        """Sets view component data to find that components in routines
            addViewComponent, removeViewComponent.
        :param data: tuple((BATTLE_CTRL.*, (componentID, ...)), ...)
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self, componentID, component, rule = VIEW_COMPONENT_RULE.PROXY):
        """View component has been created.
        :param componentID: string containing unique component ID.
        :param component: instance of component.
        :param rule: one of VIEW_COMPONENT_RULE.*.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID, component, rule=rule)
        return

    def removeViewComponent(self, componentID):
        """View component has been removed.
        :param componentID: string containing unique component ID.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def getExitResult(self):
        """ Gets result if player exits battle that are helped to notify player about penalty (if they have).
        :return: instance of BattleExitResult(isDeserter, player).
        """
        if not self.__isReplayPlaying and not self.__arenaVisitor.gui.isTrainingBattle():
            vInfo = self.__arenaDP.getVehicleInfo()
            vStats = self.__arenaDP.getVehicleStats()
            if self.__arenaVisitor.gui.isEventBattle():
                isDeserter = False
            elif self.__arenaVisitor.hasRespawns():
                isDeserter = not vStats.stopRespawn
            else:
                isDeserter = avatar_getter.isVehicleAlive() and not avatar_getter.isVehicleOverturned()
            return BattleExitResult(isDeserter, vInfo.player)
        else:
            return BattleExitResult(False, None)
            return None

    @staticmethod
    def exit():
        """Exits from current battle session."""
        avatar_getter.leaveArena()

    def start(self, setup):
        """
        Battle session is started.
        :param setup: instance of BattleSessionSetup.
        :return:
        """
        raise isinstance(setup, controllers.BattleSessionSetup) or AssertionError
        self.__isReplayPlaying = setup.isReplayPlaying
        self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
        setup.sessionProvider = weakref.proxy(self)
        self.__arenaDP = ArenaDataProvider(setup)
        self.__ctx.start(self.__arenaDP)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.start(setup)
        self.__viewComponentsBridge = createComponentsBridge()
        setup.sessionProvider = weakref.proxy(self)
        self.__sharedRepo = controllers.createShared(setup)
        self.__dynamicRepo = controllers.createDynamic(setup)
        self.__requestsCtrl = AvatarRequestsController()
        self.__invitations = invitations.createInvitationsHandler(setup)
        setup.clear()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__invitations is not None:
            self.__invitations.clear()
            self.__invitations = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__sharedRepo.destroy()
        self.__dynamicRepo.destroy()
        self.__arenaVisitor.clear()
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__ctx.stop()
        return

    def switchToPostmortem(self):
        """Player's vehicle is destroyed, switchers GUI to postmortem mode."""
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.setPlayerVehicle(0L)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.switchToPostmortem()
        return

    def useLoaderIntuition(self):
        """Loader intuition was used."""
        ctrl = self.__sharedRepo.messages
        if ctrl is not None:
            ctrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.useLoaderIntuition()
        return

    def movingToRespawnBase(self):
        """Player's avatar is moving to the respawn."""
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.movingToRespawn()
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.movingToRespawn()
        return

    def invalidateVehicleState(self, state, value, vehicleID = 0):
        """State of player's vehicle (health, fire, state of device, etc.) is
        changed, notifies GUI about it.
        :param state: one of VEHICLE_VIEW_STATE.*.
        :param value: value of state.
        :param vehicleID: vehicle ID or zero.
        """
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            ctrl = self.__sharedRepo.ammo
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.equipments
            if ctrl is not None:
                ctrl.clear(leave=False)
        return

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        ctrl = self.__dynamicRepo.repair
        if ctrl is not None:
            ctrl.action(repairPointIndex, action, nextActionTime)
        return

    def updateAvatarPrivateStats(self, stats):
        ctrl = self.__sharedRepo.privateStats
        if ctrl is not None:
            ctrl.update(stats)
        return

    def addHitDirection(self, hitDirYaw, isDamage):
        ctrl = self.__sharedRepo.hitDirection
        if ctrl is not None:
            ctrl.addHit(hitDirYaw, isDamage)
        return

    def startVehicleVisual(self, vProxy, isImmediate = False):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__dynamicRepo.debug
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy.id)
        return

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID, isPlayerVehicle)
        ctrl = self.__dynamicRepo.debug
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID)
        return

    def handleShortcutChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is not None:
            ctrl.handleShortcutChatCommand(key)
        return

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        """It's listener of event _PlayerEvents.onBattleResultsReceived.
        :param isActiveVehicle: bool.
        """
        if isActiveVehicle:
            arenaUniqueID = self.__arenaVisitor.getArenaUniqueID()
            LOG_DEBUG('Try to exit from arena', arenaUniqueID)
            if arenaUniqueID:
                self.__ctx.lastArenaUniqueID = arenaUniqueID
            avatar_getter.leaveArena()
Пример #10
0
class BattleSessionProvider(IBattleSessionProvider):
    __slots__ = ('__ctx', '__sharedRepo', '__dynamicRepo', '__requestsCtrl',
                 '__arenaDP', '__arenaListeners', '__viewComponentsBridge',
                 '__weakref__', '__arenaVisitor', '__invitations',
                 '__isReplayPlaying', '__battleCache',
                 'onUpdateObservedVehicleData')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__sharedRepo = controllers.SharedControllersLocator()
        self.__dynamicRepo = controllers.DynamicControllersLocator()
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__arenaListeners = None
        self.__viewComponentsBridge = None
        self.__invitations = None
        self.__isReplayPlaying = False
        self.__battleCache = BattleClientCache()
        self.onBattleSessionStart = Event.Event()
        self.onBattleSessionStop = Event.Event()
        self.onUpdateObservedVehicleData = Event.Event()
        return

    @property
    def shared(self):
        return self.__sharedRepo

    @property
    def dynamic(self):
        return self.__dynamicRepo

    @property
    def arenaVisitor(self):
        return self.__arenaVisitor

    @property
    def invitations(self):
        return self.__invitations

    @property
    def battleCache(self):
        return self.__battleCache

    @property
    def isReplayPlaying(self):
        return self.__isReplayPlaying

    def getCtx(self):
        return self.__ctx

    @async
    def sendRequest(self, ctx, callback, allowDelay=None):
        self.__requestsCtrl.request(ctx,
                                    callback=callback,
                                    allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        ctrl = self.shared.prebattleSetups
        isSetupsSelectionStarted = ctrl.isSelectionStarted(
        ) if ctrl is not None else False
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            if not isSetupsSelectionStarted:
                ctrl.clearAmmo()
                ctrl.setGunSettings(vDesc.gun)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.notifyPlayerVehicleSet(vID)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.shared.prebattleSetups
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID, vDesc)
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.spawnVehicle(vID)
        mapKind = self.__arenaVisitor.type.getVehicleCamouflageKind()
        g_tankActiveCamouflage[
            vDesc.type.compactDescr] = SeasonType.fromArenaKind(mapKind)
        return

    def switchVehicle(self, vehicleID):
        repo = self.shared
        if repo.vehicleState is not None and repo.vehicleState.getControllingVehicleID(
        ) != vehicleID:
            for ctrl in (repo.ammo, repo.equipments, repo.optionalDevices):
                if ctrl is not None:
                    ctrl.clear(False)

        repo.vehicleState.switchToOther(vehicleID)
        return

    def updateObservedVehicleData(self, vehicle):
        ammoCtrl = self.__sharedRepo.ammo
        if ammoCtrl is not None:
            ammoCtrl.clear(False)
            ammoCtrl.setGunSettings(vehicle.typeDescriptor.gun)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl.notifyPlayerVehicleSet(vehicle.id)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        vehicle.ownVehicle.initialUpdate(force=True)
        self.updateVehicleEffects()
        self.onUpdateObservedVehicleData(vehicle.id, None)
        return

    def updateVehicleEffects(self):
        if not self.__sharedRepo.vehicleState:
            return
        else:
            vehicle = self.__sharedRepo.vehicleState.getControllingVehicle()
            if vehicle is not None:
                if vehicle.debuff:
                    vehicle.onDebuffEffectApplied(True)
                if vehicle.stunInfo > 0.0:
                    vehicle.updateStunInfo()
                if vehicle.inspired:
                    vehicle.set_inspired()
                if vehicle.healing:
                    vehicle.set_healing()
            return

    def getArenaDP(self):
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        return self.__arenaListeners.addController(
            controller) if self.__arenaListeners is not None else False

    def removeArenaCtrl(self, controller):
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def registerViewComponentsCtrl(self, controller):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerController(controller)
            return True
        else:
            return False

    def registerViewComponents(self, *data):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
            return True
        else:
            return False

    def addViewComponent(self,
                         componentID,
                         component,
                         rule=VIEW_COMPONENT_RULE.PROXY):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID,
                                                         component,
                                                         rule=rule)
        return

    def removeViewComponent(self, componentID):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def getExitResult(self):
        if not self.__isReplayPlaying and not self.__arenaVisitor.gui.isTrainingBattle(
        ) and not self.__arenaVisitor.gui.isBattleRoyale(
        ) and not self.__arenaVisitor.gui.isMapsTraining():
            vInfo = self.__arenaDP.getVehicleInfo()
            vStats = self.__arenaDP.getVehicleStats()
            if self.__arenaVisitor.hasRespawns():
                isDeserter = not vStats.stopRespawn
            else:
                isDeserter = avatar_getter.isVehicleAlive(
                ) and not avatar_getter.isVehicleOverturned()
            return BattleExitResult(isDeserter, vInfo.player)
        else:
            return BattleExitResult(False, None)
            return None

    def exit(self):
        if self.__arenaVisitor.gui.isMapsTraining():
            self.__onMapsTrainingExit()
        avatar_getter.leaveArena()

    def start(self, setup):
        self.__isReplayPlaying = setup.isReplayPlaying
        self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
        setup.sessionProvider = weakref.proxy(self)
        self.__arenaDP = ArenaDataProvider(setup)
        self.__ctx.start(self.__arenaDP)
        self.__battleCache.load()
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.start(setup)
        self.__viewComponentsBridge = createComponentsBridge()
        setup.sessionProvider = weakref.proxy(self)
        self.__sharedRepo = controllers.createShared(setup)
        self.__dynamicRepo = controllers.createDynamic(setup)
        self.__requestsCtrl = AvatarRequestsController()
        self.__invitations = invitations.createInvitationsHandler(setup)
        setup.clear()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.onBattleSessionStart()

    def stop(self):
        self.onBattleSessionStop()
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__invitations is not None:
            self.__invitations.clear()
            self.__invitations = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__sharedRepo.destroy()
        self.__dynamicRepo.destroy()
        self.__arenaVisitor.clear()
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__battleCache.clear()
        self.__ctx.stop()
        return

    def switchToPostmortem(self,
                           noRespawnPossible=True,
                           respawnAvailable=False):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.switchToPostmortem(noRespawnPossible, respawnAvailable)
        return

    def updateVehicleQuickShellChanger(self, isActive):
        ammoCtrl = self.__sharedRepo.ammo
        if ammoCtrl is not None:
            ammoCtrl.updateVehicleQuickShellChanger(isActive)
        return

    def movingToRespawnBase(self):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.movingToRespawn()
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.movingToRespawn()
        return

    def invalidateVehicleState(self, state, value, vehicleID=0):
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            ctrl = self.__sharedRepo.ammo
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.equipments
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.optionalDevices
            if ctrl is not None:
                ctrl.clear(leave=False)
        return

    def setVehicleHealth(self, isPlayerVehicle, vehicleID, newHealth,
                         attackerID, attackReasonID):
        if not isPlayerVehicle:
            ctrl = self.__sharedRepo.feedback
            if ctrl is not None:
                ctrl.setVehicleNewHealth(vehicleID, newHealth, attackerID,
                                         attackReasonID)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleHealth(vehicleID, newHealth)
        return

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        ctrl = self.__dynamicRepo.repair
        if ctrl is not None:
            ctrl.action(repairPointIndex, action, nextActionTime)
        return

    def updateAvatarPrivateStats(self, stats):
        ctrl = self.__sharedRepo.privateStats
        if ctrl is not None:
            ctrl.update(stats)
        return

    def addHitDirection(self, hitDirYaw, attackerID, damage, isBlocked,
                        critFlags, isHighExplosive, damagedID, attackReasonID):
        hitDirectionCtrl = self.__sharedRepo.hitDirection
        if hitDirectionCtrl is not None:
            hitDirectionCtrl.addHit(hitDirYaw, attackerID, damage, isBlocked,
                                    critFlags, isHighExplosive, damagedID,
                                    attackReasonID)
        return

    def startVehicleVisual(self, vProxy, isImmediate=False):
        vehicleID = vProxy.id
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleVisible(vehicleID, vProxy.health)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None and BigWorld.player(
        ).observedVehicleID == vehicleID:
            ctrl.refreshObserverVehicleVisual()
        return

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID, isPlayerVehicle)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID)
        return

    def handleShortcutChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is None:
            return
        else:
            if self.__arenaVisitor.gui.isInEpicRange():
                mapCtrl = self.dynamic.maps
                if not mapCtrl or mapCtrl.overviewMapScreenVisible:
                    return
            ctrl.handleShortcutChatCommand(key)
            return

    def handleContexChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is None:
            return
        else:
            ctrl.handleContexChatCommand(key)
            return

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        if isActiveVehicle and not BattleReplay.g_replayCtrl.isPlaying:
            arenaUniqueID = self.__arenaVisitor.getArenaUniqueID()
            arenaBonusType = self.__arenaVisitor.getArenaBonusType()
            LOG_DEBUG('Try to exit from arena', arenaUniqueID, arenaBonusType)
            if arenaUniqueID:
                self.__ctx.lastArenaUniqueID = arenaUniqueID
            if arenaBonusType:
                self.__ctx.lastArenaBonusType = arenaBonusType
            self.exit()

    def __onMapsTrainingExit(self):
        if not BattleReplay.isPlaying(
        ) and self.__ctx.lastArenaUniqueID is None:
            self.__ctx.lastArenaUniqueID = self.__arenaVisitor.getArenaUniqueID(
            )
            self.__ctx.lastArenaBonusType = self.__arenaVisitor.getArenaBonusType(
            )
        return
class BattleSessionProvider(object):
    __slots__ = ('__ammoCtrl', '__equipmentsCtrl', '__optDevicesCtrl', '__vehicleStateCtrl', '__chatCommands', '__drrScaleCtrl', '__feedback', '__ctx', '__arenaDP', '__arenaListeners', '__arenaLoadCtrl', '__respawnsCtrl', '__notificationsCtrl', '__isBattleUILoaded', '__arenaTeamsBasesCtrl', '__periodCtrl', '__messagesCtrl', '__repairCtrl', '__hitDirectionCtrl', '__requestsCtrl', '__avatarStatsCtrl', '__dynSquadFunctional', '__weakref__', '__gasAttackCtrl')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__ammoCtrl = None
        self.__equipmentsCtrl = None
        self.__optDevicesCtrl = None
        self.__vehicleStateCtrl = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__feedback = None
        self.__messagesCtrl = None
        self.__hitDirectionCtrl = None
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__dynSquadFunctional = None
        self.__avatarStatsCtrl = None
        self.__arenaListeners = None
        self.__isBattleUILoaded = False
        self.__gasAttackCtrl = None
        return

    def isBattleUILoaded(self):
        return self.__isBattleUILoaded

    def getCtx(self):
        return self.__ctx

    def getAmmoCtrl(self):
        return self.__ammoCtrl

    def getEquipmentsCtrl(self):
        return self.__equipmentsCtrl

    def getOptDevicesCtrl(self):
        return self.__optDevicesCtrl

    def getVehicleStateCtrl(self):
        return self.__vehicleStateCtrl

    def getChatCommands(self):
        return self.__chatCommands

    def getDrrScaleCtrl(self):
        return self.__drrScaleCtrl

    def getRespawnsCtrl(self):
        return self.__respawnsCtrl

    def getNotificationsCtrl(self):
        return self.__notificationsCtrl

    def getRepairCtrl(self):
        return self.__repairCtrl

    def getFeedback(self):
        return self.__feedback

    def getBattleMessagesCtrl(self):
        return self.__messagesCtrl

    def getHitDirectionCtrl(self):
        return self.__hitDirectionCtrl

    def getAvatarStatsCtrl(self):
        return self.__avatarStatsCtrl

    def getArenaTeamsBasesCtrl(self):
        return self.__arenaTeamsBasesCtrl

    def getPeriodCtrl(self):
        return self.__periodCtrl

    def getGasAttackCtrl(self):
        return self.__gasAttackCtrl

    @async
    def sendRequest(self, ctx, callback, allowDelay = None):
        self.__requestsCtrl.request(ctx, callback=callback, allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        self.__ammoCtrl.setGunSettings(vDesc.gun)
        self.__vehicleStateCtrl.setPlayerVehicle(vID)
        self.__feedback.setPlayerVehicle(vID)
        self.__respawnsCtrl.spawnVehicle(vID)

    def setAimOffset(self, offset):
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.setOffset(offset)
        return

    def setAimPositionUpdated(self, mode, x, y):
        if self.__feedback is not None:
            self.__feedback.setAimPositionUpdated(mode, x, y)
        return

    def getArenaDP(self):
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.addController(weakref.proxy(self.__ctx), controller)

    def removeArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.removeController(controller)

    def start(self, startCtx = None):
        isReplayRecording = startCtx.replayCtrl.isRecording
        isReplayPlaying = startCtx.replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider(avatar=startCtx.avatar)
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
        isMultiTeam = self.__arenaDP.isMultipleTeams()
        self.__arenaLoadCtrl = ArenaLoadController(isMultiTeam)
        self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
        self.__periodCtrl = createPeriodCtrl(isReplayPlaying, isReplayRecording)
        self.__drrScaleCtrl = DRRScaleController()
        self.__respawnsCtrl = RespawnsController(startCtx)
        self.__repairCtrl = RepairController()
        self.__dynSquadFunctional = DynSquadFunctional(isReplayPlaying)
        self.__notificationsCtrl = NotificationsController(self.__arenaDP)
        self.__gasAttackCtrl = GasAttackController(startCtx)
        ctx = weakref.proxy(self.__ctx)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
        self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
        self.__arenaListeners.addController(ctx, self.__periodCtrl)
        self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
        self.__arenaListeners.start(startCtx.avatar.arena, arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
        self.__messagesCtrl.start(ctx)
        self.__hitDirectionCtrl = HitDirectionController()
        self.__hitDirectionCtrl.start()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.__chatCommands = ChatCommandsController()
        self.__chatCommands.start(self.__arenaDP, self.__feedback)
        self.__requestsCtrl = AvatarRequestsController()
        self.__avatarStatsCtrl = AvatarStatsController()

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__requestsCtrl:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__ammoCtrl:
            self.__ammoCtrl.clear()
            self.__ammoCtrl = None
        if self.__equipmentsCtrl:
            self.__equipmentsCtrl.clear()
            self.__equipmentsCtrl = None
        if self.__optDevicesCtrl:
            self.__optDevicesCtrl.clear()
            self.__optDevicesCtrl = None
        if self.__vehicleStateCtrl:
            self.__vehicleStateCtrl.clear()
            self.__vehicleStateCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__feedback is not None:
            self.__feedback.stop()
            self.__feedback = None
        if self.__messagesCtrl is not None:
            self.__messagesCtrl.stop()
            self.__messagesCtrl = None
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.stop()
            self.__hitDirectionCtrl = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        if self.__chatCommands is not None:
            self.__chatCommands.stop()
            self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__gasAttackCtrl = None
        self.__dynSquadFunctional = None
        if self.__avatarStatsCtrl is not None:
            self.__avatarStatsCtrl.stop()
            self.__avatarStatsCtrl = None
        self.__ctx.stop()
        return

    def setBattleUI(self, battleUI):
        raise not self.__isBattleUILoaded or AssertionError('Battle UI already is set')
        self.__isBattleUILoaded = True
        self.__arenaTeamsBasesCtrl.setUI(battleUI.getTeamBasesPanel())
        self.__periodCtrl.setUI(battleUI.getBattleTimer(), battleUI.getPreBattleTimer(), battleUI.getPlayersPanelsSwitcher())
        self.__hitDirectionCtrl.setUI(battleUI.getIndicators())
        self.__drrScaleCtrl.start(battleUI)
        self.__dynSquadFunctional.setUI(battleUI, self)

    def clearBattleUI(self):
        self.__isBattleUILoaded = False
        self.__arenaTeamsBasesCtrl.clearUI()
        self.__periodCtrl.clearUI()
        self.__hitDirectionCtrl.clearUI()
        self.__drrScaleCtrl.stop()
        self.__dynSquadFunctional.clearUI(self)

    def switchToPostmortem(self):
        self.__ammoCtrl.clear()
        self.__equipmentsCtrl.clear()
        self.__optDevicesCtrl.clear()
        self.__gasAttackCtrl.clear()
        self.__feedback.setPlayerVehicle(0)
        self.__vehicleStateCtrl.switchToPostmortem()

    def useLoaderIntuition(self):
        self.__messagesCtrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        self.__ammoCtrl.useLoaderIntuition()

    def movingToRespawnBase(self):
        self.__ammoCtrl.clear(False)
        self.__equipmentsCtrl.clear(False)
        self.__optDevicesCtrl.clear(False)
        self.__vehicleStateCtrl.movingToRespawn()
        self.__respawnsCtrl.movingToRespawn()

    def invalidateVehicleState(self, state, value, vehicleID = 0):
        self.__vehicleStateCtrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            self.__ammoCtrl.clear(False)
            self.__equipmentsCtrl.clear(False)

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        self.__repairCtrl.action(repairPointIndex, action, nextActionTime)

    def updateAvatarPrivateStats(self, stats):
        self.__avatarStatsCtrl.update(stats)

    def addHitDirection(self, hitDirYaw, isDamage):
        self.__hitDirectionCtrl.addHit(hitDirYaw, isDamage)

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        if isActiveVehicle:
            arena = getClientArena()
            LOG_DEBUG('Try to exit from arena', arena)
            if arena:
                self.__ctx.lastArenaUniqueID = arena.arenaUniqueID
            leaveArena()
class BattleSessionProvider(object):
    __slots__ = ('__ammoCtrl', '__equipmentsCtrl', '__optDevicesCtrl', '__vehicleStateCtrl', '__chatCommands', '__drrScaleCtrl', '__feedback', '__ctx', '__arenaDP', '__arenaListeners', '__arenaLoadCtrl', '__respawnsCtrl', '__notificationsCtrl', '__arenaTeamsBasesCtrl', '__periodCtrl', '__messagesCtrl', '__repairCtrl', '__hitDirectionCtrl', '__requestsCtrl', '__avatarStatsCtrl', '__dynSquadFunctional', '__weakref__', '__gasAttackCtrl', '__debugCtrl', '__viewComponentsBridge')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__ammoCtrl = None
        self.__equipmentsCtrl = None
        self.__optDevicesCtrl = None
        self.__vehicleStateCtrl = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__feedback = None
        self.__messagesCtrl = None
        self.__hitDirectionCtrl = None
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__dynSquadFunctional = None
        self.__avatarStatsCtrl = None
        self.__arenaListeners = None
        self.__gasAttackCtrl = None
        self.__debugCtrl = None
        self.__viewComponentsBridge = None
        return

    def getCtx(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ctx

    def getAmmoCtrl(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ammoCtrl

    def getEquipmentsCtrl(self):
        """
        Gets instance of equipments controller.
        :return: instance of EquipmentsController.
        """
        return self.__equipmentsCtrl

    def getOptDevicesCtrl(self):
        """
        Gets instance of optional devices controller.
        :return: instance of OptionalDevicesController.
        """
        return self.__optDevicesCtrl

    def getVehicleStateCtrl(self):
        """
        Gets instance of vehicle state controller.
        :return: instance of VehicleStateController.
        """
        return self.__vehicleStateCtrl

    def getChatCommands(self):
        """
        Gets instance of chat commands controller.
        :return: instance of ChatCommandsController.
        """
        return self.__chatCommands

    def getDrrScaleCtrl(self):
        """
        Gets instance of DRR scale controller.
        :return: instance of DRRScaleController.
        """
        return self.__drrScaleCtrl

    def getRespawnsCtrl(self):
        """
        Gets instance of respawns controller.
        :return: instance of RespawnsController.
        """
        return self.__respawnsCtrl

    def getNotificationsCtrl(self):
        """
        Gets instance of notification controller.
        :return: instance of NotificationController.
        """
        return self.__notificationsCtrl

    def getRepairCtrl(self):
        """
        Gets instance of repair controller.
        :return: instance of RepairController.
        """
        return self.__repairCtrl

    def getFeedback(self):
        """
        Gets instance of feedback adaptor to notify GUI about some events that
        needs to show response on player(s) actions.
        :return: instance of BattleFeedbackAdaptor.
        """
        return self.__feedback

    def getBattleMessagesCtrl(self):
        """
        Gets instance of messages controller to show messages in a battle.
        :return: instance of BattleMessagesController.
        """
        return self.__messagesCtrl

    def getHitDirectionCtrl(self):
        """
        Gets instance of hit direction controller to show damage indicator.
        :return: instance of HitDirectionController.
        """
        return self.__hitDirectionCtrl

    def getAvatarStatsCtrl(self):
        """
        Gets instance of avatar stats controller to track stats changes.
        :return: instance of AvatarStatsController.
        """
        return self.__avatarStatsCtrl

    def getArenaTeamsBasesCtrl(self):
        """
        Gets instance of arena team bases controller to track bases changes.
        :return: instance of BattleTeamsBasesController.
        """
        return self.__arenaTeamsBasesCtrl

    def getPeriodCtrl(self):
        """
        Gets instance of period controller to track time changes.
        :return: instance of ArenaPeriodController.
        """
        return self.__periodCtrl

    def getGasAttackCtrl(self):
        """
        Gets instance of gas attack controller.
        :return: instance of GasAttackController.
        """
        return self.__gasAttackCtrl

    def getDynSquadFunctional(self):
        """
        Gets instance of dynamic squad functional.
        :return: instance of DynSquadFunctional.
        """
        return self.__dynSquadFunctional

    @async
    def sendRequest(self, ctx, callback, allowDelay = None):
        """
        Sends request to the server.
        :param ctx: avatar request context object,
            @see gui.battle_control.request.context.
        :param callback: function that is invoked when response is received.
        :param allowDelay: bool.
        """
        self.__requestsCtrl.request(ctx, callback=callback, allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        self.__ammoCtrl.setGunSettings(vDesc.gun)
        self.__vehicleStateCtrl.setPlayerVehicle(vID)
        self.__feedback.setPlayerVehicle(vID)
        self.__respawnsCtrl.spawnVehicle(vID)

    def setAimOffset(self, offset):
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.setOffset(offset)
        return

    def setAimPositionUpdated(self, mode, x, y):
        if self.__feedback is not None:
            self.__feedback.setAimPositionUpdated(mode, x, y)
        return

    def getArenaDP(self):
        """
        Gets instance of arena data provider.
        :return: instance of ArenaDataProvider.
        """
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        """
        Adds arena controller. For additional information see
            gui.arena_info.IArenaController.
        :param controller: object extends IArenaController
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.addController(weakref.proxy(self.__ctx), controller)
        return

    def removeArenaCtrl(self, controller):
        """
        Removes arena controller.
        :param controller: object extends IArenaController.
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def start(self, startCtx = None):
        """
        Battle session is started.
        :param startCtx: instance of BattleSessionProviderStartCtx.
        :return:
        """
        isReplayRecording = startCtx.replayCtrl.isRecording
        isReplayPlaying = startCtx.replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider(avatar=startCtx.avatar)
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
        self.__arenaLoadCtrl = ArenaLoadController()
        self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
        self.__periodCtrl = createPeriodCtrl(isReplayPlaying, isReplayRecording)
        self.__respawnsCtrl = RespawnsController(startCtx)
        self.__repairCtrl = RepairController()
        self.__dynSquadFunctional = DynSquadFunctional(isReplayPlaying)
        self.__notificationsCtrl = NotificationsController(self.__arenaDP)
        self.__gasAttackCtrl = GasAttackController(startCtx)
        ctx = weakref.proxy(self.__ctx)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
        self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
        self.__arenaListeners.addController(ctx, self.__periodCtrl)
        self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
        self.__arenaListeners.addController(ctx, self.__dynSquadFunctional)
        self.__arenaListeners.start(startCtx.avatar.arena, arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
        self.__messagesCtrl.start(ctx)
        self.__drrScaleCtrl = DRRScaleController()
        self.__drrScaleCtrl.start(self.__messagesCtrl)
        self.__hitDirectionCtrl = HitDirectionController()
        self.__hitDirectionCtrl.start()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.__chatCommands = ChatCommandsController()
        self.__chatCommands.start(self.__arenaDP, self.__feedback)
        self.__requestsCtrl = AvatarRequestsController()
        self.__avatarStatsCtrl = AvatarStatsController()
        self.__debugCtrl = DebugController()
        self.__debugCtrl.start()
        self.__viewComponentsBridge = createComponentsBridge()
        self.__viewComponentsBridge.registerControllers((BATTLE_CTRL.PERIOD, self.__periodCtrl), (BATTLE_CTRL.TEAM_BASES, self.__arenaTeamsBasesCtrl), (BATTLE_CTRL.DEBUG, self.__debugCtrl), (BATTLE_CTRL.HIT_DIRECTION, self.__hitDirectionCtrl))

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__ammoCtrl is not None:
            self.__ammoCtrl.clear()
            self.__ammoCtrl = None
        if self.__equipmentsCtrl is not None:
            self.__equipmentsCtrl.clear()
            self.__equipmentsCtrl = None
        if self.__optDevicesCtrl is not None:
            self.__optDevicesCtrl.clear()
            self.__optDevicesCtrl = None
        if self.__vehicleStateCtrl is not None:
            self.__vehicleStateCtrl.clear()
            self.__vehicleStateCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__drrScaleCtrl is not None:
            self.__drrScaleCtrl.stop()
            self.__drrScaleCtrl = None
        if self.__feedback is not None:
            self.__feedback.stop()
            self.__feedback = None
        if self.__messagesCtrl is not None:
            self.__messagesCtrl.stop()
            self.__messagesCtrl = None
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.stop()
            self.__hitDirectionCtrl = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        if self.__chatCommands is not None:
            self.__chatCommands.stop()
            self.__chatCommands = None
        if self.__debugCtrl is not None:
            self.__debugCtrl.stop()
            self.__debugCtrl = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__gasAttackCtrl = None
        self.__dynSquadFunctional = None
        if self.__avatarStatsCtrl is not None:
            self.__avatarStatsCtrl.stop()
            self.__avatarStatsCtrl = None
        self.__ctx.stop()
        return

    def registerViewComponents(self, *data):
        """
        Sets view component data to find that components in routines
            addViewComponent, removeViewComponent.
        :param data: tuple((BATTLE_CTRL.*, (componentID, ...)), ...)
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self, componentID, component, rule = VIEW_COMPONENT_RULE.PROXY):
        """
        View component has been created.
        :param componentID: string containing unique component ID.
        :param component: instance of component.
        :param rule: one of VIEW_COMPONENT_RULE.*.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID, component, rule=rule)
        return

    def removeViewComponent(self, componentID):
        """
        View component has been removed.
        :param componentID: string containing unique component ID.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def switchToPostmortem(self):
        """
        Player's vehicle is destroyed, switchers GUI to postmortem mode.
        """
        self.__ammoCtrl.clear()
        self.__equipmentsCtrl.clear()
        self.__optDevicesCtrl.clear()
        self.__gasAttackCtrl.clear()
        self.__feedback.setPlayerVehicle(0L)
        self.__vehicleStateCtrl.switchToPostmortem()

    def useLoaderIntuition(self):
        """
        Loader intuition was used.
        """
        self.__messagesCtrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        self.__ammoCtrl.useLoaderIntuition()

    def movingToRespawnBase(self):
        """
        Player's avatar is moving to the respawn.
        """
        self.__ammoCtrl.clear(False)
        self.__equipmentsCtrl.clear(False)
        self.__optDevicesCtrl.clear(False)
        self.__vehicleStateCtrl.movingToRespawn()
        self.__respawnsCtrl.movingToRespawn()

    def invalidateVehicleState(self, state, value, vehicleID = 0):
        """
        State of player's vehicle (health, fire, state of device, etc.) is
        changed, notifies GUI about it.
        :param state: one of VEHICLE_VIEW_STATE.*.
        :param value: value of state.
        :param vehicleID: vehicle ID or zero.
        """
        self.__vehicleStateCtrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            self.__ammoCtrl.clear(False)
            self.__equipmentsCtrl.clear(False)

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        self.__repairCtrl.action(repairPointIndex, action, nextActionTime)

    def updateAvatarPrivateStats(self, stats):
        self.__avatarStatsCtrl.update(stats)

    def addHitDirection(self, hitDirYaw, isDamage):
        self.__hitDirectionCtrl.addHit(hitDirYaw, isDamage)

    def startVehicleVisual(self, vProxy, isImmediate = False):
        self.__feedback.startVehicleVisual(vProxy, isImmediate)
        self.__debugCtrl.startVehicleVisual(vProxy.id)

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        self.__feedback.stopVehicleVisual(vehicleID, isPlayerVehicle)
        self.__debugCtrl.stopVehicleVisual(vehicleID)

    def handleShortcutChatCommand(self, key):
        self.__chatCommands.handleShortcutChatCommand(key)

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        """
        It's listener of event _PlayerEvents.onBattleResultsReceived.
        :param isActiveVehicle: bool.
        """
        if isActiveVehicle:
            arena = getClientArena()
            LOG_DEBUG('Try to exit from arena', arena)
            if arena:
                self.__ctx.lastArenaUniqueID = arena.arenaUniqueID
            leaveArena()
Пример #13
0
class BattleSessionProvider(IBattleSessionProvider):
    """This class is backend of GUI for one battle session."""
    __slots__ = ('__ctx', '__sharedRepo', '__dynamicRepo', '__requestsCtrl', '__arenaDP', '__arenaListeners', '__viewComponentsBridge', '__weakref__', '__arenaVisitor', '__invitations', '__isReplayPlaying', '__battleCache')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__sharedRepo = controllers.SharedControllersLocator()
        self.__dynamicRepo = controllers.DynamicControllersLocator()
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__arenaListeners = None
        self.__viewComponentsBridge = None
        self.__invitations = None
        self.__isReplayPlaying = False
        self.__battleCache = BattleClientCache()
        return

    @property
    def shared(self):
        """ Returns reference to repository of shared controllers
        that are created for all game sessions.
        :return: instance of SharedControllersLocator.
        """
        return self.__sharedRepo

    @property
    def dynamic(self):
        """ Returns reference to repository of controllers
        that are created for some game sessions.
        :return: instance of DynamicControllersLocator.
        """
        return self.__dynamicRepo

    @property
    def arenaVisitor(self):
        """ Returns reference to visitor that has safe access to properties of arena.
        :return: instance of _ClientArenaVisitor.
        """
        return self.__arenaVisitor

    @property
    def invitations(self):
        """ Returns reference to invitations handler.
        :return: instance of _SquadInvitationsHandler.
        """
        return self.__invitations

    @property
    def battleCache(self):
        """
        Returns reference to the battle cache that is stored on the server.
        Note that the cache is created once per each battle and can be used to restore data
        after re-login.
        :return: instance of derived class BattleClientCache
        """
        return self.__battleCache

    @property
    def isReplayPlaying(self):
        """
        Returns flag is this battle actually replay.
        :return: boolean flag
        """
        return self.__isReplayPlaying

    def getCtx(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ctx

    @async
    def sendRequest(self, ctx, callback, allowDelay = None):
        """
        Sends request to the server.
        :param ctx: avatar request context object,
            @see gui.battle_control.request.context.
        :param callback: function that is invoked when response is received.
        :param allowDelay: bool.
        """
        self.__requestsCtrl.request(ctx, callback=callback, allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.setGunSettings(vDesc.gun)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.spawnVehicle(vID)
        mapKind = self.__arenaVisitor.type.getVehicleCamouflageKind()
        g_tankActiveCamouflage[vDesc.type.compactDescr] = SeasonType.fromArenaKind(mapKind)
        return

    def switchVehicle(self, vehicleID):
        repo = self.shared
        for ctrl in (repo.ammo, repo.equipments, repo.optionalDevices):
            if ctrl is not None:
                ctrl.clear(False)

        repo.vehicleState.switchToOther(vehicleID)
        return

    def updateObservedVehicleData(self, vID, extraData):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
            ctrl.setGunSettings(extraData.gunSettings)
            for intCD, quantity, quantityInClip in extraData.orderedAmmo:
                ctrl.setShells(intCD, quantity, quantityInClip)

            ctrl.setCurrentShellCD(extraData.currentShellCD)
            ctrl.setNextShellCD(extraData.nextShellCD)
            ctrl.setGunReloadTime(extraData.reloadTimeLeft, extraData.reloadBaseTime)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
            for intCD, quantity, stage, timeRemaining in extraData.orderedEquipment:
                ctrl.setEquipment(intCD, quantity, stage, timeRemaining)

        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
            for deviceID, isOn in extraData.orderedOptionalDevices:
                ctrl.setOptionalDevice(deviceID, isOn)

        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.refreshVehicleStateValue(VEHICLE_VIEW_STATE.HEALTH)
            ctrl.notifyStateChanged(VEHICLE_VIEW_STATE.VEHICLE_CHANGED, vID)
        return

    def getArenaDP(self):
        """Gets instance of arena data provider.
        :return: instance of ArenaDataProvider.
        """
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        """Adds arena controller. For additional information see
            gui.arena_info.IArenaController.
        :param controller: object that implements IArenaController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__arenaListeners is not None:
            return self.__arenaListeners.addController(controller)
        else:
            return False

    def removeArenaCtrl(self, controller):
        """Removes arena controller.
        :param controller: object extends IArenaController.
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def registerViewComponentsCtrl(self, controller):
        """Registers controller in the bridge of view components.
        :param controller: object that implements IViewComponentsController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerController(controller)
            return True
        else:
            return False

    def registerViewComponents(self, *data):
        """Sets view component data to find that components in routines
            addViewComponent, removeViewComponent.
        :param data: tuple((BATTLE_CTRL.*, (componentID, ...)), ...)
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self, componentID, component, rule = VIEW_COMPONENT_RULE.PROXY):
        """View component has been created.
        :param componentID: string containing unique component ID.
        :param component: instance of component.
        :param rule: one of VIEW_COMPONENT_RULE.*.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID, component, rule=rule)
        return

    def removeViewComponent(self, componentID):
        """View component has been removed.
        :param componentID: string containing unique component ID.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def getExitResult(self):
        """ Gets result if player exits battle that are helped to notify player about penalty (if they have).
        :return: instance of BattleExitResult(isDeserter, player).
        """
        if not self.__isReplayPlaying and not self.__arenaVisitor.gui.isTrainingBattle() and not self.__arenaVisitor.gui.isEventBattle():
            vInfo = self.__arenaDP.getVehicleInfo()
            vStats = self.__arenaDP.getVehicleStats()
            if self.__arenaVisitor.hasRespawns():
                isDeserter = not vStats.stopRespawn
            else:
                isDeserter = avatar_getter.isVehicleAlive() and not avatar_getter.isVehicleOverturned()
            return BattleExitResult(isDeserter, vInfo.player)
        else:
            return BattleExitResult(False, None)
            return None

    @staticmethod
    def exit():
        """Exits from current battle session."""
        avatar_getter.leaveArena()

    def start(self, setup):
        """
        Battle session is started.
        :param setup: instance of BattleSessionSetup.
        :return:
        """
        raise isinstance(setup, controllers.BattleSessionSetup) or AssertionError
        self.__isReplayPlaying = setup.isReplayPlaying
        self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
        setup.sessionProvider = weakref.proxy(self)
        self.__arenaDP = ArenaDataProvider(setup)
        self.__ctx.start(self.__arenaDP)
        self.__battleCache.load()
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.start(setup)
        self.__viewComponentsBridge = createComponentsBridge()
        setup.sessionProvider = weakref.proxy(self)
        self.__sharedRepo = controllers.createShared(setup)
        self.__dynamicRepo = controllers.createDynamic(setup)
        self.__requestsCtrl = AvatarRequestsController()
        self.__invitations = invitations.createInvitationsHandler(setup)
        setup.clear()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__invitations is not None:
            self.__invitations.clear()
            self.__invitations = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__sharedRepo.destroy()
        self.__dynamicRepo.destroy()
        self.__arenaVisitor.clear()
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__battleCache.clear()
        self.__ctx.stop()
        return

    def switchToPostmortem(self, noRespawnPossible = True, respawnAvailable = False):
        """Player's vehicle is destroyed, switchers GUI to postmortem mode.
        :param noRespawnPossible: whether the player can respawn or not during the game.
        :param respawnAvailable: if the player can respawn directly after being dead (move to respawn ctrl mode)
        """
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(noRespawnPossible)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.switchToPostmortem(noRespawnPossible, respawnAvailable)
        return

    def useLoaderIntuition(self):
        """Loader intuition was used."""
        ctrl = self.__sharedRepo.messages
        if ctrl is not None:
            ctrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.useLoaderIntuition()
        return

    def movingToRespawnBase(self):
        """Player's avatar is moving to the respawn."""
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.movingToRespawn()
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.movingToRespawn()
        return

    def invalidateVehicleState(self, state, value, vehicleID = 0):
        """State of player's vehicle (health, fire, state of device, etc.) is
        changed, notifies GUI about it.
        :param state: one of VEHICLE_VIEW_STATE.*.
        :param value: value of state.
        :param vehicleID: vehicle ID or zero.
        """
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            ctrl = self.__sharedRepo.ammo
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.equipments
            if ctrl is not None:
                ctrl.clear(leave=False)
        return

    def setVehicleHealth(self, isPlayerVehicle, vehicleID, newHealth, attackerID, attackReasonID):
        """New vehicle health value is changed, notifies GUI about it.
        :param isPlayerVehicle: (bool) determine is player vehicle
        :param vehicleID: (int) vehicle id
        :param newHealth: (int) vehicle health
        :param attackerID: (int) vehicle which dealt damage
        :param attackReasonID: (str) ATTACK_REASON.*
        """
        if not isPlayerVehicle:
            ctrl = self.__sharedRepo.feedback
            if ctrl is not None:
                ctrl.setVehicleNewHealth(vehicleID, newHealth, attackerID, attackReasonID)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleHealth(vehicleID, newHealth)
        return

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        ctrl = self.__dynamicRepo.repair
        if ctrl is not None:
            ctrl.action(repairPointIndex, action, nextActionTime)
        return

    def updateAvatarPrivateStats(self, stats):
        ctrl = self.__sharedRepo.privateStats
        if ctrl is not None:
            ctrl.update(stats)
        return

    def addHitDirection(self, hitDirYaw, attackerID, damage, isBlocked, critFlags, isHighExplosive, damagedID):
        hitDirectionCtrl = self.__sharedRepo.hitDirection
        if hitDirectionCtrl is not None:
            atackerVehInfo = self.__arenaDP.getVehicleInfo(attackerID)
            atackerVehType = atackerVehInfo.vehicleType
            isAlly = self.__arenaDP.isAllyTeam(atackerVehInfo.team)
            playerVehType = self.__arenaDP.getVehicleInfo(damagedID).vehicleType
            hitDirectionCtrl.addHit(HitData(yaw=hitDirYaw, attackerID=attackerID, isAlly=isAlly, damage=damage, attackerVehName=atackerVehType.shortNameWithPrefix, isBlocked=isBlocked, attackerVehClassTag=atackerVehType.classTag, critFlags=critFlags, playerVehMaxHP=playerVehType.maxHealth, isHighExplosive=isHighExplosive))
        return

    def startVehicleVisual(self, vProxy, isImmediate = False):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleVisible(vProxy.id, vProxy.health)
        return

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID, isPlayerVehicle)
        return

    def handleShortcutChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is not None:
            ctrl.handleShortcutChatCommand(key)
        return

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        """It's listener of event _PlayerEvents.onBattleResultsReceived.
        :param isActiveVehicle: bool.
        """
        if isActiveVehicle and not BattleReplay.g_replayCtrl.isPlaying:
            arenaUniqueID = self.__arenaVisitor.getArenaUniqueID()
            LOG_DEBUG('Try to exit from arena', arenaUniqueID)
            if arenaUniqueID:
                self.__ctx.lastArenaUniqueID = arenaUniqueID
            BattleSessionProvider.exit()
Пример #14
0
class BattleSessionProvider(object):
    __slots__ = ('__ammoCtrl', '__equipmentsCtrl', '__optDevicesCtrl',
                 '__vehicleStateCtrl', '__chatCommands', '__drrScaleCtrl',
                 '__feedback', '__ctx', '__arenaDP', '__arenaListeners',
                 '__arenaLoadCtrl', '__respawnsCtrl', '__notificationsCtrl',
                 '__isBattleUILoaded', '__arenaTeamsBasesCtrl', '__periodCtrl',
                 '__messagesCtrl', '__repairCtrl', '__hitDirectionCtrl',
                 '__requestsCtrl', '__avatarStatsCtrl', '__dynSquadFunctional',
                 '__weakref__')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__ammoCtrl = None
        self.__equipmentsCtrl = None
        self.__optDevicesCtrl = None
        self.__vehicleStateCtrl = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__feedback = None
        self.__messagesCtrl = None
        self.__hitDirectionCtrl = None
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__dynSquadFunctional = None
        self.__avatarStatsCtrl = None
        self.__arenaListeners = None
        self.__isBattleUILoaded = False

    def isBattleUILoaded(self):
        return self.__isBattleUILoaded

    def getCtx(self):
        return self.__ctx

    def getAmmoCtrl(self):
        return self.__ammoCtrl

    def getEquipmentsCtrl(self):
        return self.__equipmentsCtrl

    def getOptDevicesCtrl(self):
        return self.__optDevicesCtrl

    def getVehicleStateCtrl(self):
        return self.__vehicleStateCtrl

    def getChatCommands(self):
        return self.__chatCommands

    def getDrrScaleCtrl(self):
        return self.__drrScaleCtrl

    def getRespawnsCtrl(self):
        return self.__respawnsCtrl

    def getNotificationsCtrl(self):
        return self.__notificationsCtrl

    def getRepairCtrl(self):
        return self.__repairCtrl

    def getFeedback(self):
        return self.__feedback

    def getBattleMessagesCtrl(self):
        return self.__messagesCtrl

    def getHitDirectionCtrl(self):
        return self.__hitDirectionCtrl

    def getAvatarStatsCtrl(self):
        return self.__avatarStatsCtrl

    def getArenaTeamsBasesCtrl(self):
        return self.__arenaTeamsBasesCtrl

    def getPeriodCtrl(self):
        return self.__periodCtrl

    @async
    def sendRequest(self, ctx, callback, allowDelay=None):
        self.__requestsCtrl.request(ctx,
                                    callback=callback,
                                    allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        self.__ammoCtrl.setGunSettings(vDesc.gun)
        self.__vehicleStateCtrl.setPlayerVehicle(vID)
        self.__feedback.setPlayerVehicle(vID)
        self.__respawnsCtrl.spawnVehicle(vID)

    def setAimOffset(self, offset):
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.setOffset(offset)

    def setAimPositionUpdated(self, mode, x, y):
        if self.__feedback is not None:
            self.__feedback.setAimPositionUpdated(mode, x, y)

    def getArenaDP(self):
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.addController(weakref.proxy(self.__ctx),
                                                controller)

    def removeArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.removeController(controller)

    def start(self, avatar=None):
        import BattleReplay
        replayCtrl = BattleReplay.g_replayCtrl
        isReplayRecording = replayCtrl.isRecording
        isReplayPlaying = replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider(avatar=avatar)
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying,
                                                     isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(
            isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(
            isReplayRecording)
        isMultiTeam = self.__arenaDP.isMultipleTeams()
        self.__arenaLoadCtrl = ArenaLoadController(isMultiTeam)
        self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
        self.__periodCtrl = createPeriodCtrl(isReplayPlaying,
                                             isReplayRecording)
        self.__drrScaleCtrl = DRRScaleController()
        self.__respawnsCtrl = RespawnsController()
        self.__repairCtrl = RepairController()
        self.__dynSquadFunctional = DynSquadFunctional()
        self.__notificationsCtrl = NotificationsController(self.__arenaDP)
        ctx = weakref.proxy(self.__ctx)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
        self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
        self.__arenaListeners.addController(ctx, self.__periodCtrl)
        self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
        self.__arenaListeners.start(getClientArena(avatar=avatar),
                                    arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
        self.__messagesCtrl.start(ctx)
        self.__hitDirectionCtrl = HitDirectionController()
        self.__hitDirectionCtrl.start()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.__chatCommands = ChatCommandsController()
        self.__chatCommands.start(self.__arenaDP, self.__feedback)
        self.__requestsCtrl = AvatarRequestsController()
        self.__avatarStatsCtrl = AvatarStatsController()

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__requestsCtrl:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__ammoCtrl:
            self.__ammoCtrl.clear()
            self.__ammoCtrl = None
        if self.__equipmentsCtrl:
            self.__equipmentsCtrl.clear()
            self.__equipmentsCtrl = None
        if self.__optDevicesCtrl:
            self.__optDevicesCtrl.clear()
            self.__optDevicesCtrl = None
        if self.__vehicleStateCtrl:
            self.__vehicleStateCtrl.clear()
            self.__vehicleStateCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__feedback is not None:
            self.__feedback.stop()
            self.__feedback = None
        if self.__messagesCtrl is not None:
            self.__messagesCtrl.stop()
            self.__messagesCtrl = None
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.stop()
            self.__hitDirectionCtrl = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        if self.__chatCommands is not None:
            self.__chatCommands.stop()
            self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__dynSquadFunctional = None
        if self.__avatarStatsCtrl is not None:
            self.__avatarStatsCtrl.stop()
            self.__avatarStatsCtrl = None
        self.__ctx.stop()

    def setBattleUI(self, battleUI):
        assert not self.__isBattleUILoaded, 'Battle UI already is set'
        self.__isBattleUILoaded = True
        self.__arenaTeamsBasesCtrl.setUI(battleUI.teamBasesPanel)
        self.__periodCtrl.setUI(battleUI.timersBar, battleUI.ppSwitcher)
        self.__hitDirectionCtrl.setUI(battleUI.indicators)
        self.__drrScaleCtrl.start(battleUI)
        self.__repairCtrl.start(battleUI)
        self.__dynSquadFunctional.setUI(battleUI, self)

    def clearBattleUI(self):
        self.__isBattleUILoaded = False
        self.__arenaTeamsBasesCtrl.clearUI()
        self.__periodCtrl.clearUI()
        self.__hitDirectionCtrl.clearUI()
        self.__drrScaleCtrl.stop()
        self.__repairCtrl.stop()
        self.__dynSquadFunctional.clearUI(self)

    def switchToPostmortem(self):
        self.__ammoCtrl.clear()
        self.__equipmentsCtrl.clear()
        self.__optDevicesCtrl.clear()
        self.__feedback.setPlayerVehicle(0L)
        self.__vehicleStateCtrl.switchToPostmortem()

    def useLoaderIntuition(self):
        self.__messagesCtrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        self.__ammoCtrl.useLoaderIntuition()

    def movingToRespawnBase(self):
        self.__ammoCtrl.clear(False)
        self.__equipmentsCtrl.clear(False)
        self.__optDevicesCtrl.clear(False)
        self.__vehicleStateCtrl.movingToRespawn()
        self.__respawnsCtrl.movingToRespawn()

    def invalidateVehicleState(self, state, value):
        self.__vehicleStateCtrl.invalidate(state, value)

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        self.__repairCtrl.action(repairPointIndex, action, nextActionTime)

    def updateAvatarPrivateStats(self, stats):
        self.__avatarStatsCtrl.update(stats)

    def addHitDirection(self, hitDirYaw, isDamage):
        self.__hitDirectionCtrl.addHit(hitDirYaw, isDamage)

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        if isActiveVehicle:
            arena = getClientArena()
            LOG_DEBUG('Try to exit from arena', arena)
            if arena:
                self.__ctx.lastArenaUniqueID = arena.arenaUniqueID
            leaveArena()
Пример #15
0
class BattleSessionProvider(object):
    __slots__ = ('__ammoCtrl', '__equipmentsCtrl', '__optDevicesCtrl', '__vehicleStateCtrl', '__chatCommands', '__drrScaleCtrl', '__feedback', '__ctx', '__arenaDP', '__arenaListeners', '__arenaLoadCtrl', '__respawnsCtrl', '__notificationsCtrl', '__repairCtrl', '__isBattleUILoaded', '__requestsCtrl')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__ammoCtrl = None
        self.__equipmentsCtrl = None
        self.__optDevicesCtrl = None
        self.__vehicleStateCtrl = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__feedback = None
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaLoadCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__arenaListeners = None
        self.__isBattleUILoaded = False
        return

    def isBattleUILoaded(self):
        return self.__isBattleUILoaded

    def getCtx(self):
        return self.__ctx

    def getAmmoCtrl(self):
        return self.__ammoCtrl

    def getEquipmentsCtrl(self):
        return self.__equipmentsCtrl

    def getOptDevicesCtrl(self):
        return self.__optDevicesCtrl

    def getVehicleStateCtrl(self):
        return self.__vehicleStateCtrl

    def getChatCommands(self):
        return self.__chatCommands

    def getDrrScaleCtrl(self):
        return self.__drrScaleCtrl

    def getRespawnsCtrl(self):
        return self.__respawnsCtrl

    def getNotificationsCtrl(self):
        return self.__notificationsCtrl

    def getRepairCtrl(self):
        return self.__repairCtrl

    def getFeedback(self):
        return self.__feedback

    @async
    def sendRequest(self, ctx, callback, allowDelay = None):
        self.__requestsCtrl.request(ctx, callback=callback, allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        self.__ammoCtrl.setGunSettings(vDesc.gun)
        self.__vehicleStateCtrl.setPlayerVehicle(vID)
        self.__feedback.setPlayerVehicle(vID)

    def setAimPositionUpdated(self, mode, x, y):
        self.__feedback.setAimPositionUpdated(mode, x, y)

    def getArenaDP(self):
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.addController(weakref.proxy(self.__ctx), controller)

    def removeArenaCtrl(self, controller):
        if self.__arenaListeners:
            self.__arenaListeners.removeController(controller)

    def start(self):
        import BattleReplay
        replayCtrl = BattleReplay.g_replayCtrl
        if isEventBattle():
            replayCtrl.enableAutoRecordingBattles(0)
        isReplayRecording = replayCtrl.isRecording
        isReplayPlaying = replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider()
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying, isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(isReplayRecording)
        self.__chatCommands = ChatCommandsController()
        self.__arenaLoadCtrl = ArenaLoadController()
        self.__drrScaleCtrl = DRRScaleController()
        self.__respawnsCtrl = RespawnsController()
        self.__notificationsCtrl = NotificationsController()
        self.__repairCtrl = RepairController()
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(weakref.proxy(self.__ctx), self.__arenaLoadCtrl)
        self.__arenaListeners.addController(weakref.proxy(self.__ctx), self.__respawnsCtrl)
        self.__arenaListeners.start(arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__requestsCtrl = AvatarRequestsController()

    def stop(self):
        if self.__requestsCtrl:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__ammoCtrl:
            self.__ammoCtrl.clear()
            self.__ammoCtrl = None
        if self.__equipmentsCtrl:
            self.__equipmentsCtrl.clear()
            self.__equipmentsCtrl = None
        if self.__optDevicesCtrl:
            self.__optDevicesCtrl.clear()
            self.__optDevicesCtrl = None
        if self.__vehicleStateCtrl:
            self.__vehicleStateCtrl.clear()
            self.__vehicleStateCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__feedback is not None:
            self.__feedback.stop()
            self.__feedback = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__arenaLoadCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        import BattleReplay
        replayCtrl = BattleReplay.g_replayCtrl
        if isEventBattle():
            from account_helpers.settings_core.SettingsCore import g_settingsCore
            replayCtrl.enableAutoRecordingBattles(g_settingsCore.getSetting('replayEnabled'))
        self.__ctx.stop()
        return

    def setBattleUI(self, battleUI):
        self.__isBattleUILoaded = True
        self.__chatCommands.start(battleUI, self.__arenaDP)
        self.__drrScaleCtrl.start(battleUI)
        self.__repairCtrl.start(battleUI)

    def clearBattleUI(self):
        self.__isBattleUILoaded = False
        self.__chatCommands.stop()
        self.__drrScaleCtrl.stop()
        self.__repairCtrl.stop()

    def switchToPostmortem(self):
        self.__ammoCtrl.clear()
        self.__equipmentsCtrl.clear()
        self.__optDevicesCtrl.clear()
        self.__feedback.setPlayerVehicle(0L)
        from gui.WindowsManager import g_windowsManager
        g_windowsManager.showPostMortem()
        self.__vehicleStateCtrl.switchToPostmortem()

    def movingToRespawnBase(self):
        self.__ammoCtrl.clear(False)
        self.__equipmentsCtrl.clear(False)
        self.__optDevicesCtrl.clear(False)
        self.__vehicleStateCtrl.onRespawnBaseMoving()

    def invalidateVehicleState(self, state, value):
        self.__vehicleStateCtrl.invalidate(state, value)

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        self.__repairCtrl.action(repairPointIndex, action, nextActionTime)
class BattleSessionProvider(IBattleSessionProvider):
    __slots__ = ('__ctx', '__sharedRepo', '__dynamicRepo', '__requestsCtrl',
                 '__arenaDP', '__arenaListeners', '__viewComponentsBridge',
                 '__weakref__', '__arenaVisitor', '__invitations',
                 '__isReplayPlaying', '__battleCache')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__sharedRepo = controllers.SharedControllersLocator()
        self.__dynamicRepo = controllers.DynamicControllersLocator()
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__arenaListeners = None
        self.__viewComponentsBridge = None
        self.__invitations = None
        self.__isReplayPlaying = False
        self.__battleCache = BattleClientCache()
        return

    @property
    def shared(self):
        return self.__sharedRepo

    @property
    def dynamic(self):
        return self.__dynamicRepo

    @property
    def arenaVisitor(self):
        return self.__arenaVisitor

    @property
    def invitations(self):
        return self.__invitations

    @property
    def battleCache(self):
        return self.__battleCache

    @property
    def isReplayPlaying(self):
        return self.__isReplayPlaying

    def getCtx(self):
        return self.__ctx

    @async
    def sendRequest(self, ctx, callback, allowDelay=None):
        self.__requestsCtrl.request(ctx,
                                    callback=callback,
                                    allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.setGunSettings(vDesc.gun)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.notifyPlayerVehicleSet()
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.spawnVehicle(vID)
        mapKind = self.__arenaVisitor.type.getVehicleCamouflageKind()
        g_tankActiveCamouflage[
            vDesc.type.compactDescr] = SeasonType.fromArenaKind(mapKind)
        return

    def switchVehicle(self, vehicleID):
        repo = self.shared
        for ctrl in (repo.ammo, repo.equipments, repo.optionalDevices):
            if ctrl is not None:
                ctrl.clear(False)

        repo.vehicleState.switchToOther(vehicleID)
        return

    def updateObservedVehicleData(self, vID, extraData):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
            ctrl.setGunSettings(extraData.gunSettings)
            for intCD, quantity, quantityInClip in extraData.orderedAmmo:
                ctrl.setShells(intCD, quantity, quantityInClip)

            ctrl.setCurrentShellCD(extraData.currentShellCD)
            ctrl.setNextShellCD(extraData.nextShellCD)
            ctrl.setGunReloadTime(extraData.reloadTimeLeft,
                                  extraData.reloadBaseTime)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
            for intCD, quantity, stage, timeRemaining, totalTime in extraData.orderedEquipment:
                ctrl.setEquipment(intCD, quantity, stage, timeRemaining,
                                  totalTime)

        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
            for deviceID, isOn in extraData.orderedOptionalDevices:
                ctrl.setOptionalDevice(deviceID, isOn)

        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.refreshVehicleStateValue(VEHICLE_VIEW_STATE.HEALTH)
            ctrl.notifyStateChanged(VEHICLE_VIEW_STATE.VEHICLE_CHANGED, vID)
        return

    def getArenaDP(self):
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        return self.__arenaListeners.addController(
            controller) if self.__arenaListeners is not None else False

    def removeArenaCtrl(self, controller):
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def registerViewComponentsCtrl(self, controller):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerController(controller)
            return True
        else:
            return False

    def registerViewComponents(self, *data):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self,
                         componentID,
                         component,
                         rule=VIEW_COMPONENT_RULE.PROXY):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID,
                                                         component,
                                                         rule=rule)
        return

    def removeViewComponent(self, componentID):
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def getExitResult(self):
        if not self.__isReplayPlaying and not self.__arenaVisitor.gui.isTrainingBattle(
        ) and not self.__arenaVisitor.gui.isEventBattle():
            vInfo = self.__arenaDP.getVehicleInfo()
            vStats = self.__arenaDP.getVehicleStats()
            if self.__arenaVisitor.hasRespawns():
                isDeserter = not vStats.stopRespawn
            else:
                isDeserter = avatar_getter.isVehicleAlive(
                ) and not avatar_getter.isVehicleOverturned()
            return BattleExitResult(isDeserter, vInfo.player)
        else:
            return BattleExitResult(False, None)
            return None

    @staticmethod
    def exit():
        avatar_getter.leaveArena()

    def start(self, setup):
        self.__isReplayPlaying = setup.isReplayPlaying
        self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
        setup.sessionProvider = weakref.proxy(self)
        self.__arenaDP = ArenaDataProvider(setup)
        self.__ctx.start(self.__arenaDP)
        self.__battleCache.load()
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.start(setup)
        self.__viewComponentsBridge = createComponentsBridge()
        setup.sessionProvider = weakref.proxy(self)
        self.__sharedRepo = controllers.createShared(setup)
        self.__dynamicRepo = controllers.createDynamic(setup)
        self.__requestsCtrl = AvatarRequestsController()
        self.__invitations = invitations.createInvitationsHandler(setup)
        setup.clear()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__invitations is not None:
            self.__invitations.clear()
            self.__invitations = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__sharedRepo.destroy()
        self.__dynamicRepo.destroy()
        self.__arenaVisitor.clear()
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__battleCache.clear()
        self.__ctx.stop()
        return

    def switchToPostmortem(self,
                           noRespawnPossible=True,
                           respawnAvailable=False):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.switchToPostmortem(noRespawnPossible, respawnAvailable)
        return

    def useLoaderIntuition(self):
        ctrl = self.__sharedRepo.messages
        if ctrl is not None:
            ctrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.useLoaderIntuition()
        return

    def movingToRespawnBase(self):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.movingToRespawn()
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.movingToRespawn()
        return

    def invalidateVehicleState(self, state, value, vehicleID=0):
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            ctrl = self.__sharedRepo.ammo
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.equipments
            if ctrl is not None:
                ctrl.clear(leave=False)
        return

    def setVehicleHealth(self, isPlayerVehicle, vehicleID, newHealth,
                         attackerID, attackReasonID):
        if not isPlayerVehicle:
            ctrl = self.__sharedRepo.feedback
            if ctrl is not None:
                ctrl.setVehicleNewHealth(vehicleID, newHealth, attackerID,
                                         attackReasonID)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleHealth(vehicleID, newHealth)
        return

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        ctrl = self.__dynamicRepo.repair
        if ctrl is not None:
            ctrl.action(repairPointIndex, action, nextActionTime)
        return

    def updateAvatarPrivateStats(self, stats):
        ctrl = self.__sharedRepo.privateStats
        if ctrl is not None:
            ctrl.update(stats)
        return

    def addHitDirection(self, hitDirYaw, attackerID, damage, isBlocked,
                        critFlags, isHighExplosive, damagedID, attackReasonID):
        hitDirectionCtrl = self.__sharedRepo.hitDirection
        if hitDirectionCtrl is not None:
            atackerVehInfo = self.__arenaDP.getVehicleInfo(attackerID)
            atackerVehType = atackerVehInfo.vehicleType
            isAlly = self.__arenaDP.isAllyTeam(atackerVehInfo.team)
            playerVehType = self.__arenaDP.getVehicleInfo(
                damagedID).vehicleType
            hitData = HitData(
                yaw=hitDirYaw,
                attackerID=attackerID,
                isAlly=isAlly,
                damage=damage,
                attackerVehName=atackerVehType.shortNameWithPrefix,
                isBlocked=isBlocked,
                attackerVehClassTag=atackerVehType.classTag,
                critFlags=critFlags,
                playerVehMaxHP=playerVehType.maxHealth,
                isHighExplosive=isHighExplosive,
                attackReasonID=attackReasonID)
            if not hitData.isNonPlayerAttackReason(
            ) and not hitData.isBattleAbilityConsumable():
                hitDirectionCtrl.addHit(hitData)
        return

    def startVehicleVisual(self, vProxy, isImmediate=False):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__dynamicRepo.battleField
        if ctrl is not None:
            ctrl.setVehicleVisible(vProxy.id, vProxy.health)
        return

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID, isPlayerVehicle)
        return

    def handleShortcutChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is None:
            return
        else:
            if self.__arenaVisitor.gui.isInEpicRange():
                mapCtrl = self.dynamic.maps
                if not mapCtrl or mapCtrl.overviewMapScreenVisible:
                    return
            ctrl.handleShortcutChatCommand(key)
            return

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        if isActiveVehicle and not BattleReplay.g_replayCtrl.isPlaying:
            arenaUniqueID = self.__arenaVisitor.getArenaUniqueID()
            LOG_DEBUG('Try to exit from arena', arenaUniqueID)
            if arenaUniqueID:
                self.__ctx.lastArenaUniqueID = arenaUniqueID
            BattleSessionProvider.exit()
class BattleSessionProvider(object):
    __slots__ = ('__ammoCtrl', '__equipmentsCtrl', '__optDevicesCtrl',
                 '__vehicleStateCtrl', '__chatCommands', '__drrScaleCtrl',
                 '__feedback', '__ctx', '__arenaDP', '__arenaListeners',
                 '__arenaLoadCtrl', '__respawnsCtrl', '__notificationsCtrl',
                 '__arenaTeamsBasesCtrl', '__periodCtrl', '__messagesCtrl',
                 '__repairCtrl', '__hitDirectionCtrl', '__requestsCtrl',
                 '__avatarStatsCtrl', '__dynSquadFunctional', '__weakref__',
                 '__gasAttackCtrl', '__debugCtrl', '__viewComponentsBridge')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__ammoCtrl = None
        self.__equipmentsCtrl = None
        self.__optDevicesCtrl = None
        self.__vehicleStateCtrl = None
        self.__chatCommands = None
        self.__drrScaleCtrl = None
        self.__feedback = None
        self.__messagesCtrl = None
        self.__hitDirectionCtrl = None
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__dynSquadFunctional = None
        self.__avatarStatsCtrl = None
        self.__arenaListeners = None
        self.__gasAttackCtrl = None
        self.__debugCtrl = None
        self.__viewComponentsBridge = None
        return

    def getCtx(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ctx

    def getAmmoCtrl(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ammoCtrl

    def getEquipmentsCtrl(self):
        """
        Gets instance of equipments controller.
        :return: instance of EquipmentsController.
        """
        return self.__equipmentsCtrl

    def getOptDevicesCtrl(self):
        """
        Gets instance of optional devices controller.
        :return: instance of OptionalDevicesController.
        """
        return self.__optDevicesCtrl

    def getVehicleStateCtrl(self):
        """
        Gets instance of vehicle state controller.
        :return: instance of VehicleStateController.
        """
        return self.__vehicleStateCtrl

    def getChatCommands(self):
        """
        Gets instance of chat commands controller.
        :return: instance of ChatCommandsController.
        """
        return self.__chatCommands

    def getDrrScaleCtrl(self):
        """
        Gets instance of DRR scale controller.
        :return: instance of DRRScaleController.
        """
        return self.__drrScaleCtrl

    def getRespawnsCtrl(self):
        """
        Gets instance of respawns controller.
        :return: instance of RespawnsController.
        """
        return self.__respawnsCtrl

    def getNotificationsCtrl(self):
        """
        Gets instance of notification controller.
        :return: instance of NotificationController.
        """
        return self.__notificationsCtrl

    def getRepairCtrl(self):
        """
        Gets instance of repair controller.
        :return: instance of RepairController.
        """
        return self.__repairCtrl

    def getFeedback(self):
        """
        Gets instance of feedback adaptor to notify GUI about some events that
        needs to show response on player(s) actions.
        :return: instance of BattleFeedbackAdaptor.
        """
        return self.__feedback

    def getBattleMessagesCtrl(self):
        """
        Gets instance of messages controller to show messages in a battle.
        :return: instance of BattleMessagesController.
        """
        return self.__messagesCtrl

    def getHitDirectionCtrl(self):
        """
        Gets instance of hit direction controller to show damage indicator.
        :return: instance of HitDirectionController.
        """
        return self.__hitDirectionCtrl

    def getAvatarStatsCtrl(self):
        """
        Gets instance of avatar stats controller to track stats changes.
        :return: instance of AvatarStatsController.
        """
        return self.__avatarStatsCtrl

    def getArenaTeamsBasesCtrl(self):
        """
        Gets instance of arena team bases controller to track bases changes.
        :return: instance of BattleTeamsBasesController.
        """
        return self.__arenaTeamsBasesCtrl

    def getPeriodCtrl(self):
        """
        Gets instance of period controller to track time changes.
        :return: instance of ArenaPeriodController.
        """
        return self.__periodCtrl

    def getGasAttackCtrl(self):
        """
        Gets instance of gas attack controller.
        :return: instance of GasAttackController.
        """
        return self.__gasAttackCtrl

    def getDynSquadFunctional(self):
        """
        Gets instance of dynamic squad functional.
        :return: instance of DynSquadFunctional.
        """
        return self.__dynSquadFunctional

    @async
    def sendRequest(self, ctx, callback, allowDelay=None):
        """
        Sends request to the server.
        :param ctx: avatar request context object,
            @see gui.battle_control.request.context.
        :param callback: function that is invoked when response is received.
        :param allowDelay: bool.
        """
        self.__requestsCtrl.request(ctx,
                                    callback=callback,
                                    allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        self.__ammoCtrl.setGunSettings(vDesc.gun)
        self.__vehicleStateCtrl.setPlayerVehicle(vID)
        self.__feedback.setPlayerVehicle(vID)
        self.__respawnsCtrl.spawnVehicle(vID)

    def setAimOffset(self, offset):
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.setOffset(offset)
        return

    def setAimPositionUpdated(self, mode, x, y):
        if self.__feedback is not None:
            self.__feedback.setAimPositionUpdated(mode, x, y)
        return

    def getArenaDP(self):
        """
        Gets instance of arena data provider.
        :return: instance of ArenaDataProvider.
        """
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        """
        Adds arena controller. For additional information see
            gui.arena_info.IArenaController.
        :param controller: object extends IArenaController
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.addController(weakref.proxy(self.__ctx),
                                                controller)
        return

    def removeArenaCtrl(self, controller):
        """
        Removes arena controller.
        :param controller: object extends IArenaController.
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def start(self, startCtx=None):
        """
        Battle session is started.
        :param startCtx: instance of BattleSessionProviderStartCtx.
        :return:
        """
        isReplayRecording = startCtx.replayCtrl.isRecording
        isReplayPlaying = startCtx.replayCtrl.isPlaying
        self.__arenaDP = ArenaDataProvider(avatar=startCtx.avatar)
        self.__ctx.start(self.__arenaDP)
        self.__ammoCtrl = consumables.createAmmoCtrl(isReplayPlaying,
                                                     isReplayRecording)
        self.__equipmentsCtrl = consumables.createEquipmentCtrl(
            isReplayPlaying)
        self.__optDevicesCtrl = consumables.createOptDevicesCtrl()
        self.__vehicleStateCtrl = vehicle_state_ctrl.createCtrl(
            isReplayRecording)
        self.__arenaLoadCtrl = ArenaLoadController()
        self.__arenaTeamsBasesCtrl = createTeamsBasesCtrl(isReplayPlaying)
        self.__periodCtrl = createPeriodCtrl(isReplayPlaying,
                                             isReplayRecording)
        self.__respawnsCtrl = RespawnsController(startCtx)
        self.__repairCtrl = RepairController()
        self.__dynSquadFunctional = DynSquadFunctional(isReplayPlaying)
        self.__notificationsCtrl = NotificationsController(self.__arenaDP)
        self.__gasAttackCtrl = GasAttackController(startCtx)
        ctx = weakref.proxy(self.__ctx)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.addController(ctx, self.__arenaLoadCtrl)
        self.__arenaListeners.addController(ctx, self.__arenaTeamsBasesCtrl)
        self.__arenaListeners.addController(ctx, self.__periodCtrl)
        self.__arenaListeners.addController(ctx, self.__respawnsCtrl)
        self.__arenaListeners.addController(ctx, self.__dynSquadFunctional)
        self.__arenaListeners.start(startCtx.avatar.arena,
                                    arenaDP=self.__arenaDP)
        self.__feedback = createFeedbackAdaptor(isReplayPlaying)
        self.__feedback.start(self.__arenaDP)
        self.__messagesCtrl = createBattleMessagesCtrl(isReplayPlaying)
        self.__messagesCtrl.start(ctx)
        self.__drrScaleCtrl = DRRScaleController()
        self.__drrScaleCtrl.start(self.__messagesCtrl)
        self.__hitDirectionCtrl = HitDirectionController()
        self.__hitDirectionCtrl.start()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived
        self.__chatCommands = ChatCommandsController()
        self.__chatCommands.start(self.__arenaDP, self.__feedback)
        self.__requestsCtrl = AvatarRequestsController()
        self.__avatarStatsCtrl = AvatarStatsController()
        self.__debugCtrl = DebugController()
        self.__debugCtrl.start()
        self.__viewComponentsBridge = createComponentsBridge()
        self.__viewComponentsBridge.registerControllers(
            (BATTLE_CTRL.PERIOD, self.__periodCtrl),
            (BATTLE_CTRL.TEAM_BASES, self.__arenaTeamsBasesCtrl),
            (BATTLE_CTRL.DEBUG, self.__debugCtrl),
            (BATTLE_CTRL.HIT_DIRECTION, self.__hitDirectionCtrl))

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__ammoCtrl is not None:
            self.__ammoCtrl.clear()
            self.__ammoCtrl = None
        if self.__equipmentsCtrl is not None:
            self.__equipmentsCtrl.clear()
            self.__equipmentsCtrl = None
        if self.__optDevicesCtrl is not None:
            self.__optDevicesCtrl.clear()
            self.__optDevicesCtrl = None
        if self.__vehicleStateCtrl is not None:
            self.__vehicleStateCtrl.clear()
            self.__vehicleStateCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__drrScaleCtrl is not None:
            self.__drrScaleCtrl.stop()
            self.__drrScaleCtrl = None
        if self.__feedback is not None:
            self.__feedback.stop()
            self.__feedback = None
        if self.__messagesCtrl is not None:
            self.__messagesCtrl.stop()
            self.__messagesCtrl = None
        if self.__hitDirectionCtrl is not None:
            self.__hitDirectionCtrl.stop()
            self.__hitDirectionCtrl = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        if self.__chatCommands is not None:
            self.__chatCommands.stop()
            self.__chatCommands = None
        if self.__debugCtrl is not None:
            self.__debugCtrl.stop()
            self.__debugCtrl = None
        self.__arenaLoadCtrl = None
        self.__arenaTeamsBasesCtrl = None
        self.__periodCtrl = None
        self.__respawnsCtrl = None
        self.__notificationsCtrl = None
        self.__repairCtrl = None
        self.__gasAttackCtrl = None
        self.__dynSquadFunctional = None
        if self.__avatarStatsCtrl is not None:
            self.__avatarStatsCtrl.stop()
            self.__avatarStatsCtrl = None
        self.__ctx.stop()
        return

    def registerViewComponents(self, *data):
        """
        Sets view component data to find that components in routines
            addViewComponent, removeViewComponent.
        :param data: tuple((BATTLE_CTRL.*, (componentID, ...)), ...)
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self,
                         componentID,
                         component,
                         rule=VIEW_COMPONENT_RULE.PROXY):
        """
        View component has been created.
        :param componentID: string containing unique component ID.
        :param component: instance of component.
        :param rule: one of VIEW_COMPONENT_RULE.*.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID,
                                                         component,
                                                         rule=rule)
        return

    def removeViewComponent(self, componentID):
        """
        View component has been removed.
        :param componentID: string containing unique component ID.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def switchToPostmortem(self):
        """
        Player's vehicle is destroyed, switchers GUI to postmortem mode.
        """
        self.__ammoCtrl.clear()
        self.__equipmentsCtrl.clear()
        self.__optDevicesCtrl.clear()
        self.__gasAttackCtrl.clear()
        self.__feedback.setPlayerVehicle(0L)
        self.__vehicleStateCtrl.switchToPostmortem()

    def useLoaderIntuition(self):
        """
        Loader intuition was used.
        """
        self.__messagesCtrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        self.__ammoCtrl.useLoaderIntuition()

    def movingToRespawnBase(self):
        """
        Player's avatar is moving to the respawn.
        """
        self.__ammoCtrl.clear(False)
        self.__equipmentsCtrl.clear(False)
        self.__optDevicesCtrl.clear(False)
        self.__vehicleStateCtrl.movingToRespawn()
        self.__respawnsCtrl.movingToRespawn()

    def invalidateVehicleState(self, state, value, vehicleID=0):
        """
        State of player's vehicle (health, fire, state of device, etc.) is
        changed, notifies GUI about it.
        :param state: one of VEHICLE_VIEW_STATE.*.
        :param value: value of state.
        :param vehicleID: vehicle ID or zero.
        """
        self.__vehicleStateCtrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            self.__ammoCtrl.clear(False)
            self.__equipmentsCtrl.clear(False)

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        self.__repairCtrl.action(repairPointIndex, action, nextActionTime)

    def updateAvatarPrivateStats(self, stats):
        self.__avatarStatsCtrl.update(stats)

    def addHitDirection(self, hitDirYaw, isDamage):
        self.__hitDirectionCtrl.addHit(hitDirYaw, isDamage)

    def startVehicleVisual(self, vProxy, isImmediate=False):
        self.__feedback.startVehicleVisual(vProxy, isImmediate)
        self.__debugCtrl.startVehicleVisual(vProxy.id)

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        self.__feedback.stopVehicleVisual(vehicleID, isPlayerVehicle)
        self.__debugCtrl.stopVehicleVisual(vehicleID)

    def handleShortcutChatCommand(self, key):
        self.__chatCommands.handleShortcutChatCommand(key)

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        """
        It's listener of event _PlayerEvents.onBattleResultsReceived.
        :param isActiveVehicle: bool.
        """
        if isActiveVehicle:
            arena = getClientArena()
            LOG_DEBUG('Try to exit from arena', arena)
            if arena:
                self.__ctx.lastArenaUniqueID = arena.arenaUniqueID
            leaveArena()
Пример #18
0
class BattleSessionProvider(object):
    """This class is backend of GUI for one battle session."""
    __slots__ = ('__ctx', '__sharedRepo', '__dynamicRepo', '__requestsCtrl',
                 '__arenaDP', '__arenaListeners', '__viewComponentsBridge',
                 '__weakref__', '__arenaVisitor', '__invitations',
                 '__isReplayPlaying')

    def __init__(self):
        super(BattleSessionProvider, self).__init__()
        self.__ctx = BattleContext()
        self.__sharedRepo = controllers.SharedControllersLocator()
        self.__dynamicRepo = controllers.DynamicControllersLocator()
        self.__requestsCtrl = None
        self.__arenaDP = None
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__arenaListeners = None
        self.__viewComponentsBridge = None
        self.__invitations = None
        self.__isReplayPlaying = False
        return

    @property
    def shared(self):
        """ Returns reference to repository of shared controllers
        that are created for all game sessions.
        :return: instance of SharedControllersLocator.
        """
        return self.__sharedRepo

    @property
    def dynamic(self):
        """ Returns reference to repository of controllers
        that are created for some game sessions.
        :return: instance of DynamicControllersLocator.
        """
        return self.__dynamicRepo

    @property
    def arenaVisitor(self):
        """ Returns reference to visitor that has safe access to properties of arena.
        :return: instance of _ClientArenaVisitor.
        """
        return self.__arenaVisitor

    @property
    def invitations(self):
        """ Returns reference to invitations handler.
        :return: instance of _SquadInvitationsHandler.
        """
        return self.__invitations

    def getCtx(self):
        """
        Gets instance of ammo controller.
        :return: instance of AmmoController.
        """
        return self.__ctx

    @async
    def sendRequest(self, ctx, callback, allowDelay=None):
        """
        Sends request to the server.
        :param ctx: avatar request context object,
            @see gui.battle_control.request.context.
        :param callback: function that is invoked when response is received.
        :param allowDelay: bool.
        """
        self.__requestsCtrl.request(ctx,
                                    callback=callback,
                                    allowDelay=allowDelay)

    def setPlayerVehicle(self, vID, vDesc):
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.setGunSettings(vDesc.gun)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.setPlayerVehicle(vID)
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.spawnVehicle(vID)
        g_tankActiveCamouflage[
            vDesc.type.
            compactDescr] = self.__arenaVisitor.type.getVehicleCamouflageKind(
            )
        return

    def getArenaDP(self):
        """Gets instance of arena data provider.
        :return: instance of ArenaDataProvider.
        """
        return self.__arenaDP

    def addArenaCtrl(self, controller):
        """Adds arena controller. For additional information see
            gui.arena_info.IArenaController.
        :param controller: object that implements IArenaController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__arenaListeners is not None:
            return self.__arenaListeners.addController(controller)
        else:
            return False
            return

    def removeArenaCtrl(self, controller):
        """Removes arena controller.
        :param controller: object extends IArenaController.
        """
        if self.__arenaListeners is not None:
            self.__arenaListeners.removeController(controller)
        return

    def registerViewComponentsCtrl(self, controller):
        """Registers controller in the bridge of view components.
        :param controller: object that implements IViewComponentsController.
        :return: True if controller is added to arena listeners, otherwise - False.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerController(controller)
            return True
        else:
            return False
            return

    def registerViewComponents(self, *data):
        """Sets view component data to find that components in routines
            addViewComponent, removeViewComponent.
        :param data: tuple((BATTLE_CTRL.*, (componentID, ...)), ...)
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.registerViewComponents(*data)
        return

    def addViewComponent(self,
                         componentID,
                         component,
                         rule=VIEW_COMPONENT_RULE.PROXY):
        """View component has been created.
        :param componentID: string containing unique component ID.
        :param component: instance of component.
        :param rule: one of VIEW_COMPONENT_RULE.*.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.addViewComponent(componentID,
                                                         component,
                                                         rule=rule)
        return

    def removeViewComponent(self, componentID):
        """View component has been removed.
        :param componentID: string containing unique component ID.
        """
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.removeViewComponent(componentID)
        return

    def getExitResult(self):
        """ Gets result if player exits battle that are helped to notify player about penalty (if they have).
        :return: instance of BattleExitResult(isDeserter, player).
        """
        if not self.__isReplayPlaying and not self.__arenaVisitor.gui.isTrainingBattle(
        ):
            vInfo = self.__arenaDP.getVehicleInfo()
            vStats = self.__arenaDP.getVehicleStats()
            if self.__arenaVisitor.gui.isEventBattle():
                isDeserter = False
            elif self.__arenaVisitor.hasRespawns():
                isDeserter = not vStats.stopRespawn
            else:
                isDeserter = avatar_getter.isVehicleAlive(
                ) and not avatar_getter.isVehicleOverturned()
            return BattleExitResult(isDeserter, vInfo.player)
        else:
            return BattleExitResult(False, None)
            return None

    @staticmethod
    def exit():
        """Exits from current battle session."""
        avatar_getter.leaveArena()

    def start(self, setup):
        """
        Battle session is started.
        :param setup: instance of BattleSessionSetup.
        :return:
        """
        raise isinstance(setup,
                         controllers.BattleSessionSetup) or AssertionError
        self.__isReplayPlaying = setup.isReplayPlaying
        self.__arenaVisitor = arena_visitor.createByAvatar(avatar=setup.avatar)
        setup.sessionProvider = weakref.proxy(self)
        self.__arenaDP = ArenaDataProvider(setup)
        self.__ctx.start(self.__arenaDP)
        self.__arenaListeners = ListenersCollection()
        self.__arenaListeners.start(setup)
        self.__viewComponentsBridge = createComponentsBridge()
        setup.sessionProvider = weakref.proxy(self)
        self.__sharedRepo = controllers.createShared(setup)
        self.__dynamicRepo = controllers.createDynamic(setup)
        self.__requestsCtrl = AvatarRequestsController()
        self.__invitations = invitations.createInvitationsHandler(setup)
        setup.clear()
        g_playerEvents.onBattleResultsReceived += self.__pe_onBattleResultsReceived

    def stop(self):
        g_playerEvents.onBattleResultsReceived -= self.__pe_onBattleResultsReceived
        if self.__viewComponentsBridge is not None:
            self.__viewComponentsBridge.clear()
            self.__viewComponentsBridge = None
        if self.__invitations is not None:
            self.__invitations.clear()
            self.__invitations = None
        if self.__requestsCtrl is not None:
            self.__requestsCtrl.fini()
            self.__requestsCtrl = None
        if self.__arenaListeners is not None:
            self.__arenaListeners.stop()
            self.__arenaListeners = None
        if self.__arenaDP is not None:
            self.__arenaDP.clear()
            self.__arenaDP = None
        self.__sharedRepo.destroy()
        self.__dynamicRepo.destroy()
        self.__arenaVisitor.clear()
        self.__arenaVisitor = arena_visitor.createSkeleton()
        self.__ctx.stop()
        return

    def switchToPostmortem(self):
        """Player's vehicle is destroyed, switchers GUI to postmortem mode."""
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear()
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.setPlayerVehicle(0L)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.switchToPostmortem()
        return

    def useLoaderIntuition(self):
        """Loader intuition was used."""
        ctrl = self.__sharedRepo.messages
        if ctrl is not None:
            ctrl.showVehicleMessage('LOADER_INTUITION_WAS_USED')
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.useLoaderIntuition()
        return

    def movingToRespawnBase(self):
        """Player's avatar is moving to the respawn."""
        ctrl = self.__sharedRepo.ammo
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.equipments
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.optionalDevices
        if ctrl is not None:
            ctrl.clear(False)
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.movingToRespawn()
        ctrl = self.__dynamicRepo.respawn
        if ctrl is not None:
            ctrl.movingToRespawn()
        return

    def invalidateVehicleState(self, state, value, vehicleID=0):
        """State of player's vehicle (health, fire, state of device, etc.) is
        changed, notifies GUI about it.
        :param state: one of VEHICLE_VIEW_STATE.*.
        :param value: value of state.
        :param vehicleID: vehicle ID or zero.
        """
        ctrl = self.__sharedRepo.vehicleState
        if ctrl is not None:
            ctrl.invalidate(state, value, vehicleID)
        if state == VEHICLE_VIEW_STATE.DESTROYED:
            ctrl = self.__sharedRepo.ammo
            if ctrl is not None:
                ctrl.clear(leave=False)
            ctrl = self.__sharedRepo.equipments
            if ctrl is not None:
                ctrl.clear(leave=False)
        return

    def repairPointAction(self, repairPointIndex, action, nextActionTime):
        ctrl = self.__dynamicRepo.repair
        if ctrl is not None:
            ctrl.action(repairPointIndex, action, nextActionTime)
        return

    def updateAvatarPrivateStats(self, stats):
        ctrl = self.__sharedRepo.privateStats
        if ctrl is not None:
            ctrl.update(stats)
        return

    def addHitDirection(self, hitDirYaw, isDamage):
        ctrl = self.__sharedRepo.hitDirection
        if ctrl is not None:
            ctrl.addHit(hitDirYaw, isDamage)
        return

    def startVehicleVisual(self, vProxy, isImmediate=False):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy, isImmediate)
        ctrl = self.__dynamicRepo.debug
        if ctrl is not None:
            ctrl.startVehicleVisual(vProxy.id)
        return

    def stopVehicleVisual(self, vehicleID, isPlayerVehicle):
        ctrl = self.__sharedRepo.feedback
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID, isPlayerVehicle)
        ctrl = self.__dynamicRepo.debug
        if ctrl is not None:
            ctrl.stopVehicleVisual(vehicleID)
        return

    def handleShortcutChatCommand(self, key):
        ctrl = self.__sharedRepo.chatCommands
        if ctrl is not None:
            ctrl.handleShortcutChatCommand(key)
        return

    def __pe_onBattleResultsReceived(self, isActiveVehicle, _):
        """It's listener of event _PlayerEvents.onBattleResultsReceived.
        :param isActiveVehicle: bool.
        """
        if isActiveVehicle:
            arenaUniqueID = self.__arenaVisitor.getArenaUniqueID()
            LOG_DEBUG('Try to exit from arena', arenaUniqueID)
            if arenaUniqueID:
                self.__ctx.lastArenaUniqueID = arenaUniqueID
            avatar_getter.leaveArena()