def __init__(self, flags=ViewFlags.VIEW):
     settings = ViewSettings(
         R.views.lobby.battle_pass.BattlePassEntryPointView())
     settings.flags = flags
     settings.model = BattlePassEntryPointViewModel()
     self.__isSmall = False
     self.__isAttentionTimerStarted = False
     self.__notifications = Notifiable()
     super(BattlePassEntryPointView, self).__init__(settings)
 def _initialize(self, *args, **kwargs):
     super(PremDashboardMapsBlacklistCard, self)._initialize(*args, **kwargs)
     self.viewModel.onGoToMapsBlacklistView += self.__onOpenMapsBlackListView
     self.__lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingsChanged
     self.__gameSession.onPremiumNotify += self.__updatePrem
     g_clientUpdateManager.addCallbacks({'preferredMaps': self.__onPreferredMapsChanged})
     self.__notifier = Notifiable()
     self.__notifier.addNotificator(AcyclicNotifier(lambda : ONE_MINUTE, self.__timerUpdate))
     self.__update()
コード例 #3
0
 def __init__(self):
     super(BoostersController, self).__init__()
     self.__eventManager = Event.EventManager()
     self.onBoosterChangeNotify = Event.Event(self.__eventManager)
     self.onReserveTimerTick = Event.Event(self.__eventManager)
     self.__boosterNotifyTimeCallback = None
     self.__boostersForUpdate = []
     self.__notificatorManager = Notifiable()
     return
コード例 #4
0
 def __init__(self, notifierClass = None):
     Notifiable.__init__(self)
     self.__sortiesAvailable = None
     self.__currServerAvailable = None
     self.onStatusChanged = Event.Event()
     notifier = notifierClass or SimpleNotifier
     self.addNotificator(notifier(self.__getClosestUpdatePeriod, self.__notificatorUpdated))
     self.__currentPeriod = 0
     self.__periods = None
     return
 def _onLoading(self, *args, **kwargs):
     super(BattlePassProgressionsView, self)._onLoading()
     self.__notifier = Notifiable()
     self.__notifier.addNotificator(
         PeriodicNotifier(self.__battlePass.getSeasonTimeLeft,
                          self.__updateTimer))
     self.__notifier.addNotificator(
         SimpleNotifier(self.__battlePass.getFinalOfferTimeLeft,
                        self.__updateTimer))
     self.__notifier.startNotification()
     self.__updateProgressData()
     self.__updateBuyButtonState()
コード例 #6
0
 def __init__(self,
              layoutID,
              wsFlags=ViewFlags.LOBBY_TOP_SUB_VIEW,
              viewModelClazz=BattlePassBuyViewModel,
              ctx=None):
     settings = ViewSettings(layoutID)
     settings.flags = wsFlags
     settings.model = viewModelClazz()
     self.__backCallback = None if ctx is None else ctx.get('backCallback')
     self.__packages = []
     self.__selectedPackage = None
     self.__tooltipItems = {}
     self.__notifications = Notifiable()
     self.__tooltipWindow = None
     super(BattlePassBuyView, self).__init__(settings)
     return
コード例 #7
0
 def _onLoading(self, *args, **kwargs):
     super(BattlePassProgressionsView, self)._onLoading()
     self.__addListeners()
     self.__notifier = Notifiable()
     self.__notifier.addNotificator(
         PeriodicNotifier(self.__battlePassController.getSeasonTimeLeft,
                          self.__updateTimer))
     self.__notifier.addNotificator(
         PeriodicNotifier(
             self.__battlePassController.getSellAnyLevelsUnlockTimeLeft,
             self.__updateTimer))
     self.__notifier.addNotificator(
         SimpleNotifier(self.__battlePassController.getFinalOfferTimeLeft,
                        self.__updateTimer))
     self.__notifier.startNotification()
     self.__updateProgressData()
     self.__updateBuyButtonState()
     self.__updateExtrasAndVotingButtons()
class PremDashboardMapsBlacklistCard(ViewImpl):
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __gameSession = dependency.descriptor(IGameSessionController)
    __slots__ = ('__notifier',)

    def __init__(self, layoutID=R.views.lobby.premacc.dashboard.prem_dashboard_maps_blacklist_card.PremDashboardMapsBlacklistCard()):
        settings = ViewSettings(layoutID)
        settings.model = PremDashboardMapsBlacklistCardModel()
        super(PremDashboardMapsBlacklistCard, self).__init__(settings)
        self.__notifier = None
        return

    @property
    def viewModel(self):
        return super(PremDashboardMapsBlacklistCard, self).getViewModel()

    def _initialize(self, *args, **kwargs):
        super(PremDashboardMapsBlacklistCard, self)._initialize(*args, **kwargs)
        self.viewModel.onGoToMapsBlacklistView += self.__onOpenMapsBlackListView
        self.__lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingsChanged
        self.__gameSession.onPremiumNotify += self.__updatePrem
        g_clientUpdateManager.addCallbacks({'preferredMaps': self.__onPreferredMapsChanged})
        self.__notifier = Notifiable()
        self.__notifier.addNotificator(AcyclicNotifier(lambda : ONE_MINUTE, self.__timerUpdate))
        self.__update()

    def _finalize(self):
        self.viewModel.onGoToMapsBlacklistView -= self.__onOpenMapsBlackListView
        self.__lobbyContext.getServerSettings().onServerSettingsChange -= self.__onServerSettingsChanged
        self.__gameSession.onPremiumNotify -= self.__updatePrem
        g_clientUpdateManager.removeObjectCallbacks(self)
        self.__notifier.clearNotification()
        super(PremDashboardMapsBlacklistCard, self)._finalize()

    def __onOpenMapsBlackListView(self, _=None):
        showMapsBlacklistView()
        self.__update()

    def __update(self):
        enabled = self.__lobbyContext.getServerSettings().isPreferredMapsEnabled()
        self.viewModel.setIsAvailable(enabled)
        if not enabled:
            return
        hasCooldown = False
        disabledMaps = self.viewModel.disabledMaps.getItems()
        disabledMaps.clear()
        for slotModel in buildSlotsModels(MapsBlacklistWidgetSlotModel):
            slotModel.setIsShowMode(True)
            disabledMaps.addViewModel(slotModel)
            if slotModel.getState() == MapsBlacklistSlotStates.MAPS_BLACKLIST_SLOT_STATE_COOLDOWN:
                hasCooldown = True

        disabledMaps.invalidate()
        if hasCooldown:
            self.__notifier.startNotification()
        else:
            self.__notifier.stopNotification()

    def __timerUpdate(self):
        self.__update()

    def __onServerSettingsChanged(self, diff):
        if PremiumConfigs.IS_PREFERRED_MAPS_ENABLED in diff or PremiumConfigs.PREFERRED_MAPS in diff:
            self.__update()

    def __onPreferredMapsChanged(self, _):
        self.__update()

    def __updatePrem(self, *_):
        self.__update()
コード例 #9
0
class BattlePassBuyView(ViewImpl):
    __slots__ = ('__packages', '__selectedPackage', '__tooltipItems',
                 '__backCallback', '__backBtnDescrLabel', '__notifications',
                 '__tooltipWindow')
    __battlePassController = dependency.descriptor(IBattlePassController)
    __wallet = dependency.descriptor(IWalletController)
    __itemsCache = dependency.descriptor(IItemsCache)

    def __init__(self,
                 layoutID,
                 wsFlags=ViewFlags.LOBBY_TOP_SUB_VIEW,
                 viewModelClazz=BattlePassBuyViewModel,
                 ctx=None):
        settings = ViewSettings(layoutID)
        settings.flags = wsFlags
        settings.model = viewModelClazz()
        self.__backCallback = None if ctx is None else ctx.get('backCallback')
        self.__packages = []
        self.__selectedPackage = None
        self.__tooltipItems = {}
        self.__notifications = Notifiable()
        self.__tooltipWindow = None
        super(BattlePassBuyView, self).__init__(settings)
        return

    @property
    def viewModel(self):
        return super(BattlePassBuyView, self).getViewModel()

    def createToolTip(self, event):
        if event.contentID == R.views.common.tooltip_window.backport_tooltip_content.BackportTooltipContent(
        ):
            tooltipId = event.getArgument('tooltipId')
            if tooltipId is None:
                return
            tooltipData = self.__tooltipItems.get(tooltipId)
            if tooltipData is None:
                return
            isGFTooltip = isUndefinedBonusTooltipData(tooltipData)
            if isGFTooltip:
                window = createUndefinedBonusTooltipWindow(
                    tooltipData, self.getParentWindow())
            else:
                window = backport.BackportTooltipWindow(
                    tooltipData, self.getParentWindow())
            self.__tooltipWindow = window
            if window is None:
                return
            window.load()
            if isGFTooltip:
                window.move(event.mouse.positionX, event.mouse.positionY)
            return window
        else:
            return super(BattlePassBuyView, self).createToolTip(event)

    def _onLoading(self, *args, **kwargs):
        super(BattlePassBuyView, self)._onLoading(*args, **kwargs)
        self.__addListeners()
        self.__notifications.addNotificator(
            PeriodicNotifier(self.__timeTillUnlock, self.__updateUnlockTimes))
        with self.viewModel.transaction() as tx:
            tx.setIsBattlePassBought(self.__battlePassController.isBought())
            tx.setIsWalletAvailable(self.__wallet.isAvailable)
        self.__packages = generatePackages()
        self.__setPackages()
        switchHangarOverlaySoundFilter(on=True)
        self.__notifications.startNotification()

    def _finalize(self):
        super(BattlePassBuyView, self)._finalize()
        self.__removeListeners()
        self.__selectedPackage = None
        self.__tooltipItems = None
        self.__packages = None
        self.__tooltipWindow = None
        switchHangarOverlaySoundFilter(on=False)
        self.__notifications.clearNotification()
        return

    def __clearTooltips(self):
        self.__tooltipItems.clear()
        if self.__tooltipWindow is not None:
            self.__tooltipWindow.destroy()
            self.__tooltipWindow = None
        return

    def __onBackClick(self):
        if self.__backCallback is not None:
            self.__backCallback()
        else:
            self.destroyWindow()
        return

    def __showConfirm(self):
        self.__setConfirmModel()
        self.viewModel.setState(self.viewModel.CONFIRM_STATE)
        SoundGroups.g_instance.playSound2D(BattlePassSounds.CONFIRM_BUY)

    def __showConfirmAny(self):
        self.__setConfirmAnyNumberModel()
        self.viewModel.setState(self.viewModel.CONFIRM_ANY_NUMBER_STATE)
        SoundGroups.g_instance.playSound2D(BattlePassSounds.CONFIRM_BUY)

    def __showRewards(self):
        self.viewModel.setState(self.viewModel.REWARDS_STATE)

    def __showBuy(self):
        self.__selectedPackage = None
        self.__clearTooltips()
        self.viewModel.setState(self.viewModel.BUY_STATE)
        SoundGroups.g_instance.playSound2D(
            BattlePassSounds.getOverlay(
                self.viewModel.packages.getItemsLength()))
        return

    def __addListeners(self):
        model = self.viewModel
        model.choosePackage += self.__choosePackage
        model.showConfirm += self.__showConfirm
        model.showConfirmAny += self.__showConfirmAny
        model.showRewards += self.__showRewards
        model.showBuy += self.__showBuy
        model.onBackClick += self.__onBackClick
        model.confirm.onShowRewardsClick += self.__showRewards
        model.confirm.onBuyClick += self.__onBuyBattlePassClick
        model.confirmAnyNumber.onChangeSelectedLevels += self.__onChangeSelectedLevels
        model.confirmAnyNumber.onBuyClick += self.__onBuyBattlePassClick
        model.confirmAnyNumber.onShowRewardsClick += self.__showRewards
        self.__battlePassController.onLevelUp += self.__onLevelUp
        self.__battlePassController.onBattlePassSettingsChange += self.__onSettingsChange
        self.__battlePassController.onUnlimitedPurchaseUnlocked += self.__updateState
        g_eventBus.addListener(events.BattlePassEvent.BUYING_THINGS,
                               self.__onBuying, EVENT_BUS_SCOPE.LOBBY)
        self.__wallet.onWalletStatusChanged += self.__onWalletChanged

    def __removeListeners(self):
        model = self.viewModel
        model.choosePackage -= self.__choosePackage
        model.showConfirm -= self.__showConfirm
        model.showConfirmAny -= self.__showConfirmAny
        model.showRewards -= self.__showRewards
        model.showBuy -= self.__showBuy
        model.onBackClick -= self.__onBackClick
        model.confirm.onShowRewardsClick -= self.__showRewards
        model.confirm.onBuyClick -= self.__onBuyBattlePassClick
        model.confirmAnyNumber.onChangeSelectedLevels -= self.__onChangeSelectedLevels
        model.confirmAnyNumber.onBuyClick -= self.__onBuyBattlePassClick
        model.confirmAnyNumber.onShowRewardsClick -= self.__showRewards
        self.__battlePassController.onLevelUp -= self.__onLevelUp
        self.__battlePassController.onBattlePassSettingsChange -= self.__onSettingsChange
        self.__battlePassController.onUnlimitedPurchaseUnlocked -= self.__updateState
        g_eventBus.removeListener(events.BattlePassEvent.BUYING_THINGS,
                                  self.__onBuying, EVENT_BUS_SCOPE.LOBBY)
        g_eventBus.removeListener(events.BattlePassEvent.AWARD_VIEW_CLOSE,
                                  self.__onAwardViewClose,
                                  EVENT_BUS_SCOPE.LOBBY)
        self.__wallet.onWalletStatusChanged -= self.__onWalletChanged

    def __onBuying(self, _):
        self.__battlePassController.onLevelUp += self.__onLevelUp

    def __onAwardViewClose(self, _):
        self.__onBackClick()

    def __onChangeSelectedLevels(self, args):
        self.__updateConfirmAnyNumberModel(args.get('count'))

    def __onLevelUp(self):
        self.__updateState()

    def __onSettingsChange(self, *_):
        if self.__battlePassController.isVisible(
        ) and not self.__battlePassController.isPaused():
            self.__updateState()
            self.__notifications.startNotification()
        else:
            showHangar()

    def __onWalletChanged(self, _):
        self.viewModel.setIsWalletAvailable(self.__wallet.isAvailable)

    def __updateState(self):
        if self.viewModel.getState(
        ) == self.viewModel.CONFIRM_ANY_NUMBER_STATE:
            if self.__battlePassController.getState() == BattlePassState.POST:
                self.destroyWindow()
            self.__setConfirmAnyNumberModel()
        elif self.viewModel.getState() == self.viewModel.CONFIRM_STATE:
            self.__setConfirmModel()
        elif self.viewModel.getState() == self.viewModel.REWARDS_STATE:
            self.__updateDetailRewards()
        else:
            self.__setPackages()
            self.viewModel.packages.invalidate()

    def __choosePackage(self, args):
        packageID = int(args.get('packageID'))
        self.__selectedPackage = self.__packages[packageID]
        if self.__selectedPackage.hasBattlePass():
            self.__showConfirm()
        else:
            self.__showConfirmAny()

    def __setConfirmModel(self):
        if self.__selectedPackage is None:
            return
        else:
            self.__clearTooltips()
            self.viewModel.confirm.setPrice(self.__selectedPackage.getPrice())
            self.viewModel.confirm.setLevelsCount(
                self.__selectedPackage.getLevelsCount())
            self.viewModel.confirm.setHasBattlePass(
                self.__selectedPackage.hasBattlePass())
            self.viewModel.confirm.setStartedProgression(
                self.__isStartedProgression())
            self.viewModel.confirm.setFinishedProgression(
                self.__isFinishedProgression())
            self.__updateDetailRewards()
            return

    def __setConfirmAnyNumberModel(self):
        if self.__selectedPackage is None:
            return
        else:
            with self.viewModel.confirmAnyNumber.transaction() as tx:
                tx.setLevelsTotal(self.__battlePassController.getMaxLevel())
                tx.setLevelsPassed(
                    self.__battlePassController.getCurrentLevel())
            self.__updateConfirmAnyNumberModel(
                self.__selectedPackage.getLevelsCount())
            return

    def __updateConfirmAnyNumberModel(self, count):
        if self.__selectedPackage is None:
            return
        else:
            self.__selectedPackage.setLevels(int(count))
            self.__clearTooltips()
            with self.viewModel.confirmAnyNumber.transaction() as tx:
                tx.setAllowSlide(self.__selectedPackage.isDynamic())
                tx.setPrice(self.__selectedPackage.getPrice())
                tx.setLevelsSelected(
                    self.__selectedPackage.getLevelsCount() +
                    self.__battlePassController.getCurrentLevel())
                tx.rewards.clearItems()
                packBonusModelAndTooltipData(
                    self.__selectedPackage.getNowAwards(), tx.rewards,
                    self.__tooltipItems)
            self.__updateDetailRewards()
            return

    def __updateDetailRewards(self):
        if not isCurrentBattlePassStateBase():
            curLevel = self.__battlePassController.getMaxLevel()
        else:
            curLevel = self.__battlePassController.getCurrentLevel()
        if self.__selectedPackage.hasBattlePass():
            fromLevel = 0
            toLevel = curLevel
        else:
            fromLevel = curLevel
            toLevel = curLevel + self.__selectedPackage.getLevelsCount()
        with self.viewModel.rewards.transaction() as tx:
            tx.nowRewards.clearItems()
            tx.futureRewards.clearItems()
            tx.setFromLevel(fromLevel + 1)
            tx.setToLevel(toLevel)
            tx.setStatePackage(self.__getTypePackage(self.__selectedPackage))
        packBonusModelAndTooltipData(self.__selectedPackage.getNowAwards(),
                                     self.viewModel.rewards.nowRewards,
                                     self.__tooltipItems)
        packBonusModelAndTooltipData(self.__selectedPackage.getFutureAwards(),
                                     self.viewModel.rewards.futureRewards,
                                     self.__tooltipItems)

    def __onBuyBattlePassClick(self):
        if self.__selectedPackage is not None:
            self.__battlePassController.onLevelUp -= self.__onLevelUp
            if self.__selectedPackage.hasBattlePass():
                BattlePassBuyer.buyBP(self.__selectedPackage.getSeasonID(),
                                      onBuyCallback=self.__onBuyBPCallback)
            else:
                BattlePassBuyer.buyLevels(
                    self.__selectedPackage.getSeasonID(),
                    self.__selectedPackage.getLevelsCount(),
                    onBuyCallback=self.__onBuyLevelsCallback)
        return

    def __onBuyBPCallback(self, result):
        if not result:
            self.__battlePassController.onLevelUp += self.__onLevelUp
        else:
            g_eventBus.addListener(events.BattlePassEvent.AWARD_VIEW_CLOSE,
                                   self.__onAwardViewClose,
                                   EVENT_BUS_SCOPE.LOBBY)

    def __onBuyLevelsCallback(self, result):
        if not result:
            self.__battlePassController.onLevelUp += self.__onLevelUp
        else:
            g_eventBus.addListener(events.BattlePassEvent.AWARD_VIEW_CLOSE,
                                   self.__onAwardViewClose,
                                   EVENT_BUS_SCOPE.LOBBY)
            g_eventBus.handleEvent(events.BattlePassEvent(
                events.BattlePassEvent.ON_PURCHASE_LEVELS),
                                   scope=EVENT_BUS_SCOPE.LOBBY)

    def __isStartedProgression(self):
        return self.__battlePassController.getCurrentLevel() > 0

    def __isFinishedProgression(self):
        return self.__battlePassController.getState() != BattlePassState.BASE

    @replaceNoneKwargsModel
    def __setPackages(self, model=None):
        model.packages.clearItems()
        for packageID, package in enumerate(self.__packages):
            if not package.isVisible():
                continue
            item = PackageItem()
            item.setPackageID(packageID)
            item.setPrice(package.getPrice())
            item.setLevels(package.getLevelsCount())
            item.setIsBought(package.isBought())
            item.setType(self.__getTypePackage(package))
            item.setIsLocked(package.isLocked())
            self.__setPackageUnlockTime(item, package)
            model.packages.addViewModel(item)

        SoundGroups.g_instance.playSound2D(
            BattlePassSounds.getOverlay(model.packages.getItemsLength()))

    def __timeTillUnlock(self):
        minTime = 0
        for package in self.__packages:
            timeToUnlock = package.getTimeToUnlock()
            minTime = min(timeToUnlock, minTime) if minTime else timeToUnlock

        return minTime

    def __updateUnlockTimes(self):
        for packageModel, package in zip(self.viewModel.packages.getItems(),
                                         self.__packages):
            self.__setPackageUnlockTime(packageModel, package)

        self.viewModel.packages.invalidate()

    @staticmethod
    def __setPackageUnlockTime(model, package):
        timeToUnlock = package.getTimeToUnlock()
        model.setTimeToUnlock(
            getFormattedTimeLeft(timeToUnlock) if timeToUnlock else '')

    @staticmethod
    def __getTypePackage(package):
        if package.hasBattlePass():
            return PackageItem.BATTLE_PASS_TYPE
        return PackageItem.ANY_LEVELS_TYPE if package.isDynamic(
        ) else PackageItem.LIMITED_LEVELS_TYPE
class BattlePassEntryPointView(ViewImpl, BaseBattlePassEntryPointView):
    __battlePass = dependency.descriptor(IBattlePassController)
    __slots__ = ('__isSmall', '__notifications', '__isAttentionTimerStarted')

    def __init__(self, flags=ViewFlags.VIEW):
        settings = ViewSettings(
            R.views.lobby.battle_pass.BattlePassEntryPointView())
        settings.flags = flags
        settings.model = BattlePassEntryPointViewModel()
        self.__isSmall = False
        self.__isAttentionTimerStarted = False
        self.__notifications = Notifiable()
        super(BattlePassEntryPointView, self).__init__(settings)

    @property
    def viewModel(self):
        return super(BattlePassEntryPointView, self).getViewModel()

    def createToolTipContent(self, event, contentID):
        if contentID == R.views.lobby.battle_pass.tooltips.BattlePassNotStartedTooltipView(
        ):
            return BattlePassNotStartedTooltipView()
        if contentID == R.views.lobby.battle_pass.tooltips.BattlePassNoChapterTooltipView(
        ):
            return BattlePassNoChapterTooltipView()
        return BattlePassCompletedTooltipView(
        ) if contentID == R.views.lobby.battle_pass.tooltips.BattlePassCompletedTooltipView(
        ) else BattlePassInProgressTooltipView()

    def setIsSmall(self, value):
        if self.viewModel.proxy:
            self.viewModel.setIsSmall(value)
        self.__isSmall = value

    def _onLoading(self, *args, **kwargs):
        super(BattlePassEntryPointView, self)._onLoading(*args, **kwargs)
        self._start()
        self.__notifications.addNotificator(
            PeriodicNotifier(self.__attentionTickTime,
                             self.__showAttentionAnimation))

    def _finalize(self):
        self.__notifications.clearNotification()
        self._stop()
        super(BattlePassEntryPointView, self)._finalize()

    def _addListeners(self):
        super(BattlePassEntryPointView, self)._addListeners()
        self.viewModel.onClick += self._onClick

    def _removeListeners(self):
        self.viewModel.onClick -= self._onClick
        super(BattlePassEntryPointView, self)._removeListeners()

    def _updateData(self, *_):
        self.__updateViewModel()

    def __attentionTickTime(self):
        return ATTENTION_TIMER_DELAY

    def __showAttentionAnimation(self):
        with self.getViewModel().transaction() as tx:
            tx.setAnimState(AnimationState.NOT_TAKEN_REWARDS)
            tx.setAnimStateKey(MS_IN_SECOND)

    def __startAttentionTimer(self):
        if not self.__isAttentionTimerStarted:
            self.__notifications.startNotification()
            self.__isAttentionTimerStarted = True

    def __stopAttentionTimer(self):
        self.__notifications.clearNotification()
        self.__isAttentionTimerStarted = False

    def __updateViewModel(self):
        uiState = self.__getUIState()
        if uiState == BPState.ATTENTION:
            self.__startAttentionTimer()
        else:
            self.__stopAttentionTimer()
        with self.getViewModel().transaction() as tx:
            tx.setIsSmall(self.__isSmall)
            tx.setTooltipID(self._getTooltip())
            tx.setPrevHasExtra(_g_entryLastState.hasExtra)
            tx.setHasExtra(self.hasExtra)
            tx.setPrevLevel(getPresentLevel(_g_entryLastState.level))
            tx.setLevel(getPresentLevel(self.level))
            tx.setChapterID(self.chapterID)
            tx.setPreviousChapterID(_g_entryLastState.chapterID)
            tx.setPrevProgression(_g_entryLastState.progress)
            tx.setProgression(self.progress)
            tx.setBattlePassState(uiState)
            tx.setNotChosenRewardCount(self.notChosenRewardCount)
            tx.setIsProgressionCompleted(self.isCompleted)
            tx.setIsChapterChosen(self.isChapterChosen)
            tx.setFreePoints(self.freePoints)
            tx.setHasBattlePass(self.isBought)
            tx.setAnimState(self.__getAnimationState())
            tx.setIsFirstShow(_g_entryLastState.isFirstShow)
            if self.chapterID:
                tx.setFinalReward(self.finalReward.value)
            if not self.__battlePass.isGameModeEnabled(
                    self._getCurrentArenaBonusType()):
                tx.setBattleType(getPreQueueName(self._getQueueType(), True))
        self._saveLastState()

    def __getAnimationState(self):
        animState = AnimationState.NORMAL
        lastState = _g_entryLastState
        if self.battlePassState == BattlePassState.COMPLETED and lastState.state != BattlePassState.COMPLETED:
            animState = AnimationState.PROGRESSION_COMPLETED
        elif self.chapterID and self.chapterID != lastState.chapterID:
            animState = AnimationState.NEW_CHAPTER
        elif not self.chapterID:
            animState = AnimationState.CHAPTER_NOT_CHOSEN
        elif self.level and self.level != lastState.level:
            animState = AnimationState.NEW_LEVEL
        elif self.isBought and not lastState.isBought:
            animState = AnimationState.BUY_BATTLE_PASS
        elif self.progress != lastState.progress:
            animState = AnimationState.CHANGE_PROGRESS
        elif self.notChosenRewardCount and self.notChosenRewardCount != lastState.rewardsCount:
            animState = AnimationState.NOT_TAKEN_REWARDS
        return animState

    def __getUIState(self):
        if self.isPaused:
            return BPState.DISABLED
        return BPState.ATTENTION if self.notChosenRewardCount and self.battlePassState != BattlePassState.BASE else BPState.NORMAL
コード例 #11
0
class BoostersController(IBoostersController):
    itemsCache = dependency.descriptor(IItemsCache)
    goodiesCache = dependency.descriptor(IGoodiesCache)

    def __init__(self):
        super(BoostersController, self).__init__()
        self.__eventManager = Event.EventManager()
        self.onBoosterChangeNotify = Event.Event(self.__eventManager)
        self.onReserveTimerTick = Event.Event(self.__eventManager)
        self.__boosterNotifyTimeCallback = None
        self.__boostersForUpdate = []
        self.__notificatorManager = Notifiable()
        return

    def fini(self):
        self._stop()
        super(BoostersController, self).fini()

    def onLobbyInited(self, event):
        self.itemsCache.onSyncCompleted += self._update
        self.__notificatorManager.addNotificator(
            PeriodicNotifier(self.__timeTillNextReserveTick,
                             self.onReserveTimerTick,
                             (time_utils.ONE_MINUTE, )))
        self.__notificatorManager.startNotification()
        if self.__boosterNotifyTimeCallback is None:
            self.__startBoosterTimeNotifyCallback()
        return

    def onAvatarBecomePlayer(self):
        self._stop()

    def onDisconnected(self):
        self._stop()

    def _stop(self):
        self.__clearBoosterTimeNotifyCallback()
        self.__notificatorManager.stopNotification()
        self.__notificatorManager.clearNotification()
        self.__boostersForUpdate = None
        self.__eventManager.clear()
        self.itemsCache.onSyncCompleted -= self._update
        return

    def _update(self, *args):
        self.__clearBoosterTimeNotifyCallback()
        self.__notificatorManager.startNotification()
        self.__startBoosterTimeNotifyCallback()

    def __startBoosterTimeNotifyCallback(self):
        self.__boostersForUpdate = []
        activeBoosters = self.goodiesCache.getBoosters(
            REQ_CRITERIA.BOOSTER.ACTIVE).values()
        notificationList = []
        for booster in activeBoosters:
            notificationList.append(
                (booster.boosterID,
                 booster.getUsageLeftTime() % time_utils.ONE_MINUTE))

        if notificationList:
            _, nextBoosterNotification = min(notificationList,
                                             key=itemgetter(1))
            for item in notificationList:
                if item[1] == nextBoosterNotification:
                    self.__boostersForUpdate.append(item[0])

            nextBoosterNotification = max(nextBoosterNotification, 1)
        else:
            return
        self.__boosterNotifyTimeCallback = BigWorld.callback(
            nextBoosterNotification, self.__notifyBoosterTime)

    def __notifyBoosterTime(self):
        self.__boosterNotifyTimeCallback = None
        self.onBoosterChangeNotify(self.__boostersForUpdate)
        self.__startBoosterTimeNotifyCallback()
        return

    def __clearBoosterTimeNotifyCallback(self):
        if self.__boosterNotifyTimeCallback is not None:
            BigWorld.cancelCallback(self.__boosterNotifyTimeCallback)
            self.__boosterNotifyTimeCallback = None
        return

    def __timeTillNextReserveTick(self):
        clanReserves = self.goodiesCache.getClanReserves().values()
        return min((reserve.getUsageLeftTime()
                    for reserve in clanReserves)) + 1 if clanReserves else 0
コード例 #12
0
class BattlePassEntryPointView(ViewImpl, BaseBattlePassEntryPointView):
    __slots__ = ('__isSmall', '__notifications', '__isAttentionTimerStarted')

    def __init__(self, flags=ViewFlags.VIEW):
        settings = ViewSettings(
            R.views.lobby.battle_pass.BattlePassEntryPointView())
        settings.flags = flags
        settings.model = BattlePassEntryPointViewModel()
        self.__isSmall = False
        self.__isAttentionTimerStarted = False
        self.__notifications = Notifiable()
        super(BattlePassEntryPointView, self).__init__(settings)

    @property
    def viewModel(self):
        return super(BattlePassEntryPointView, self).getViewModel()

    def setIsSmall(self, value):
        if self.viewModel.proxy:
            self.viewModel.setIsSmall(value)
        self.__isSmall = value

    def _onLoading(self, *args, **kwargs):
        super(BattlePassEntryPointView, self)._onLoading(*args, **kwargs)
        self._start()
        self.__notifications.addNotificator(
            PeriodicNotifier(self.__attentionTickTime,
                             self.__showAttentionAnimation))

    def _finalize(self):
        self.__notifications.clearNotification()
        self._stop()
        super(BattlePassEntryPointView, self)._finalize()

    def _addListeners(self):
        super(BattlePassEntryPointView, self)._addListeners()
        self.viewModel.onClick += self._onClick

    def _removeListeners(self):
        super(BattlePassEntryPointView, self)._removeListeners()
        self.viewModel.onClick -= self._onClick

    def _updateData(self, *_):
        super(BattlePassEntryPointView, self)._updateData()
        self.__updateViewModel()

    def createToolTipContent(self, event, contentID):
        if contentID == R.views.lobby.battle_pass.tooltips.BattlePassNotStartedTooltipView(
        ):
            return BattlePassNotStartedTooltipView()
        if contentID == R.views.lobby.battle_pass.tooltips.BattlePassCompletedTooltipView(
        ):
            return BattlePassCompletedTooltipView()
        return BattlePass3dStyleNotChosenTooltip(
        ) if contentID == R.views.lobby.battle_pass.tooltips.BattlePass3dStyleNotChosenTooltip(
        ) else BattlePassInProgressTooltipView()

    def __showAttentionAnimation(self):
        with self.getViewModel().transaction() as model:
            model.setAnimState(AnimationState.SHOW_NOT_TAKEN_REWARDS)
            model.setAnimStateKey(random.randint(0, 1000))

    def __attentionTickTime(self):
        return ATTENTION_TIMER_DELAY

    def __startAttentionTimer(self):
        if not self.__isAttentionTimerStarted:
            self.__notifications.startNotification()
            self.__isAttentionTimerStarted = True

    def __stopAttentionTimer(self):
        self.__notifications.clearNotification()
        self.__isAttentionTimerStarted = False

    def __updateViewModel(self):
        currentLevel = min(self._widgetLevel + 1,
                           self._battlePassController.getMaxLevel())
        notChosenRewardCount = 0
        is3DStyleChosen = False
        if self._isBattlePassPaused():
            state = BPState.DISABLED
        elif self._battlePassController.isOffSeasonEnable():
            state = BPState.SEASON_WAITING
        else:
            notChosen3DStylesCount = getNotChosen3DStylesCount(
                battlePass=self._battlePassController)
            notChosenRewardCount = self._battlePassController.getNotChosenRewardCount(
            ) + notChosen3DStylesCount
            is3DStyleChosen = notChosen3DStylesCount == 0
            state = BPState.ATTENTION if notChosenRewardCount > 0 else BPState.NORMAL
            if state == BPState.ATTENTION:
                self.__startAttentionTimer()
            else:
                self.__stopAttentionTimer()
        with self.getViewModel().transaction() as model:
            curPoints, limitPoints = self._battlePassController.getLevelProgression(
            )
            hasBattlePass = self._isBought()
            progression = curPoints * 100 / limitPoints if limitPoints else 100
            prevProgression = model.getProgression(
            ) if model.getProgression() != -1 else progression
            model.setIsSmall(self.__isSmall)
            model.setTooltipID(self._getTooltip())
            model.setPrevLevel(g_BPEntryPointStates.curLevel)
            model.setLevel(currentLevel)
            model.setChapterNumber(self._widgetChapter)
            model.setPrevProgression(prevProgression)
            model.setProgression(progression)
            model.setBattlePassState(state)
            model.setNotChosenRewardCount(notChosenRewardCount)
            model.setIs3DStyleChosen(is3DStyleChosen)
            if not self._battlePassController.isGameModeEnabled(
                    self._getCurrentArenaBonusType()):
                model.setBattleType(getPreQueueName(self._getQueueType(),
                                                    True))
            model.setIsProgressionCompleted(self._isCompleted())
            model.setHasBattlePass(hasBattlePass)
            animState = AnimationState.NORMAL
            if g_BPEntryPointStates.showProgressionCompleted:
                animState = AnimationState.SHOW_PROGRESSION_COMPLETED
            elif g_BPEntryPointStates.showSwitchToNewChapter:
                animState = AnimationState.SHOW_NEW_CHAPTER
            elif g_BPEntryPointStates.curLevel != currentLevel and g_BPEntryPointStates.curLevel != -1:
                animState = AnimationState.SHOW_NEW_LEVEL
            elif not g_BPEntryPointStates.isBPBought and hasBattlePass and not g_BPEntryPointStates.isFirstShow:
                animState = AnimationState.SHOW_BUY_BP
            elif prevProgression != progression:
                animState = AnimationState.SHOW_CHANGE_PROGRESS
            model.setAnimState(animState)
            model.setIsFirstShow(g_BPEntryPointStates.isFirstShow)
            g_BPEntryPointStates.curLevel = currentLevel
            g_BPEntryPointStates.isFirstShow = False
            g_BPEntryPointStates.isBPBought = hasBattlePass
            g_BPEntryPointStates.showSwitchToNewChapter = False
            g_BPEntryPointStates.showProgressionCompleted = False
        g_BPEntryPointStates.prevState = self._widgetState
コード例 #13
0
class BattlePassProgressionsView(ViewImpl):
    __slots__ = ('__tooltipItems', '__viewActive', '__tooltipContentCreator',
                 '__showDummyCallback', '__showViewCallback', '__notifier',
                 '__chosenChapter', '__showReplaceRewardAnimations')
    __settingsCore = dependency.descriptor(ISettingsCore)
    __battlePassController = dependency.descriptor(IBattlePassController)
    __gui = dependency.descriptor(IGuiLoader)
    __itemsCache = dependency.descriptor(IItemsCache)
    __wallet = dependency.descriptor(IWalletController)
    ANIMATION_PURCHASE_LEVELS = 'animPurchaseLevels'
    ANIMATIONS = {ANIMATION_PURCHASE_LEVELS: False}

    def __init__(self,
                 showDummyCallback,
                 showViewCallback,
                 flags=ViewFlags.VIEW):
        settings = ViewSettings(
            R.views.lobby.battle_pass.BattlePassProgressionsView())
        settings.flags = flags
        settings.model = BattlePassProgressionsViewModel()
        self.__showDummyCallback = showDummyCallback
        self.__showViewCallback = showViewCallback
        self.__tooltipItems = {}
        self.__viewActive = False
        self.__tooltipContentCreator = self.__getTooltipContentCreator()
        self.__chosenChapter = self.__battlePassController.getCurrentChapter()
        self.__showReplaceRewardAnimations = False
        super(BattlePassProgressionsView, self).__init__(settings)

    @property
    def viewModel(self):
        return super(BattlePassProgressionsView, self).getViewModel()

    @createBackportTooltipDecorator()
    def createToolTip(self, event):
        return super(BattlePassProgressionsView, self).createToolTip(event)

    @createTooltipContentDecorator()
    def createToolTipContent(self, event, contentID):
        tooltipContentCreator = self.__tooltipContentCreator.get(contentID)
        if tooltipContentCreator is None:
            raise SoftException(
                'Incorrect tooltip type with contentID {}'.format(contentID))
        return tooltipContentCreator(event)

    def getTooltipData(self, event):
        tooltipId = event.getArgument('tooltipId')
        return None if tooltipId is None else self.__tooltipItems.get(
            tooltipId)

    def setSubTab(self, subTab):
        self.__clearSubViews()
        if subTab == BattlePassProgressionSubTabs.BUY_TAB:
            self.__showBattlePassBuyWindow()
        elif subTab == BattlePassProgressionSubTabs.BUY_TAB_FOR_SHOP:
            self.__showBattlePassBuyWindow()
        elif subTab == BattlePassProgressionSubTabs.BUY_LEVELS_TAB:
            self.__showBattlePassBuyLevelsWindow()
        elif subTab == BattlePassProgressionSubTabs.BUY_LEVELS_TAB_FROM_SHOP:
            self.__showBattlePassBuyLevelsWindow()
        elif subTab == BattlePassProgressionSubTabs.SELECT_STYLE_TAB:
            self.__showStyleChoiceWindow()

    def _onLoading(self, *args, **kwargs):
        super(BattlePassProgressionsView, self)._onLoading()
        self.__addListeners()
        self.__notifier = Notifiable()
        self.__notifier.addNotificator(
            PeriodicNotifier(self.__battlePassController.getSeasonTimeLeft,
                             self.__updateTimer))
        self.__notifier.addNotificator(
            SimpleNotifier(self.__battlePassController.getFinalOfferTimeLeft,
                           self.__updateTimer))
        self.__notifier.startNotification()
        self.__updateProgressData()
        self.__updateBuyButtonState()

    def _finalize(self):
        super(BattlePassProgressionsView, self)._finalize()
        SoundGroups.g_instance.playSound2D(
            backport.sound(R.sounds.bp_progress_bar_stop()))
        self.__removeListeners()
        self.__showDummyCallback = None
        self.__showViewCallback = None
        self.__tooltipItems = None
        if self.viewModel.getShowIntro():
            self.__setBattlePassIntroShown()
        self.__notifier.stopNotification()
        self.__notifier.clearNotification()
        return

    def __showDummy(self):
        if self.__showDummyCallback is not None:
            self.__showDummyCallback(True)
            with self.viewModel.transaction() as model:
                model.setIsPaused(True)
        return

    def __hideDummy(self):
        if self.__showDummyCallback is not None:
            self.__showDummyCallback(False)
            with self.viewModel.transaction() as model:
                model.setIsPaused(False)
        return

    def __onBuyClick(self):
        self.__setBuyButtonHintShown()
        self.__updateBuyButtonState()
        with self.viewModel.transaction() as model:
            model.setShowBuyAnimations(False)
            model.setShowLevelsAnimations(
                self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        if self.__battlePassController.isBought(chapter=self.__chosenChapter):
            tab = BattlePassProgressionSubTabs.BUY_LEVELS_TAB
        else:
            tab = BattlePassProgressionSubTabs.BUY_TAB
        self.setSubTab(tab)

    def __onIntroCloseClick(self):
        if getNotChosen3DStylesCount() > 0:
            self.__onSelectStyle()
        self.viewModel.setShowIntro(False)
        self.__setBattlePassIntroShown()

    def __onAboutClick(self):
        self.__loadUrl(getInfoPageURL())

    @staticmethod
    def __onClose():
        showHangar()

    @staticmethod
    def __loadUrl(url):
        showBrowserOverlayView(url, VIEW_ALIAS.BATTLE_PASS_BROWSER_VIEW)

    def __showIntro(self):
        with self.viewModel.transaction() as tx:
            videoIsOpening = self.__showIntroVideo(onStart=True)
            tx.setShowIntro(self.__isFirstShowView())
            vehIntCDs = self.__battlePassController.getSpecialVehicles()
            capacity = self.__battlePassController.getVehicleProgression(
                vehIntCDs[0])[1]
            tx.intro.setPoints(capacity)
            for vehIntCD in vehIntCDs:
                if getVehicleByIntCD(vehIntCD) is not None:
                    tx.intro.getTankNames().addString(
                        getVehicleByIntCD(vehIntCD).userName)
                tx.intro.getTankNames().addString('')

            if not videoIsOpening:
                self.__setShowBuyAnimations(model=tx)
        return

    def __isFirstShowView(self):
        return not self.__settingsCore.serverSettings.getBPStorage().get(
            BattlePassStorageKeys.INTRO_SHOWN)

    def __setBattlePassIntroShown(self):
        self.__settingsCore.serverSettings.saveInBPStorage(
            {BattlePassStorageKeys.INTRO_SHOWN: True})

    def __updateProgressData(self):
        isPaused = self.__battlePassController.isPaused()
        if isPaused:
            self.__showDummy()
        elif self.__battlePassController.isOffSeasonEnable():
            self.__hideDummy()
            self.__updateOffSeason()
        else:
            self.__hideDummy()
            self.__showIntro()
            with self.viewModel.transaction() as model:
                self.__setAwards(model)
                self.__setCurrentLevelState(model=model)
                self.__updateBalance(model=model)
                self.__updateWalletAvailability(model=model)

    def __setAwards(self, model):
        self.__tooltipItems.clear()
        self.__setStyleWidget(model)
        self.__setRewardsList(BattlePassConsts.REWARD_FREE, model.freeRewards)
        self.__setRewardsList(BattlePassConsts.REWARD_PAID, model.paidRewards)
        self.__setChapterCharacter(model)
        self.__resetReplaceRewardAnimations(model=model)

    def __setStyleWidget(self, model):
        chosenItems = self.__itemsCache.items.battlePass.getChosenItems()
        if chosenItems is None or self.__chosenChapter not in chosenItems:
            style, level = (None, 0)
        else:
            intCD, level = chosenItems[self.__chosenChapter]
            style = self.__itemsCache.items.getItemByCD(intCD)
        isUnselectedPrevStyle = chosenItems is not None and self.__chosenChapter != BattlePassConsts.MINIMAL_CHAPTER_NUMBER and self.__chosenChapter - 1 not in chosenItems
        model.widget3dStyle.setStyleName(style.userName if style else '')
        model.widget3dStyle.setStyleId(style.id if style else 0)
        model.widget3dStyle.setLevel(level)
        model.widget3dStyle.setIsUnselectedPrevStyle(isUnselectedPrevStyle)
        if style is not None:
            vehicleCD = getVehicleCDForStyle(style,
                                             itemsCache=self.__itemsCache)
            vehicle = getVehicleByIntCD(vehicleCD)
            fillVehicleInfo(model.widget3dStyle.vehicleInfo, vehicle)
        return

    def __setChapterCharacter(self, model):
        _, maxLevel = self.__battlePassController.getChapterLevelInterval(
            self.__chosenChapter)
        freeModel = model.freeRewards.getItem(
            model.freeRewards.getItemsLength() - 1)
        tooltipId = self.__removeCharacter(freeModel)
        freeRewards = self.__battlePassController.getSingleAward(maxLevel)
        characterBonus = findFirst(lambda b: b.getName() == 'tmanToken',
                                   freeRewards)
        if characterBonus is None:
            self.__clearChapterCharacter(model)
            return
        else:
            character = getTankmanInfo(characterBonus)
            if character is None:
                self.__clearChapterCharacter(model)
                return
            iconName, characterName, skills = getDataByTankman(character)
            skillsArray = Array()
            for skill in skills:
                skillsArray.addString(skill)

            model.chapterCharacter.setIcon(iconName)
            model.chapterCharacter.setTankman(characterName)
            model.chapterCharacter.setSkills(skillsArray)
            if tooltipId is not None:
                model.chapterCharacter.setTooltipId(tooltipId)
            return

    @staticmethod
    def __clearChapterCharacter(model):
        model.chapterCharacter.setIcon('')
        model.chapterCharacter.setTankman('')
        model.chapterCharacter.setSkills(Array())

    @staticmethod
    def __removeCharacter(model):
        tooltipId = None
        freeItems = model.rewardItems.getItems()
        indexes = []
        for index, item in enumerate(freeItems):
            if item.getName() == 'tmanToken':
                indexes.append(index)
                tooltipId = item.getTooltipId()

        model.rewardItems.removeItemByIndexes(indexes)
        return tooltipId

    def __setRewardsList(self, awardType, model):
        model.clearItems()
        minLevel, maxLevel = self.__battlePassController.getChapterLevelInterval(
            self.__chosenChapter)
        curLevel = self.__battlePassController.getCurrentLevel()
        isBattlePassBought = self.__battlePassController.isBought(
            chapter=self.__chosenChapter)
        bonuses = sorted(self.__battlePassController.getAwardsInterval(
            minLevel, maxLevel, awardType).iteritems(),
                         key=itemgetter(0))
        for level, awards in bonuses:
            item = RewardLevelModel()
            item.setLevel(level)
            item.setLevelPoints(
                self.__battlePassController.getLevelPoints(level - 1))
            item.setIsRare(self.__battlePassController.isRareLevel(level))
            levelState, isNeedToTake, isChooseRewardEnabled = self.__getRewardLevelState(
                awardType, curLevel, level, isBattlePassBought)
            item.setState(levelState)
            item.setNeedTake(isNeedToTake)
            item.setIsRewardChoiceEnabled(isChooseRewardEnabled)
            realAwards = self.__battlePassController.replaceOfferByReward(
                awards)
            packBonusModelAndTooltipData(realAwards, item.rewardItems,
                                         self.__tooltipItems)
            model.addViewModel(item)

        model.invalidate()

    def __resetRewardsInterval(self,
                               awardType,
                               model,
                               fromLevel,
                               toLevel,
                               chapter,
                               replaceRewards=False):
        curLevel = self.__battlePassController.getCurrentLevel()
        isBattlePassBought = self.__battlePassController.isBought()
        startLevel, finalLevel = self.__battlePassController.getChapterLevelInterval(
            chapter)
        if fromLevel <= startLevel:
            fromLevel = startLevel + 1
        if toLevel > finalLevel:
            toLevel = finalLevel
        for level in range(fromLevel, toLevel + 1):
            item = model.getItem(level - startLevel)
            levelState, isNeedToTake, isChooseRewardEnabled = self.__getRewardLevelState(
                awardType, curLevel, level, isBattlePassBought)
            if replaceRewards and item.getNeedTake() and not isNeedToTake:
                item.rewardItems.clearItems()
                awards = self.__battlePassController.getSingleAward(
                    level, awardType)
                realAwards = self.__battlePassController.replaceOfferByReward(
                    awards)
                packBonusModelAndTooltipData(realAwards, item.rewardItems,
                                             self.__tooltipItems)
                self.__showReplaceRewardAnimations = True
            item.setState(levelState)
            item.setNeedTake(isNeedToTake)
            item.setIsRewardChoiceEnabled(isChooseRewardEnabled)

        model.invalidate()

    def __getRewardLevelState(self, awardType, curLevel, level,
                              isBattlePassBought):
        isReached = curLevel >= level or self.__battlePassController.getState(
        ) == BattlePassState.COMPLETED
        if awardType == BattlePassConsts.REWARD_PAID and not isBattlePassBought:
            levelState = RewardLevelModel.DISABLED
        else:
            levelState = RewardLevelModel.REACHED if isReached else RewardLevelModel.NOT_REACHED
        isNeedToTake = self.__battlePassController.isNeedToTakeReward(
            awardType, level)
        if isNeedToTake:
            isChooseRewardEnabled = self.__battlePassController.isChooseRewardEnabled(
                awardType, level)
            levelState = RewardLevelModel.NOT_CHOSEN
        else:
            isChooseRewardEnabled = False
        return (levelState, isNeedToTake, isChooseRewardEnabled)

    @replaceNoneKwargsModel
    def __setCurrentLevelState(self, model=None):
        currentChapter = self.__battlePassController.getCurrentChapter()
        pointsBeforeChapterStart = self.__battlePassController.getFullChapterPoints(
            self.__chosenChapter, False)
        minLevel, maxLevel = self.__battlePassController.getChapterLevelInterval(
            self.__chosenChapter)
        if self.__chosenChapter == currentChapter:
            previousTotalPoints = AccountSettings.getSettings(
                LAST_BATTLE_PASS_POINTS_SEEN)
            currentTotalPoints = self.__battlePassController.getCurrentPoints()
            AccountSettings.setSettings(LAST_BATTLE_PASS_POINTS_SEEN,
                                        currentTotalPoints)
        elif self.__chosenChapter < currentChapter:
            previousTotalPoints = currentTotalPoints = self.__battlePassController.getFullChapterPoints(
                self.__chosenChapter, True)
        else:
            previousTotalPoints = currentTotalPoints = pointsBeforeChapterStart
        _, previousLevel = self.__battlePassController.getLevelByPoints(
            previousTotalPoints)
        previousPoints, _ = self.__battlePassController.getProgressionByPoints(
            previousTotalPoints, previousLevel)
        previousLevel += 1
        _, currentLevel = self.__battlePassController.getLevelByPoints(
            currentTotalPoints)
        currentLevel += 1
        if previousTotalPoints > currentTotalPoints or previousLevel > currentLevel:
            previousLevel = minLevel
            previousTotalPoints = pointsBeforeChapterStart
        previousLevel = min(max(previousLevel, minLevel - 1), maxLevel + 1)
        currentLevel = min(max(currentLevel, minLevel - 1), maxLevel + 1)
        previousTotalPoints = max(
            0, previousTotalPoints - pointsBeforeChapterStart)
        currentTotalPoints -= pointsBeforeChapterStart
        isBattlePassBought = self.__battlePassController.isBought(
            chapter=self.__chosenChapter)
        chapterConfig = self.__battlePassController.getChapterConfig()
        model.setChapterCount(len(chapterConfig))
        model.setChapterStep(first(chapterConfig, default=0))
        model.setChosenChapter(self.__chosenChapter)
        model.setCurrentChapter(currentChapter)
        model.setPointsBeforeStart(pointsBeforeChapterStart)
        chapterText = backport.text(
            _rBattlePass.progression.chapterText(),
            chapter=backport.text(
                _rBattlePass.chapter.name.num(self.__chosenChapter)()),
            chapterName=backport.text(
                _rBattlePass.chapter.fullName.num(self.__chosenChapter)()))
        model.setChapterText(chapterText)
        model.setPreviousAllPoints(previousTotalPoints)
        model.setPreviousPoints(previousPoints)
        model.setPreviousLevel(previousLevel)
        model.setCurrentAllPoints(currentTotalPoints)
        currentPoints, levelPoints = self.__battlePassController.getLevelProgression(
        )
        if self.__chosenChapter != currentChapter:
            currentPoints = 0
            currentLevel = self.__battlePassController.getCurrentLevel() + 1
        currentLevel = min(currentLevel,
                           self.__battlePassController.getMaxLevel())
        model.setCurrentPoints(currentPoints)
        model.setTotalPoints(levelPoints)
        model.setCurrentLevel(currentLevel)
        model.setIsBattlePassPurchased(isBattlePassBought)
        model.setIsPaused(self.__battlePassController.isPaused())
        model.setSeasonTimeLeft(
            getFormattedTimeLeft(
                self.__battlePassController.getSeasonTimeLeft()))
        if self.__battlePassController.isSeasonFinished():
            model.setSeasonText(
                backport.text(_rBattlePass.commonProgression.body.ended()))
        else:
            seasonNum = self.__battlePassController.getSeasonNum()
            timeEnd = self.__battlePassController.getSeasonFinishTime()
            model.setSeasonText(self.__makeSeasonTimeText(timeEnd, seasonNum))
        self.__updateRewardSelectButton(model=model)

    def __updateOffSeason(self):
        prevSeasonStats = self.__battlePassController.getLastFinishedSeasonStats(
        )
        if prevSeasonStats is None:
            self.__showDummy()
            _logger.warning('There is not previous season stats')
            return
        else:
            prevOtherStats = prevSeasonStats.otherStats
            prevSeasonHistory = getSeasonHistory(prevSeasonStats.seasonID)
            if prevSeasonHistory is None:
                self.__showDummy()
                _logger.warning('There is not previous season %r history',
                                prevSeasonStats.seasonID)
                return
            sumPoints = sum(prevSeasonStats.vehPoints)
            seasonName = backport.text(_rBattlePass.offSeason.title(),
                                       season=int2roman(
                                           prevSeasonHistory.seasonNum))
            state, currentLevel = getLevelFromStats(prevOtherStats,
                                                    prevSeasonHistory)
            with self.viewModel.transaction() as tx:
                tx.setShowOffSeason(True)
                offSeason = tx.offSeason
                offSeason.setLevel(currentLevel + 1)
                offSeason.setSeasonName(seasonName)
                offSeason.setHasBattlePass(
                    self.__battlePassController.isBought(
                        prevSeasonStats.seasonID))
                offSeason.setIsPostProgression(state != BattlePassState.BASE)
                offSeason.setIsPostProgressionCompleted(
                    state == BattlePassState.COMPLETED)
                offSeason.setIsEnabled(sumPoints > 0)
            return

    def __updateBuyButtonState(self):
        currentLevel = self.__battlePassController.getCurrentLevel()
        isBattlePassBought = self.__battlePassController.isBought(
            chapter=self.__chosenChapter)
        minLevel, maxLevel = self.__battlePassController.getChapterLevelInterval(
            self.__chosenChapter)
        allLevelsComplete = maxLevel <= currentLevel or self.__battlePassController.getState(
        ) == BattlePassState.COMPLETED
        isVisible = not (isBattlePassBought and allLevelsComplete)
        if not isVisible:
            with self.viewModel.transaction() as model:
                model.setIsVisibleBuyButton(isVisible)
            return
        seasonTimeLeft = ''
        if minLevel > currentLevel + 1:
            if not isBattlePassBought:
                state = self.viewModel.buyButton.DISABLE_BP
            else:
                state = self.viewModel.buyButton.DISABLE_LEVELS
        elif not isBattlePassBought:
            state = self.viewModel.buyButton.BUY_BP
        else:
            state = self.viewModel.buyButton.BUY_LEVELS
        showBubble = not self.__isBuyButtonHintShown()
        isHighlightOn = isSeasonEndingSoon()
        if isHighlightOn:
            seasonTimeLeft = getFormattedTimeLeft(
                self.__battlePassController.getSeasonTimeLeft())
        with self.viewModel.transaction() as model:
            model.setIsVisibleBuyButton(isVisible)
            buyButtonModel = model.buyButton
            buyButtonModel.setState(state)
            buyButtonModel.setIsHighlightOn(isHighlightOn)
            buyButtonModel.setSeasonTimeLeft(seasonTimeLeft)
            buyButtonModel.setShowBuyButtonBubble(showBubble)

    @replaceNoneKwargsModel
    def __updateRewardSelectButton(self, model=None):
        model.setIsChooseDeviceEnabled(False)
        model.setIsTakeAllButtonVisible(False)
        notChosenStylesCount = getNotChosen3DStylesCount(
            battlePass=self.__battlePassController,
            itemsCache=self.__itemsCache)
        notChosenRewardCount = self.__battlePassController.getNotChosenRewardCount(
        )
        if self.__battlePassController.hasAnyOfferGiftToken(
        ) or notChosenStylesCount:
            model.setIsTakeAllButtonVisible(True)
            model.setIsChooseDeviceEnabled(
                self.__battlePassController.canChooseAnyReward()
                or notChosenStylesCount)
            notChosenRewardCount += notChosenStylesCount
            model.setNotChosenRewardCount(notChosenRewardCount)

    @replaceNoneKwargsModel
    def __updateRewardSelectButtons(self, model=None):
        startLevel = 1
        finalLevel = self.__battlePassController.getMaxLevel()
        self.__resetRewardSelectButtons(BattlePassConsts.REWARD_FREE,
                                        model.freeRewards, startLevel,
                                        finalLevel, self.__chosenChapter)
        self.__resetRewardSelectButtons(BattlePassConsts.REWARD_PAID,
                                        model.paidRewards, startLevel,
                                        finalLevel, self.__chosenChapter)

    def __resetRewardSelectButtons(self, awardType, model, fromLevel, toLevel,
                                   chapter):
        startLevel, finalLevel = self.__battlePassController.getChapterLevelInterval(
            chapter)
        if fromLevel <= startLevel:
            fromLevel = startLevel + 1
        if toLevel > finalLevel:
            toLevel = finalLevel
        for level in range(fromLevel, toLevel + 1):
            item = model.getItem(level - startLevel)
            isChooseRewardEnabled = self.__battlePassController.isChooseRewardEnabled(
                awardType, level)
            item.setIsRewardChoiceEnabled(isChooseRewardEnabled)

        model.invalidate()

    def __updateTimer(self):
        self.viewModel.setSeasonTimeLeft(
            getFormattedTimeLeft(
                self.__battlePassController.getSeasonTimeLeft()))
        self.__updateBuyButtonState()

    def __isBuyButtonHintShown(self):
        return self.__settingsCore.serverSettings.getBPStorage().get(
            BattlePassStorageKeys.BUY_BUTTON_HINT_IS_SHOWN)

    def __setBuyButtonHintShown(self):
        self.__settingsCore.serverSettings.saveInBPStorage(
            {BattlePassStorageKeys.BUY_BUTTON_HINT_IS_SHOWN: True})

    def __addListeners(self):
        model = self.viewModel
        model.onBuyClick += self.__onBuyClick
        model.onAboutClick += self.__onAboutClick
        model.onViewLoaded += self.__showViewCallback
        model.onClose += self.__onClose
        model.intro.onClose += self.__onIntroCloseClick
        model.intro.onVideo += self.__showIntroVideo
        model.onGoToChapter += self.__onGoToChapter
        model.widget3dStyle.onPreviewClick += self.__onPreviewClick
        model.widget3dStyle.onSelectStyle += self.__onSelectStyle
        model.onTakeClick += self.__onTakeClick
        model.onTakeAllClick += self.__onTakeAllClick
        model.onOpenShopClick += self.__onOpenShopClick
        model.onPointsInfoClick += self.__onPointsInfoClick
        model.onFinishedAnimation += self.__resetReplaceRewardAnimations
        model.onLevelsAnimationFinished += self.__resetLevelAnimations
        self.__battlePassController.onPointsUpdated += self.__onPointsUpdated
        self.__battlePassController.onBattlePassIsBought += self.__onBattlePassBought
        self.__battlePassController.onBattlePassSettingsChange += self.__onBattlePassSettingsChange
        self.__battlePassController.onRewardSelectChange += self.__onRewardSelectChange
        self.__battlePassController.onOffersUpdated += self.__onOffersUpdated
        self.__battlePassController.onSeasonStateChange += self.__updateProgressData
        self.__wallet.onWalletStatusChanged += self.__updateWalletAvailability
        g_clientUpdateManager.addCurrencyCallback(Currency.BPCOIN,
                                                  self.__updateBalance)
        g_eventBus.addListener(events.MissionsEvent.ON_TAB_CHANGED,
                               self.__onMissionsTabChanged,
                               EVENT_BUS_SCOPE.LOBBY)
        g_eventBus.addListener(events.FocusEvent.COMPONENT_FOCUSED,
                               self.__onFocus)
        g_eventBus.addListener(events.BattlePassEvent.ON_PURCHASE_LEVELS,
                               self.__onPurchaseLevels, EVENT_BUS_SCOPE.LOBBY)

    def __removeListeners(self):
        model = self.viewModel
        model.onBuyClick -= self.__onBuyClick
        model.onAboutClick -= self.__onAboutClick
        model.onViewLoaded -= self.__showViewCallback
        model.onClose -= self.__onClose
        model.intro.onClose -= self.__onIntroCloseClick
        model.intro.onVideo -= self.__showIntroVideo
        model.onGoToChapter -= self.__onGoToChapter
        model.widget3dStyle.onPreviewClick -= self.__onPreviewClick
        model.widget3dStyle.onSelectStyle -= self.__onSelectStyle
        model.onTakeClick -= self.__onTakeClick
        model.onOpenShopClick -= self.__onOpenShopClick
        model.onTakeAllClick -= self.__onTakeAllClick
        model.onPointsInfoClick -= self.__onPointsInfoClick
        model.onFinishedAnimation -= self.__resetReplaceRewardAnimations
        model.onLevelsAnimationFinished -= self.__resetLevelAnimations
        self.__battlePassController.onPointsUpdated -= self.__onPointsUpdated
        self.__battlePassController.onBattlePassIsBought -= self.__onBattlePassBought
        self.__battlePassController.onBattlePassSettingsChange -= self.__onBattlePassSettingsChange
        self.__battlePassController.onRewardSelectChange -= self.__onRewardSelectChange
        self.__battlePassController.onOffersUpdated -= self.__onOffersUpdated
        self.__battlePassController.onSeasonStateChange -= self.__updateProgressData
        self.__wallet.onWalletStatusChanged -= self.__updateWalletAvailability
        g_clientUpdateManager.removeCurrencyCallback(Currency.BPCOIN,
                                                     self.__updateBalance)
        g_eventBus.removeListener(events.MissionsEvent.ON_TAB_CHANGED,
                                  self.__onMissionsTabChanged,
                                  EVENT_BUS_SCOPE.LOBBY)
        g_eventBus.removeListener(events.FocusEvent.COMPONENT_FOCUSED,
                                  self.__onFocus)
        g_eventBus.removeListener(events.BattlePassEvent.ON_PURCHASE_LEVELS,
                                  self.__onPurchaseLevels,
                                  EVENT_BUS_SCOPE.LOBBY)

    @staticmethod
    def __getDayMonth(timeStamp):
        timeStruct = time_utils.getTimeStructInLocal(timeStamp)
        return (timeStruct.tm_mday, timeStruct.tm_mon)

    def __onMissionsTabChanged(self, event):
        viewActive = event.ctx == QUESTS_ALIASES.BATTLE_PASS_MISSIONS_VIEW_PY_ALIAS
        if self.__viewActive == viewActive and self.__viewActive:
            self.__clearSubViews()
        self.__viewActive = viewActive

    def __clearSubViews(self):
        def __lobbyTopSubViewPredicate(view):
            return view.viewFlags & ViewFlags.VIEW_TYPE_MASK == ViewFlags.LOBBY_TOP_SUB_VIEW and view.viewStatus in (
                ViewStatus.LOADED, ViewStatus.LOADING)

        views = self.__gui.windowsManager.findViews(__lobbyTopSubViewPredicate)
        for view in views:
            view.destroyWindow()

    def __onFocus(self, event):
        context = event.ctx
        if context.get('alias') == VIEW_ALIAS.LOBBY_MISSIONS:
            if self.__viewActive:
                self.__setShowBuyAnimations()

    def __onBattlePassSettingsChange(self, *_):
        if not self.__battlePassController.isEnabled():
            showHangar()
            return
        self.__updateProgressData()
        self.__updateBuyButtonState()

    def __onGoToChapter(self, args):
        chapter = args.get('chapterNumber')
        if chapter is None:
            return
        else:
            self.__chosenChapter = int(chapter)
            self.__updateProgressData()
            self.__updateBuyButtonState()
            return

    def __onPreviewClick(self):
        styleInfo = getStyleForChapter(self.__chosenChapter,
                                       itemsCache=self.__itemsCache)
        vehicleCD = getVehicleCDForStyle(styleInfo,
                                         itemsCache=self.__itemsCache)
        showProgressionStylesStylePreview(
            vehicleCD, styleInfo, styleInfo.getDescription(),
            showMissionsBattlePassCommonProgression)

    def __onSelectStyle(self):
        self.setSubTab(BattlePassProgressionSubTabs.SELECT_STYLE_TAB)

    def __onPointsUpdated(self):
        with self.viewModel.transaction() as model:
            newChapter = self.__battlePassController.getCurrentChapter()
            if model.getCurrentChapter() != newChapter:
                self.__onGoToChapter({'chapterNumber': newChapter})
                return
            oldPoints = model.getCurrentAllPoints()
            pointsBeforeStart = model.getPointsBeforeStart()
            oldPoints += pointsBeforeStart
            oldChapter, oldLevel = self.__battlePassController.getLevelByPoints(
                oldPoints)
            newPoints = self.__battlePassController.getCurrentPoints()
            newLevel = self.__battlePassController.getCurrentLevel()
            self.__resetRewardsInterval(BattlePassConsts.REWARD_FREE,
                                        model.freeRewards, oldLevel, newLevel,
                                        oldChapter)
            self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                        model.paidRewards, oldLevel, newLevel,
                                        oldChapter)
            self.__setCurrentLevelState(model=model)
        isDrawPoints = newLevel < oldLevel or newPoints < oldPoints
        if isDrawPoints:
            model.setShowLevelsAnimations(
                self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.__updateBuyButtonState()

    def __updateTooltipsSingleCard(self, rewards, model):
        tooltipIds = [
            item.getTooltipId() for item in model.rewardItems.getItems()
        ]
        tooltipIds = tooltipIds[:len(rewards)]
        changeBonusTooltipData(zip(rewards, tooltipIds), self.__tooltipItems)

    def __onBattlePassBought(self):
        with self.viewModel.transaction() as model:
            startLevel = 1
            finalLevel = self.__battlePassController.getMaxLevel()
            self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                        model.paidRewards, startLevel,
                                        finalLevel, self.__chosenChapter)
            self.__setCurrentLevelState(model=model)
        self.__updateBuyButtonState()

    def __onRewardSelectChange(self):
        self.__updateRewardSelectButton()
        with self.viewModel.transaction() as model:
            self.__setStyleWidget(model)
            startLevel = 1
            finalLevel = self.__battlePassController.getMaxLevel()
            self.__resetRewardsInterval(BattlePassConsts.REWARD_FREE,
                                        model.freeRewards, startLevel,
                                        finalLevel, self.__chosenChapter, True)
            self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                        model.paidRewards, startLevel,
                                        finalLevel, self.__chosenChapter, True)
            model.setShowReplaceRewardsAnimations(
                self.__showReplaceRewardAnimations)

    @replaceNoneKwargsModel
    def __onOffersUpdated(self, model=None):
        self.__updateRewardSelectButton(model=model)
        self.__updateRewardSelectButtons(model=model)

    def __onPurchaseLevels(self, _):
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = True

    def __getTooltipContentCreator(self):
        return {
            R.views.lobby.battle_pass.tooltips.BattlePassPointsView():
            self.__getBattlePassPointsTooltipContent,
            R.views.lobby.battle_pass.tooltips.BattlePassLockIconTooltipView():
            self.__getBattlePassLockIconTooltipContent
        }

    @replaceNoneKwargsModel
    def __setShowBuyAnimations(self, model=None):
        showAnimations = False
        if self.__battlePassController.isBought():
            settings = self.__settingsCore.serverSettings
            shownChapters = settings.getBPStorage().get(
                BattlePassStorageKeys.BUY_ANIMATION_WAS_SHOWN)
            chapter = 1 << self.__chosenChapter - 1
            if shownChapters & chapter == 0:
                showAnimations = True
                settings.saveInBPStorage({
                    BattlePassStorageKeys.BUY_ANIMATION_WAS_SHOWN:
                    shownChapters | chapter
                })
        model.setShowBuyAnimations(showAnimations)
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = False

    @staticmethod
    def __getBattlePassPointsTooltipContent(_=None):
        return BattlePassPointsTooltip()

    @staticmethod
    def __getBattlePassLockIconTooltipContent(_=None):
        return BattlePassLockIconTooltipView()

    def __showIntroVideo(self, onStart=False):
        settings = self.__settingsCore.serverSettings
        if onStart:
            if settings.getBPStorage().get(
                    BattlePassStorageKeys.INTRO_VIDEO_SHOWN):
                return False
            settings.saveInBPStorage(
                {BattlePassStorageKeys.INTRO_VIDEO_SHOWN: True})
        showBrowserOverlayView(getIntroVideoURL(), VIEW_ALIAS.BROWSER_OVERLAY)
        return True

    def __makeSeasonTimeText(self, timeStamp, seasonNum):
        day, month = self.__getDayMonth(timeStamp)
        return backport.text(_rBattlePass.progression.seasonText(),
                             seasonNum=int2roman(seasonNum),
                             endDay=str(day),
                             endMonth=backport.text(
                                 R.strings.menu.dateTime.months.num(month)()))

    def __showBattlePassBuyWindow(self, backCallback=None):
        from gui.impl.lobby.battle_pass.battle_pass_buy_view import BattlePassBuyWindow
        ctx = {'backCallback': backCallback}
        view = self.__gui.windowsManager.getViewByLayoutID(
            R.views.lobby.battle_pass.BattlePassBuyView())
        if view is None:
            window = BattlePassBuyWindow(ctx, self.getParentWindow())
            window.load()
        return

    def __showBattlePassBuyLevelsWindow(self, backCallback=None):
        from gui.impl.lobby.battle_pass.battle_pass_buy_levels_view import BattlePassBuyLevelWindow
        ctx = {'backCallback': backCallback}
        view = self.__gui.windowsManager.getViewByLayoutID(
            R.views.lobby.battle_pass.BattlePassBuyView())
        if view is None:
            window = BattlePassBuyLevelWindow(ctx, self.getParentWindow())
            window.load()
        return

    def __showStyleChoiceWindow(self):
        from gui.impl.lobby.battle_pass.battle_pass_3d_style_choice_view import BattlePass3dStyleChoiceWindow
        view = self.__gui.windowsManager.getViewByLayoutID(
            R.views.lobby.battle_pass.BattlePass3dStyleChoiceView())
        if view is None:
            window = BattlePass3dStyleChoiceWindow(self.getParentWindow())
            window.load()
        return

    def __onTakeClick(self, args):
        level = args.get('level')
        if not level:
            return
        self.__battlePassController.takeRewardForLevel(level)

    def __onTakeAllClick(self):
        self.__battlePassController.takeAllRewards()

    def __onOpenShopClick(self):
        showShop(getBattlePassCoinProductsUrl())

    def __onPointsInfoClick(self):
        showBattlePassHowToEarnPointsView(parent=self.getParentWindow())

    @replaceNoneKwargsModel
    def __updateWalletAvailability(self, status=None, model=None):
        model.setIsWalletAvailable(self.__wallet.isAvailable)

    @replaceNoneKwargsModel
    def __updateBalance(self, value=None, model=None):
        model.setBpcoinCount(self.__itemsCache.items.stats.bpcoin)

    @replaceNoneKwargsModel
    def __resetReplaceRewardAnimations(self, model=None):
        self.__showReplaceRewardAnimations = False
        model.setShowReplaceRewardsAnimations(
            self.__showReplaceRewardAnimations)

    @replaceNoneKwargsModel
    def __resetLevelAnimations(self, model=None):
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = False
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
class BattlePassProgressionsView(ViewImpl):
    __slots__ = ('__tooltipItems', '__viewActive', '__notifier', '__chapterID',
                 '__showReplaceRewardAnimations', '__specialTooltipItems')
    __settingsCore = dependency.descriptor(ISettingsCore)
    __battlePass = dependency.descriptor(IBattlePassController)
    __gui = dependency.descriptor(IGuiLoader)
    __itemsCache = dependency.descriptor(IItemsCache)
    __wallet = dependency.descriptor(IWalletController)
    ANIMATION_PURCHASE_LEVELS = 'animPurchaseLevels'
    ANIMATIONS = {ANIMATION_PURCHASE_LEVELS: False}

    def __init__(self, *args, **kwargs):
        settings = ViewSettings(
            R.views.lobby.battle_pass.BattlePassProgressionsView())
        settings.flags = ViewFlags.COMPONENT
        settings.model = BattlePassProgressionsViewModel()
        self.__tooltipItems = {}
        self.__specialTooltipItems = {}
        self.__viewActive = False
        self.__chapterID = kwargs.get(
            'chapterID') or self.__getDefaultChapterID()
        self.__showReplaceRewardAnimations = False
        self.__notifier = None
        super(BattlePassProgressionsView, self).__init__(settings)
        return

    @property
    def viewModel(self):
        return super(BattlePassProgressionsView, self).getViewModel()

    @createBackportTooltipDecorator()
    def createToolTip(self, event):
        return super(BattlePassProgressionsView, self).createToolTip(event)

    @createTooltipContentDecorator()
    def createToolTipContent(self, event, contentID):
        return super(BattlePassProgressionsView,
                     self).createToolTipContent(event, contentID)

    def getTooltipData(self, event):
        tooltipId = event.getArgument('tooltipId')
        if tooltipId is None:
            return
        else:
            tooltipData = self.__tooltipItems.get(tooltipId)
            return tooltipData if tooltipData is not None else self.__specialTooltipItems.get(
                tooltipId)

    def _getEvents(self):
        return (
            (self.viewModel.onActionClick,
             self.__onActionClick), (self.viewModel.onAboutClick,
                                     self.__onAboutClick),
            (self.viewModel.onClose,
             self.__onClose), (self.viewModel.widget3dStyle.onPreviewClick,
                               self.__onPreviewClick),
            (self.viewModel.widget3dStyle.onExtraPreviewClick,
             self.__onExtraPreviewClick), (self.viewModel.onTakeClick,
                                           self.__onTakeClick),
            (self.viewModel.onTakeAllClick,
             self.__onTakeAllClick), (self.viewModel.onOpenShopClick,
                                      self.__onOpenShopClick),
            (self.viewModel.onPointsInfoClick,
             self.__onPointsInfoClick), (self.viewModel.onFinishedAnimation,
                                         self.__resetReplaceRewardAnimations),
            (self.viewModel.onLevelsAnimationFinished,
             self.__resetLevelAnimations), (self.viewModel.onChapterChoice,
                                            self.__onChapterChoice),
            (self.viewModel.onBpcoinClick,
             self.__showCoinsShop), (self.viewModel.onBpbitClick,
                                     self.__showPointsShop),
            (self.viewModel.onTakeRewardsClick, self.__takeAllRewards),
            (self.__battlePass.onPointsUpdated,
             self.__onPointsUpdated), (self.__battlePass.onBattlePassIsBought,
                                       self.__onBattlePassBought),
            (self.__battlePass.onBattlePassSettingsChange,
             self.__onBattlePassSettingsChange),
            (self.__battlePass.onRewardSelectChange,
             self.__onRewardSelectChange), (self.__battlePass.onOffersUpdated,
                                            self.__onOffersUpdated),
            (self.__battlePass.onSelectTokenUpdated,
             self.__onSelectTokenUpdated), (self.__battlePass.onChapterChanged,
                                            self.__onChapterChanged),
            (self.__battlePass.onExtraChapterExpired,
             self.__onExtraChapterExpired),
            (self.__wallet.onWalletStatusChanged,
             self.__updateWalletAvailability), (g_playerEvents.onClientUpdated,
                                                self.__onBpBitUpdated))

    def _getListeners(self):
        return ((events.MissionsEvent.ON_TAB_CHANGED,
                 self.__onMissionsTabChanged, EVENT_BUS_SCOPE.LOBBY),
                (events.BattlePassEvent.AWARD_VIEW_CLOSE,
                 self.__onAwardViewClose),
                (events.BattlePassEvent.ON_PURCHASE_LEVELS,
                 self.__onPurchaseLevels, EVENT_BUS_SCOPE.LOBBY),
                (events.BattlePassEvent.BUYING_THINGS,
                 self.__updateBuyButtonState, EVENT_BUS_SCOPE.LOBBY))

    def _getCallbacks(self):
        return (('stats.bpcoin', self.__updateBalance), )

    def _onLoading(self, *args, **kwargs):
        super(BattlePassProgressionsView, self)._onLoading()
        self.__notifier = Notifiable()
        self.__notifier.addNotificator(
            PeriodicNotifier(self.__battlePass.getSeasonTimeLeft,
                             self.__updateTimer))
        self.__notifier.addNotificator(
            SimpleNotifier(self.__battlePass.getFinalOfferTimeLeft,
                           self.__updateTimer))
        self.__notifier.startNotification()
        self.__updateProgressData()
        self.__updateBuyButtonState()

    def _onLoaded(self, *args, **kwargs):
        super(BattlePassProgressionsView, self)._onLoaded(*args, **kwargs)
        self.__setShowBuyAnimations()

    def _finalize(self):
        SoundGroups.g_instance.playSound2D(
            backport.sound(R.sounds.bp_progress_bar_stop()))
        self.__tooltipItems = None
        self.__specialTooltipItems = None
        if self.__notifier is not None:
            self.__notifier.stopNotification()
            self.__notifier.clearNotification()
        super(BattlePassProgressionsView, self)._finalize()
        return

    def __onActionClick(self):
        self.__resetBuyAnimation()
        ctrl = self.__battlePass
        if ctrl.isChapterActive(self.__chapterID):
            if ctrl.isBought(chapterID=self.__chapterID):
                self.__showBuyLevelsWindow()
            else:
                self.__showBuyWindow()
        elif not ctrl.isChapterCompleted(self.__chapterID):
            ctrl.activateChapter(self.__chapterID)
        elif not ctrl.isBought(chapterID=self.__chapterID):
            self.__showBuyWindow()

    def __onAboutClick(self):
        self.__loadUrl(getExtraInfoPageURL() if self.__battlePass.
                       isExtraChapter(self.__chapterID) else getInfoPageURL())

    @staticmethod
    def __onClose():
        showHangar()

    @staticmethod
    def __loadUrl(url):
        showBrowserOverlayView(url, VIEW_ALIAS.BATTLE_PASS_BROWSER_VIEW)

    def __setBattlePassIntroShown(self):
        self.__settingsCore.serverSettings.saveInBPStorage(
            {BattlePassStorageKeys.INTRO_SHOWN: True})

    def __updateProgressData(self):
        with self.viewModel.transaction() as model:
            self.__setAwards(model)
            self.__updateData(model=model)
            self.__updateBalance(model=model)
            self.__updateWalletAvailability(model=model)

    def __setAwards(self, model):
        bpController = self.__battlePass
        self.__tooltipItems.clear()
        self.__specialTooltipItems.clear()
        if self.__battlePass.getRewardType(
                self.__chapterID) == FinalReward.STYLE:
            self.__setStyleWidget(model)
        elif self.__battlePass.getRewardType(
                self.__chapterID) == FinalReward.TANKMAN:
            self.__setCharacterWidget(model)
        model.levels.clearItems()
        minLevel, maxLevel = bpController.getChapterLevelInterval(
            self.__chapterID)
        freeBonuses = sorted(bpController.getAwardsInterval(
            self.__chapterID, minLevel, maxLevel,
            BattlePassConsts.REWARD_FREE).iteritems(),
                             key=itemgetter(0))
        paidBonuses = sorted(bpController.getAwardsInterval(
            self.__chapterID, minLevel, maxLevel,
            BattlePassConsts.REWARD_PAID).iteritems(),
                             key=itemgetter(0))
        for (level, freeBonus), (_, paidBonus) in zip(freeBonuses,
                                                      paidBonuses):
            isNeedToTakeFree, isChooseFreeRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_FREE, level)
            isNeedToTakePaid, isChoosePaidRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_PAID, level)
            levelModel = RewardLevelModel()
            levelModel.setLevel(level)
            levelModel.setIsRare(
                bpController.isRareLevel(self.__chapterID, level))
            levelModel.setIsFreeRewardChoiceEnabled(isChooseFreeRewardEnabled)
            levelModel.setIsPaidRewardChoiceEnabled(isChoosePaidRewardEnabled)
            levelModel.setLevelPoints(
                bpController.getLevelPoints(self.__chapterID, level - 1))
            levelModel.setNeedTakeFree(isNeedToTakeFree)
            levelModel.setNeedTakePaid(isNeedToTakePaid)
            realFreeAwards = self.__battlePass.replaceOfferByReward(freeBonus)
            packBonusModelAndTooltipData(realFreeAwards,
                                         levelModel.freeRewardItems,
                                         self.__tooltipItems)
            realPaidAwards = self.__battlePass.replaceOfferByReward(paidBonus)
            packBonusModelAndTooltipData(realPaidAwards,
                                         levelModel.paidRewardItems,
                                         self.__tooltipItems)
            model.levels.addViewModel(levelModel)

    def __setStyleWidget(self, model):
        style = getStyleForChapter(self.__chapterID)
        model.widget3dStyle.setStyleName(style.userName if style else '')
        model.widget3dStyle.setStyleId(style.id if style else 0)
        if style is not None:
            vehicleCD = getVehicleCDForStyle(style,
                                             itemsCache=self.__itemsCache)
            vehicle = getVehicleByIntCD(vehicleCD)
            fillVehicleInfo(model.widget3dStyle.vehicleInfo, vehicle)
        return

    def __setCharacterWidget(self, model):
        _, maxLevel = self.__battlePass.getChapterLevelInterval(
            self.__chapterID)
        freeRewards = self.__battlePass.getSingleAward(
            chapterId=self.__chapterID, level=maxLevel)
        characterBonus = findFirst(lambda b: b.getName() == 'tmanToken',
                                   freeRewards)
        if characterBonus is None:
            self.__clearChapterCharacter(model)
            return
        else:
            character = getTankmanInfo(characterBonus)
            if character is None:
                self.__clearChapterCharacter(model)
                return
            iconName, characterName, skills = getDataByTankman(character)
            skillsArray = Array()
            for skill in skills:
                skillsArray.addString(skill)

            model.chapterCharacter.setIcon(iconName)
            model.chapterCharacter.setTankman(characterName)
            model.chapterCharacter.setSkills(skillsArray)
            model.chapterCharacter.setTooltipId(
                TOOLTIPS_CONSTANTS.TANKMAN_NOT_RECRUITED)
            packSpecialTooltipData(TOOLTIPS_CONSTANTS.TANKMAN_NOT_RECRUITED,
                                   self.__specialTooltipItems,
                                   character.getRecruitID())
            return

    @staticmethod
    def __clearChapterCharacter(model):
        model.chapterCharacter.setIcon('')
        model.chapterCharacter.setTankman('')
        model.chapterCharacter.setSkills(Array())

    def __resetRewardsInterval(self,
                               model,
                               fromLevel,
                               toLevel,
                               replaceRewards=False):
        startLevel, finalLevel = self.__battlePass.getChapterLevelInterval(
            self.__chapterID)
        if fromLevel == toLevel:
            return
        fromLevel += 1
        if toLevel > finalLevel:
            toLevel = finalLevel
        for level in range(fromLevel, toLevel + 1):
            levelData = model.levels.getItem(level - startLevel)
            isNeedToTakeFree, isChooseFreeRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_FREE, level)
            if replaceRewards and levelData.getNeedTakeFree(
            ) and not isNeedToTakeFree:
                levelData.freeRewardItems.clearItems()
                awards = self.__battlePass.getSingleAward(
                    self.__chapterID, level, BattlePassConsts.REWARD_FREE)
                realAwards = self.__battlePass.replaceOfferByReward(awards)
                packBonusModelAndTooltipData(realAwards,
                                             levelData.freeRewardItems,
                                             self.__tooltipItems)
                self.__showReplaceRewardAnimations = True
            isNeedToTakePaid, isChoosePaidRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_PAID, level)
            if replaceRewards and levelData.getNeedTakePaid(
            ) and not isNeedToTakePaid:
                levelData.paidRewardItems.clearItems()
                awards = self.__battlePass.getSingleAward(
                    self.__chapterID, level, BattlePassConsts.REWARD_PAID)
                realAwards = self.__battlePass.replaceOfferByReward(awards)
                packBonusModelAndTooltipData(realAwards,
                                             levelData.paidRewardItems,
                                             self.__tooltipItems)
                self.__showReplaceRewardAnimations = True
            levelData.setNeedTakeFree(isNeedToTakeFree)
            levelData.setNeedTakePaid(isNeedToTakePaid)
            levelData.setIsFreeRewardChoiceEnabled(isChooseFreeRewardEnabled)
            levelData.setIsPaidRewardChoiceEnabled(isChoosePaidRewardEnabled)

        model.setShowReplaceRewardsAnimations(
            self.__showReplaceRewardAnimations)
        model.levels.invalidate()

    def __getRewardLevelState(self, awardType, level):
        bpController = self.__battlePass
        isNeedToTake = bpController.isNeedToTakeReward(self.__chapterID,
                                                       awardType, level)
        isChooseRewardEnabled = isNeedToTake and bpController.isChooseRewardEnabled(
            awardType, self.__chapterID, level)
        return (isNeedToTake, isChooseRewardEnabled)

    @replaceNoneKwargsModel
    def __updateData(self, model=None):
        self.__updateLevelState(model)
        isBattlePassBought = self.__battlePass.isBought(
            chapterID=self.__chapterID)
        model.setIsBattlePassPurchased(isBattlePassBought)
        model.setIsPaused(self.__battlePass.isPaused())
        model.setChapterState(
            _CHAPTER_STATES.get(
                self.__battlePass.getChapterState(self.__chapterID)))
        model.setFinalReward(
            self.__battlePass.getRewardType(self.__chapterID).value)
        model.setChapterID(self.__chapterID)
        model.setBpbitCount(
            self.__itemsCache.items.stats.dynamicCurrencies.get(
                CurrencyBP.BIT.value, 0))
        model.setIsBattlePassCompleted(self.__battlePass.isCompleted())
        model.setNotChosenRewardCount(
            self.__battlePass.getNotChosenRewardCount())
        model.setIsChooseRewardsEnabled(self.__battlePass.canChooseAnyReward())
        model.setIsExtra(self.__battlePass.isExtraChapter(self.__chapterID))
        model.setIsSeasonEndingSoon(isSeasonEndingSoon())
        model.setSeasonText(self.__makeSeasonTimeText())
        model.setHasExtra(self.__battlePass.hasExtra())
        self.__setExpirations(model)
        if self.__battlePass.getRewardType(
                self.__chapterID) == FinalReward.STYLE:
            self.__setStyleTaken(model)
        self.__updateRewardSelectButton(model=model)

    def __setExpirations(self, model):
        expireTimestamp = self.__battlePass.getChapterRemainingTime(
            self.__chapterID) if self.__battlePass.isExtraChapter(
                self.__chapterID) else self.__battlePass.getSeasonTimeLeft()
        model.setExpireTime(expireTimestamp)
        model.setExpireTimeStr(getFormattedTimeLeft(expireTimestamp))

    def __setStyleTaken(self, model):
        style = getStyleForChapter(self.__chapterID)
        vehicleCD = getVehicleCDForStyle(style, itemsCache=self.__itemsCache)
        vehicle = self.__itemsCache.items.getItemByCD(vehicleCD)
        model.setIsStyleTaken(style.isInInventory
                              or bool(style.installedCount(vehicle.intCD)))

    def __updateLevelState(self, model):
        previousBattlePassPointsSeen = AccountSettings.getSettings(
            LAST_BATTLE_PASS_POINTS_SEEN)
        previousChapterPoints = previousBattlePassPointsSeen.get(
            self.__chapterID, 0)
        previousFreePoints = previousBattlePassPointsSeen.get(
            _FREE_POINTS_INDEX, 0)
        currentChapterPoints = self.__battlePass.getPointsInChapter(
            self.__chapterID)
        previousLevel = self.__battlePass.getLevelByPoints(
            self.__chapterID, previousChapterPoints)
        previousPoints, _ = self.__battlePass.getProgressionByPoints(
            self.__chapterID, previousChapterPoints, previousLevel)
        previousLevel += 1
        currentLevel = self.__battlePass.getLevelByPoints(
            self.__chapterID, currentChapterPoints)
        currentPoints, _ = self.__battlePass.getProgressionByPoints(
            self.__chapterID, currentChapterPoints, currentLevel)
        currentLevel += 1
        finalLevel = self.__battlePass.getMaxLevelInChapter(self.__chapterID)
        currentLevel = currentLevel if currentLevel <= finalLevel else finalLevel
        freePointsInChapter = self.__battlePass.getFreePoints(
        ) + currentChapterPoints
        potentialLevel = self.__battlePass.getLevelByPoints(
            self.__chapterID, freePointsInChapter)
        freePointsInLevel, _ = self.__battlePass.getProgressionByPoints(
            self.__chapterID, freePointsInChapter, potentialLevel)
        potentialLevel += 1
        previousPotentialLevel = self.__battlePass.getLevelByPoints(
            self.__chapterID, previousFreePoints)
        previousFreePointsInLevel, _ = self.__battlePass.getProgressionByPoints(
            self.__chapterID, previousFreePoints, previousPotentialLevel)
        previousPotentialLevel += 1
        if self.__battlePass.isExtraChapter(self.__chapterID):
            freePointsInChapter = 0
            freePointsInLevel = 0
            potentialLevel = 0
            previousFreePoints = 0
            previousFreePointsInLevel = 0
            previousPotentialLevel = 0
        model.setPreviousPointsInChapter(previousChapterPoints)
        model.setPreviousPointsInLevel(previousPoints)
        model.setPreviousLevel(previousLevel)
        model.setCurrentPointsInChapter(currentChapterPoints)
        model.setCurrentPointsInLevel(currentPoints)
        model.setCurrentLevel(currentLevel)
        model.setFreePointsInChapter(freePointsInChapter)
        model.setFreePointsInLevel(freePointsInLevel)
        model.setPreviousFreePointsInChapter(previousFreePoints)
        model.setPreviousFreePointsInLevel(previousFreePointsInLevel)
        model.setPreviousPotentialLevel(previousPotentialLevel)
        model.setPotentialLevel(potentialLevel)
        previousBattlePassPointsSeen[self.__chapterID] = currentChapterPoints
        previousBattlePassPointsSeen[_FREE_POINTS_INDEX] = freePointsInChapter
        AccountSettings.setSettings(LAST_BATTLE_PASS_POINTS_SEEN,
                                    previousBattlePassPointsSeen)

    def __updateBuyButtonState(self, *_):
        bpController = self.__battlePass
        isBattlePassBought = bpController.isBought(chapterID=self.__chapterID)
        isActiveChapter = bpController.isChapterActive(self.__chapterID)
        isCompleted = bpController.isChapterCompleted(self.__chapterID)
        state = ButtonStates.HIDE
        if isActiveChapter:
            if not isBattlePassBought:
                state = ButtonStates.BUY
            else:
                state = ButtonStates.LEVEL
        elif not isCompleted:
            state = ButtonStates.ACTIVATE
        elif not isBattlePassBought:
            state = ButtonStates.BUY
        with self.viewModel.transaction() as model:
            model.setButtonState(state)

    @replaceNoneKwargsModel
    def __updateRewardSelectButton(self, model=None):
        model.setIsChooseDeviceEnabled(False)
        notChosenRewardCount = self.__battlePass.getNotChosenRewardCount()
        model.setIsChooseDeviceEnabled(self.__battlePass.canChooseAnyReward())
        model.setNotChosenRewardCount(notChosenRewardCount)

    @replaceNoneKwargsModel
    def __updateRewardSelectButtons(self, model=None):
        self.__resetRewardSelectButtons(model, MIN_LEVEL)

    def __resetRewardSelectButtons(self, model, fromLevel):
        startLevel, finalLevel = self.__battlePass.getChapterLevelInterval(
            self.__chapterID)
        if fromLevel <= startLevel:
            fromLevel = startLevel + 1
        for level in range(fromLevel, finalLevel + 1):
            item = model.levels.getItem(level - startLevel)
            _, isChooseFreeRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_FREE, level)
            _, isChoosePaidRewardEnabled = self.__getRewardLevelState(
                BattlePassConsts.REWARD_PAID, level)
            item.setIsFreeRewardChoiceEnabled(isChooseFreeRewardEnabled)
            item.setIsPaidRewardChoiceEnabled(isChoosePaidRewardEnabled)

        model.levels.invalidate()

    def __updateTimer(self):
        self.viewModel.setExpireTimeStr(
            getFormattedTimeLeft(self.__battlePass.getSeasonTimeLeft()))
        self.__updateBuyButtonState()

    def __onMissionsTabChanged(self, event):
        viewActive = event.ctx.get(
            'alias') == QUESTS_ALIASES.BATTLE_PASS_MISSIONS_VIEW_PY_ALIAS
        if self.__viewActive == viewActive and self.__viewActive:
            self.__clearSubViews()
        self.__viewActive = viewActive

    def __clearSubViews(self):
        def __isValidSubView(v):
            return v.viewFlags & ViewFlags.VIEW_TYPE_MASK == ViewFlags.LOBBY_TOP_SUB_VIEW and v.viewStatus in (
                ViewStatus.LOADED, ViewStatus.LOADING)

        for view in self.__gui.windowsManager.findViews(__isValidSubView):
            view.destroyWindow()

    def __onAwardViewClose(self):
        self.__setShowBuyAnimations()

    def __onBattlePassSettingsChange(self, *_):
        if not self.__battlePass.isChapterExists(self.__chapterID):
            showMissionsBattlePass(
                R.views.lobby.battle_pass.ChapterChoiceView())
            return
        if self.__battlePass.isPaused():
            showMissionsBattlePass()
            return
        if not (self.__battlePass.isEnabled()
                and self.__battlePass.isActive()):
            showHangar()
            return
        self.__updateProgressData()
        self.__updateBuyButtonState()

    def __onGoToChapter(self, args):
        chapter = args.get('chapterNumber')
        if chapter is None:
            return
        else:
            self.__chapterID = int(chapter)
            self.__updateProgressData()
            self.__updateBuyButtonState()
            return

    def __onPreviewClick(self, args):
        level = args.get('level')
        if level is None:
            return
        else:
            styleInfo = getStyleForChapter(self.__chapterID,
                                           battlePass=self.__battlePass)
            vehicleCD = getVehicleCDForStyle(styleInfo,
                                             itemsCache=self.__itemsCache)
            showBattlePassStyleProgressionPreview(vehicleCD,
                                                  styleInfo,
                                                  styleInfo.getDescription(),
                                                  self.__getPreviewCallback(),
                                                  chapterId=self.__chapterID,
                                                  styleLevel=int(level))
            return

    def __onExtraPreviewClick(self):
        styleInfo = getStyleForChapter(self.__chapterID,
                                       battlePass=self.__battlePass)
        vehicleCD = getVehicleCDForStyle(styleInfo,
                                         itemsCache=self.__itemsCache)
        itemsPack = (ItemPackEntry(type=ItemPackType.CREW_100, groupID=1), )
        showStylePreview(vehicleCD,
                         style=styleInfo,
                         topPanelData={
                             'linkage':
                             VEHPREVIEW_CONSTANTS.TOP_PANEL_TABS_LINKAGE,
                             'tabIDs': (TabID.VEHICLE, TabID.STYLE),
                             'currentTabID': TabID.STYLE
                         },
                         itemsPack=itemsPack,
                         backCallback=self.__getPreviewCallback())

    def __getPreviewCallback(self):
        return partial(showMissionsBattlePass,
                       R.views.lobby.battle_pass.BattlePassProgressionsView(),
                       self.__chapterID)

    def __onPointsUpdated(self):
        with self.viewModel.transaction() as model:
            newChapter = self.__battlePass.getCurrentChapterID()
            newFreePoints = self.__battlePass.getFreePoints()
            oldFreePoints = model.getFreePointsInChapter()
            if model.getChapterID(
            ) != newChapter and newFreePoints == oldFreePoints:
                return
            oldPoints = model.getCurrentPointsInChapter()
            oldLevel = self.__battlePass.getLevelByPoints(
                self.__chapterID, oldPoints)
            newPoints = self.__battlePass.getPointsInChapter(self.__chapterID)
            newLevel = self.__battlePass.getLevelInChapter(self.__chapterID)
            self.__resetRewardsInterval(model, oldLevel, newLevel)
            self.__updateData(model=model)
        isDrawPoints = newLevel < oldLevel or newPoints < oldPoints or newFreePoints > oldFreePoints
        if isDrawPoints:
            model.setShowLevelsAnimations(
                self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.__updateBuyButtonState()

    def __updateTooltipsSingleCard(self, rewards, model):
        tooltipIds = [
            item.getTooltipId() for item in model.rewardItems.getItems()
        ]
        tooltipIds = tooltipIds[:len(rewards)]
        changeBonusTooltipData(zip(rewards, tooltipIds), self.__tooltipItems)

    def __onBattlePassBought(self):
        with self.viewModel.transaction() as model:
            finalLevel = self.__battlePass.getMaxLevelInChapter(
                self.__chapterID)
            self.__resetRewardsInterval(model, MIN_LEVEL, finalLevel)
            self.__updateData(model=model)
        self.__updateBuyButtonState()

    def __onRewardSelectChange(self):
        self.__updateRewardSelectButton()
        with self.viewModel.transaction() as model:
            if self.__battlePass.getRewardType(
                    self.__chapterID) == FinalReward.STYLE:
                self.__setStyleWidget(model)
            elif self.__battlePass.getRewardType(
                    self.__chapterID) == FinalReward.TANKMAN:
                self.__setCharacterWidget(model)
            finalLevel = self.__battlePass.getMaxLevelInChapter(
                self.__chapterID)
            self.__resetRewardsInterval(model,
                                        MIN_LEVEL,
                                        finalLevel,
                                        replaceRewards=True)

    def __onSelectTokenUpdated(self):
        def __viewsPredicate(view):
            return view.layoutID in (
                R.views.lobby.battle_pass.BattlePassAwardsView(),
                R.views.lobby.battle_pass.RewardsSelectionView())

        if self.__gui.windowsManager.findViews(__viewsPredicate):
            return
        self.__updateRewardSelectButton()
        with self.viewModel.transaction() as model:
            if self.__battlePass.getRewardType(
                    self.__chapterID) == FinalReward.STYLE:
                self.__setStyleWidget(model)
            elif self.__battlePass.getRewardType(
                    self.__chapterID) == FinalReward.TANKMAN:
                self.__setCharacterWidget(model)
            model.setNotChosenRewardCount(
                self.__battlePass.getNotChosenRewardCount())
            model.setIsChooseRewardsEnabled(
                self.__battlePass.canChooseAnyReward())
            finalLevel = self.__battlePass.getMaxLevelInChapter(
                self.__chapterID)
            self.__resetRewardsInterval(model,
                                        MIN_LEVEL,
                                        finalLevel,
                                        replaceRewards=False)

    def __onChapterChanged(self):
        if self.__chapterID not in self.__battlePass.getChapterIDs():
            return
        self.__updateBuyButtonState()
        self.__updateProgressData()

    @staticmethod
    def __onExtraChapterExpired():
        showMissionsBattlePass(R.views.lobby.battle_pass.ChapterChoiceView())

    @replaceNoneKwargsModel
    def __onOffersUpdated(self, model=None):
        self.__updateRewardSelectButton(model=model)
        self.__updateRewardSelectButtons(model=model)

    def __onPurchaseLevels(self, _):
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = True

    @replaceNoneKwargsModel
    def __setShowBuyAnimations(self, model=None):
        showAnimations = False
        isBattlePassBought = self.__battlePass.isBought(
            chapterID=self.__chapterID)
        if isBattlePassBought:
            showAnimations = updateBuyAnimationFlag(
                chapterID=self.__chapterID,
                settingsCore=self.__settingsCore,
                battlePass=self.__battlePass)
            model.setIsBattlePassPurchased(isBattlePassBought)
        model.setShowBuyAnimations(showAnimations)
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = False

    def __getDefaultChapterID(self):
        return self.__battlePass.getCurrentChapterID() or first(
            sorted(self.__battlePass.getChapterIDs(),
                   cmp=chaptersIDsComparator))

    def __showIntroVideo(self, onStart=False):
        settings = self.__settingsCore.serverSettings
        if onStart:
            if settings.getBPStorage().get(
                    BattlePassStorageKeys.INTRO_VIDEO_SHOWN):
                return False
            settings.saveInBPStorage(
                {BattlePassStorageKeys.INTRO_VIDEO_SHOWN: True})
        showBrowserOverlayView(getIntroVideoURL(), VIEW_ALIAS.BROWSER_OVERLAY)
        return True

    def __makeSeasonTimeText(self):
        if self.__battlePass.isExtraChapter(self.__chapterID):
            endTimestamp = self.__battlePass.getChapterExpiration(
                self.__chapterID)
            endStringRes = _bpRes.progression.season.end.extra
        elif self.__battlePass.isSeasonFinished():
            endTimestamp = 0
            endStringRes = _bpRes.commonProgression.body.ended
        else:
            endTimestamp = self.__battlePass.getSeasonFinishTime()
            endStringRes = _bpRes.progression.season.end.normal
        endTime = time_utils.getTimeStructInLocal(endTimestamp)
        return backport.text(
            endStringRes(),
            seasonNum=int2roman(self.__battlePass.getSeasonNum()),
            endDay=endTime.tm_mday,
            endMonth=backport.text(
                R.strings.menu.dateTime.months.num(endTime.tm_mon)()),
            endTime=formatDate('%H:%M', endTimestamp))

    def __showBuyWindow(self, backCallback=None):
        showBattlePassBuyWindow({'backCallback': backCallback})

    def __showBuyLevelsWindow(self, backCallback=None):
        showBattlePassBuyLevelWindow({
            'backCallback': backCallback,
            'chapterID': self.__chapterID
        })

    def __onTakeClick(self, args):
        level = args.get('level')
        if not level:
            return
        self.__battlePass.takeRewardForLevel(self.__chapterID, level)

    def __onTakeAllClick(self):
        self.__battlePass.takeAllRewards()

    @staticmethod
    def __onOpenShopClick():
        showShop(getBattlePassCoinProductsUrl())

    def __onPointsInfoClick(self):
        showBattlePassHowToEarnPointsView(parent=self.getParentWindow(),
                                          chapterID=self.__chapterID)

    @staticmethod
    def __onChapterChoice():
        showMissionsBattlePass(R.views.lobby.battle_pass.ChapterChoiceView())

    @replaceNoneKwargsModel
    def __updateWalletAvailability(self, status=None, model=None):
        model.setIsWalletAvailable(self.__wallet.isAvailable)

    @replaceNoneKwargsModel
    def __updateBalance(self, value=None, model=None):
        model.setBpcoinCount(self.__itemsCache.items.stats.bpcoin)

    @replaceNoneKwargsModel
    def __resetReplaceRewardAnimations(self, model=None):
        self.__showReplaceRewardAnimations = False
        model.setShowReplaceRewardsAnimations(
            self.__showReplaceRewardAnimations)

    @replaceNoneKwargsModel
    def __resetLevelAnimations(self, model=None):
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = False
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])

    @replaceNoneKwargsModel
    def __resetBuyAnimation(self, model=None):
        model.setShowBuyAnimations(False)
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])

    def __onBpBitUpdated(self, *data):
        if data[0].get('cache', {}).get('dynamicCurrencies',
                                        {}).get(CurrencyBP.BIT.value, ''):
            with self.viewModel.transaction() as model:
                model.setBpbitCount(
                    self.__itemsCache.items.stats.dynamicCurrencies.get(
                        CurrencyBP.BIT.value, 0))

    def __takeAllRewards(self):
        self.__battlePass.takeAllRewards()

    @staticmethod
    def __showCoinsShop():
        showShop(getBattlePassCoinProductsUrl())

    @staticmethod
    def __showPointsShop():
        showShop(getBattlePassPointsProductsUrl())
コード例 #15
0
class BattlePassProgressionsView(ViewImpl):
    __slots__ = ('__tooltipItems', '__viewActive', '__tooltipContentCreator',
                 '__showDummyCallback', '__showViewCallback', '__notifier')
    __settingsCore = dependency.descriptor(ISettingsCore)
    __battlePassController = dependency.descriptor(IBattlePassController)
    __gui = dependency.descriptor(IGuiLoader)
    __itemsCache = dependency.descriptor(IItemsCache)
    ANIMATION_PURCHASE_LEVELS = 'animPurchaseLevels'
    ANIMATIONS = {ANIMATION_PURCHASE_LEVELS: False}

    def __init__(self,
                 showDummyCallback,
                 showViewCallback,
                 flags=ViewFlags.VIEW):
        settings = ViewSettings(
            R.views.lobby.battle_pass.BattlePassProgressionsView())
        settings.flags = flags
        settings.model = BattlePassProgressionsViewModel()
        self.__showDummyCallback = showDummyCallback
        self.__showViewCallback = showViewCallback
        self.__tooltipItems = {}
        self.__viewActive = False
        self.__tooltipContentCreator = self.__getTooltipContentCreator()
        super(BattlePassProgressionsView, self).__init__(settings)

    @property
    def viewModel(self):
        return super(BattlePassProgressionsView, self).getViewModel()

    def createToolTip(self, event):
        if event.contentID == R.views.common.tooltip_window.backport_tooltip_content.BackportTooltipContent(
        ):
            tooltipData = self.__getTooltipData(event)
            if tooltipData is None:
                return
            isGFTooltip = isUndefinedBonusTooltipData(tooltipData)
            if isGFTooltip:
                window = createUndefinedBonusTooltipWindow(
                    tooltipData, self.getParentWindow())
            else:
                window = backport.BackportTooltipWindow(
                    tooltipData, self.getParentWindow())
            if window is None:
                return
            window.load()
            if isGFTooltip:
                window.move(event.mouse.positionX, event.mouse.positionY)
            return window
        else:
            return super(BattlePassProgressionsView, self).createToolTip(event)

    def createToolTipContent(self, event, contentID):
        tooltipContentCreator = self.__tooltipContentCreator.get(contentID)
        if tooltipContentCreator is None:
            raise SoftException(
                'Incorrect tooltip type with contentID {}'.format(contentID))
        return tooltipContentCreator(event)

    def setSubTab(self, subTab):
        self.__clearSubViews()
        if subTab == BattlePassProgressionSubTabs.VOTING_TAB:
            showBattleVotingResultWindow(parent=self.getParentWindow())
        elif subTab == BattlePassProgressionSubTabs.BUY_TAB:
            self.__showBattlePassBuyWindow()
        elif subTab == BattlePassProgressionSubTabs.BUY_TAB_FOR_SHOP:
            self.__showBattlePassBuyWindow(backCallback=showShop)

    def _onLoading(self, *args, **kwargs):
        super(BattlePassProgressionsView, self)._onLoading()
        self.__addListeners()
        self.__notifier = Notifiable()
        self.__notifier.addNotificator(
            PeriodicNotifier(self.__battlePassController.getSeasonTimeLeft,
                             self.__updateTimer))
        self.__notifier.addNotificator(
            PeriodicNotifier(
                self.__battlePassController.getSellAnyLevelsUnlockTimeLeft,
                self.__updateTimer))
        self.__notifier.addNotificator(
            SimpleNotifier(self.__battlePassController.getFinalOfferTimeLeft,
                           self.__updateTimer))
        self.__notifier.startNotification()
        self.__updateProgressData()
        self.__updateBuyButtonState()
        self.__updateExtrasAndVotingButtons()

    def _finalize(self):
        super(BattlePassProgressionsView, self)._finalize()
        self.__removeListeners()
        self.__showDummyCallback = None
        self.__showViewCallback = None
        self.__tooltipItems = None
        if self.viewModel.getShowIntro():
            self.__setBattlePassIntroShown()
        self.__notifier.stopNotification()
        self.__notifier.clearNotification()
        return

    def __showDummy(self):
        if self.__showDummyCallback is not None:
            self.__showDummyCallback(True)
            with self.viewModel.transaction() as model:
                model.setIsPaused(True)
        return

    def __hideDummy(self):
        if self.__showDummyCallback is not None:
            self.__showDummyCallback(False)
            with self.viewModel.transaction() as model:
                model.setIsPaused(False)
        return

    def __onBuyClick(self):
        if self.__battlePassController.isSellAnyLevelsUnlocked():
            self.__setBuyButtonHintShown()
            self.__updateBuyButtonState()
        with self.viewModel.transaction() as model:
            model.setShowBuyAnimations(False)
            model.setShowLevelsAnimations(
                self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.setSubTab(BattlePassProgressionSubTabs.BUY_TAB)

    def __onVotingResultClick(self):
        self.setSubTab(BattlePassProgressionSubTabs.VOTING_TAB)

    def __onIntroCloseClick(self):
        self.viewModel.setShowIntro(False)
        self.__setBattlePassIntroShown()

    def __onExtrasClick(self):
        self.__loadUrl(getExtrasVideoPageURL())

    def __onAboutClick(self):
        self.__loadUrl(getInfoPageURL())

    @staticmethod
    def __onBuyVehicleClick():
        showShop(shop_helpers.getBuyVehiclesUrl())

    @staticmethod
    def __onClose():
        showHangar()

    @staticmethod
    def __loadUrl(url):
        showBrowserOverlayView(url, VIEW_ALIAS.BATTLE_PASS_BROWSER_VIEW)

    def __showIntro(self):
        with self.viewModel.transaction() as tx:
            self.__showIntroVideo(onStart=True)
            tx.setShowIntro(self.__isFirstShowView())
            self.__setShowBuyAnimations(model=tx)

    def __isFirstShowView(self):
        return not self.__settingsCore.serverSettings.getBPStorage().get(
            BattlePassStorageKeys.INTRO_SHOWN)

    def __setBattlePassIntroShown(self):
        self.__settingsCore.serverSettings.saveInBPStorage(
            {BattlePassStorageKeys.INTRO_SHOWN: True})

    def __updateProgressData(self):
        isPaused = self.__battlePassController.isPaused()
        if isPaused:
            self.__showDummy()
        elif self.__battlePassController.isOffSeasonEnable():
            self.__hideDummy()
            self.__updateOffSeason()
        else:
            self.__hideDummy()
            self.__showIntro()
            with self.viewModel.transaction() as model:
                self.__setAwards(model)
                self.__setCurrentLevelState(model=model)

    def __getTooltipData(self, event):
        tooltipId = event.getArgument('tooltipId')
        return None if tooltipId is None else self.__tooltipItems.get(
            tooltipId)

    def __setAwards(self, model):
        self.__tooltipItems.clear()
        self.__setRewardsList(BattlePassConsts.REWARD_FREE, model.freeRewards)
        self.__setRewardsList(BattlePassConsts.REWARD_PAID, model.paidRewards)
        self.__setRewardsList(BattlePassConsts.REWARD_POST, model.postRewards)
        self.__setFinalReward(model)
        self.__setMedalReward(model)

    def __setMedalReward(self, model):
        maxLevel = self.__battlePassController.getMaxLevel()
        freeRewards = self.__battlePassController.getSingleAward(maxLevel)
        dossierBonus = findFirst(lambda b: b.getName() == 'dossier',
                                 freeRewards)
        if dossierBonus is None:
            return
        else:
            randomStats = self.__itemsCache.items.getAccountDossier(
            ).getRandomStats()
            achievements = dossierBonus.getAchievementsFromDossier(randomStats)
            if not achievements:
                return
            model.setHaveMedalReward(achievements[-1].isInDossier())
            model.medalReward.clearItems()
            packBonusModelAndTooltipData([dossierBonus], model.medalReward,
                                         self.__tooltipItems)
            return

    def __setFinalReward(self, model):
        finalLevel = self.__battlePassController.getMaxLevel()
        freeReward, paidReward = self.__battlePassController.getSplitFinalAwards(
        )
        freeModel = model.freeRewards.getItem(finalLevel - 1)
        paidModel = model.paidRewards.getItem(finalLevel - 1)
        self.__removeMedals(freeModel)
        packBonusModelAndTooltipData(freeReward, freeModel.rewardItems,
                                     self.__tooltipItems)
        packBonusModelAndTooltipData(paidReward, paidModel.rewardItems,
                                     self.__tooltipItems)

    @staticmethod
    def __removeMedals(model):
        freeItems = model.rewardItems.getItems()
        indexes = []
        for index, item in enumerate(freeItems):
            if item.getName() == 'dossier_achievement':
                indexes.append(index)

        model.rewardItems.removeItemByIndexes(indexes)

    def __setRewardsList(self, awardType, model):
        model.clearItems()
        bonuses = sorted(
            self.__battlePassController.getAwardsList(awardType).iteritems(),
            key=itemgetter(0))
        curLevel = self.__battlePassController.getCurrentLevel()
        curState = self.__battlePassController.getState()
        isBattlePassBought = self.__battlePassController.isBought()
        state = BattlePassState.POST if awardType == BattlePassConsts.REWARD_POST else BattlePassState.BASE
        isBase = state == BattlePassState.BASE
        for level, award in bonuses:
            item = RewardLevelModel()
            item.setLevel(level)
            item.setLevelPoints(
                self.__battlePassController.getLevelPoints(level - 1, isBase))
            item.setIsRare(
                self.__battlePassController.isRareLevel(level, isBase))
            isReached = curLevel >= level and state == curState or curState > state
            if awardType == BattlePassConsts.REWARD_PAID and not isBattlePassBought:
                levelState = RewardLevelModel.DISABLED
            else:
                levelState = RewardLevelModel.REACHED if isReached else RewardLevelModel.NOT_REACHED
            item.setState(levelState)
            packBonusModelAndTooltipData(award, item.rewardItems,
                                         self.__tooltipItems)
            model.addViewModel(item)

        model.invalidate()

    def __resetRewardsInterval(self, awardType, model, fromLevel, toLevel):
        curLevel = self.__battlePassController.getCurrentLevel()
        curState = self.__battlePassController.getState()
        isBattlePassBought = self.__battlePassController.isBought()
        state = BattlePassState.POST if awardType == BattlePassConsts.REWARD_POST else BattlePassState.BASE
        maxPostLevel = self.__battlePassController.getMaxLevel(False)
        if toLevel >= maxPostLevel and state == BattlePassState.POST:
            toLevel = maxPostLevel - 1
        for level in range(fromLevel, toLevel + 1):
            item = model.getItem(level)
            isReached = curLevel >= level and state == curState or curState > state
            if awardType == BattlePassConsts.REWARD_PAID and not isBattlePassBought:
                levelState = RewardLevelModel.DISABLED
            else:
                levelState = RewardLevelModel.REACHED if isReached else RewardLevelModel.NOT_REACHED
            item.setState(levelState)

        model.invalidate()

    @replaceNoneKwargsModel
    def __setCurrentLevelState(self, model=None):
        previousTotalPoints = AccountSettings.getSettings(
            LAST_BATTLE_PASS_POINTS_SEEN)
        previousState, previousLevel = self.__battlePassController.getLevelByPoints(
            previousTotalPoints)
        previousPoints, _ = self.__battlePassController.getProgressionByPoints(
            previousTotalPoints, previousState, previousLevel)
        previousLevel += 1
        currentTotalPoints = self.__battlePassController.getCurrentPoints()
        currentState = self.__battlePassController.getState()
        currentLevel = self.__battlePassController.getCurrentLevel() + 1
        AccountSettings.setSettings(LAST_BATTLE_PASS_POINTS_SEEN,
                                    currentTotalPoints)
        if previousState != currentState:
            if not (previousState == BattlePassState.POST
                    and currentState == BattlePassState.COMPLETED):
                previousLevel = 1
                previousTotalPoints = 0
        if previousTotalPoints > currentTotalPoints or previousLevel > currentLevel:
            previousState = BattlePassState.BASE
            previousLevel = 1
            previousTotalPoints = 0
        previousLevel = min(
            previousLevel,
            self.__battlePassController.getMaxLevel(
                previousState == BattlePassState.BASE))
        currentLevel = min(
            currentLevel,
            self.__battlePassController.getMaxLevel(
                currentState == BattlePassState.BASE))
        if previousTotalPoints > 0:
            if previousState == BattlePassState.POST:
                previousTotalPoints -= self.__battlePassController.getMaxPoints(
                )
            elif previousState == BattlePassState.COMPLETED:
                previousTotalPoints = self.__battlePassController.getMaxPoints(
                    False)
        if currentState == BattlePassState.POST:
            currentTotalPoints -= self.__battlePassController.getMaxPoints()
        elif currentState == BattlePassState.COMPLETED:
            currentTotalPoints = self.__battlePassController.getMaxPoints(
                False)
        currentPoints, levelPoints = self.__battlePassController.getLevelProgression(
        )
        isBattlePassBought = self.__battlePassController.isBought()
        model.setTitle(
            backport.text(R.strings.battle_pass_2020.progression.title()))
        model.setPreviousAllPoints(previousTotalPoints)
        model.setPreviousPoints(previousPoints)
        model.setPreviousLevel(previousLevel)
        model.setCurrentAllPoints(currentTotalPoints)
        model.setCurrentPoints(currentPoints)
        model.setTotalPoints(levelPoints)
        model.setCurrentLevel(currentLevel)
        model.setMaxLevelBase(self.__battlePassController.getMaxLevel())
        model.setMaxLevelPost(self.__battlePassController.getMaxLevel(False))
        model.setIsPostProgression(currentState != BattlePassState.BASE)
        model.setIsBattlePassPurchased(isBattlePassBought)
        isPaused = self.__battlePassController.isPaused()
        canBuy = self.__battlePassController.isActive(
        ) or currentLevel > 0 and not isPaused
        model.setIsPaused(isPaused)
        model.setCanBuy(canBuy)
        model.setSeasonTimeLeft(
            getFormattedTimeLeft(
                self.__battlePassController.getSeasonTimeLeft()))
        model.setCanPlayerParticipate(
            self.__battlePassController.canPlayerParticipate())
        if self.__battlePassController.isSeasonFinished():
            model.setSeasonTime(
                backport.text(
                    R.strings.battle_pass_2020.commonProgression.body.ended()))
        else:
            timeStart = self.__battlePassController.getSeasonStartTime()
            timeEnd = self.__battlePassController.getSeasonFinishTime()
            timePeriod = '{} - {}'.format(self.__makeSeasonTimeText(timeStart),
                                          self.__makeSeasonTimeText(timeEnd))
            model.setSeasonTime(timePeriod)

    def __updateOffSeason(self):
        prevSeasonStats = self.__battlePassController.getLastFinishedSeasonStats(
        )
        if prevSeasonStats is None:
            self.__showDummy()
            _logger.warning('There is not previous season stats')
            return
        else:
            prevOtherStats = prevSeasonStats.otherStats
            prevSeasonHistory = getSeasonHistory(prevSeasonStats.seasonID)
            if prevSeasonHistory is None:
                self.__showDummy()
                _logger.warning('There is not previous season %r history',
                                prevSeasonStats.seasonID)
                return
            sumPoints = sum(prevSeasonStats.vehPoints)
            if prevOtherStats.maxBase == prevSeasonHistory.maxBaseLevel:
                currentLevel = prevOtherStats.maxPost
                state = BattlePassState.POST
            else:
                currentLevel = prevOtherStats.maxBase
                state = BattlePassState.BASE
            if prevOtherStats.maxPost >= prevSeasonHistory.maxPostLevel:
                state = BattlePassState.COMPLETED
            with self.viewModel.transaction() as tx:
                tx.setShowOffSeason(True)
                offSeason = tx.offSeason
                offSeason.setLevel(currentLevel + 1)
                offSeason.setSeasonName(
                    backport.text(
                        R.strings.battle_pass_2020.offSeason.title()))
                offSeason.setHasBattlePass(
                    self.__battlePassController.isBought(
                        prevSeasonStats.seasonID))
                offSeason.setIsPostProgression(state != BattlePassState.BASE)
                offSeason.setIsPostProgressionCompleted(
                    state == BattlePassState.COMPLETED)
                offSeason.setIsEnabled(sumPoints > 0)
                for vehCD in prevSeasonHistory.rewardVehicles:
                    vehicle = self.__itemsCache.items.getItemByCD(vehCD)
                    vehicleBackgroundPosition = getVehicleBackgroundPosition(
                        vehCD)
                    if vehicleBackgroundPosition == BackgroundPositions.LEFT:
                        offSeason.setLeftVehicle(vehicle.userName)
                    if vehicleBackgroundPosition == BackgroundPositions.RIGHT:
                        offSeason.setRightVehicle(vehicle.userName)

                self.__updateVotingResult(model=tx)
            return

    @replaceNoneKwargsModel
    def __updateVotingResult(self, model=None):
        votingRequester = self.__battlePassController.getVotingRequester()
        prevSeasonStats = self.__battlePassController.getLastFinishedSeasonStats(
        )
        if prevSeasonStats is None:
            return
        else:
            availableService, votingResult = votingRequester.getVotingResult(
                prevSeasonStats.seasonID)
            isFailedService = not availableService or not votingResult
            offSeason = model.offSeason
            offSeason.setIsFailedService(isFailedService)
            if len(votingResult) != 2:
                _logger.error('Incorrect voting results - %s', votingResult)
                if len(votingResult) > 2:
                    return
                _logger.error('Trying to build results from history')
                prevSeasonHistory = getSeasonHistory(prevSeasonStats.seasonID)
                for vehCD in prevSeasonHistory.rewardVehicles:
                    if vehCD not in votingResult:
                        votingResult[vehCD] = 0

            selectedVehCD = self.__getSelectedVoteOptionFromTokens(
                prevSeasonStats.seasonID, votingResult.keys())
            winVehCD, _ = max(votingResult.iteritems(), key=itemgetter(1))
            if not selectedVehCD:
                offSeason.setVoteStatus(offSeason.NOT_VOTE)
            elif winVehCD == selectedVehCD:
                offSeason.setVoteStatus(offSeason.WIN_VOTE)
            else:
                offSeason.setVoteStatus(offSeason.LOSE_VOTE)
            for vehCD, voices in votingResult.iteritems():
                vehicleArtPosition = getVehicleBackgroundPosition(vehCD)
                if vehicleArtPosition == BackgroundPositions.LEFT:
                    offSeason.setLeftPoints(voices)
                if vehicleArtPosition == BackgroundPositions.RIGHT:
                    offSeason.setRightPoints(voices)

            return

    def __onVotingResultsUpdated(self):
        self.__updateVotingResult()

    def __updateBuyButtonState(self):
        sellAnyLevelsUnlocked = self.__battlePassController.isSellAnyLevelsUnlocked(
        )
        disableBuyButton = not sellAnyLevelsUnlocked and self.__battlePassController.getBoughtLevels(
        ) > 0
        showBubble = sellAnyLevelsUnlocked and not self.__isBuyButtonHintShown(
        ) and isCurrentBattlePassStateBase()
        isVisible = isCurrentBattlePassStateBase(
        ) or not self.__battlePassController.isBought()
        sellAnyLevelsUnlockTimeLeft = ''
        if disableBuyButton:
            sellAnyLevelsUnlockTimeLeft = getFormattedTimeLeft(
                self.__battlePassController.getSellAnyLevelsUnlockTimeLeft())
        with self.viewModel.transaction() as model:
            model.setIsFinalOfferTime(isSeasonEndingSoon())
            model.setSeasonTimeLeft(
                getFormattedTimeLeft(
                    self.__battlePassController.getSeasonTimeLeft()))
            model.setSellAnyLevelsUnlockTimeLeft(sellAnyLevelsUnlockTimeLeft)
            model.setShowBuyButtonBubble(showBubble)
            model.setIsVisibleBuyButton(isVisible)

    def __updateExtrasAndVotingButtons(self):
        with self.viewModel.transaction() as tx:
            tx.setHighlightVoting(isNeededToVote())
            tx.setIsPlayerVoted(self.__battlePassController.isPlayerVoted())

    def __updateTimer(self):
        self.viewModel.setSeasonTimeLeft(
            getFormattedTimeLeft(
                self.__battlePassController.getSeasonTimeLeft()))
        self.__updateBuyButtonState()

    def __isBuyButtonHintShown(self):
        return self.__settingsCore.serverSettings.getBPStorage().get(
            BattlePassStorageKeys.BUY_BUTTON_HINT_IS_SHOWN)

    def __setBuyButtonHintShown(self):
        self.__settingsCore.serverSettings.saveInBPStorage(
            {BattlePassStorageKeys.BUY_BUTTON_HINT_IS_SHOWN: True})

    def __addListeners(self):
        model = self.viewModel
        model.onBuyClick += self.__onBuyClick
        model.onVotingResultClick += self.__onVotingResultClick
        model.onExtrasClick += self.__onExtrasClick
        model.onAboutClick += self.__onAboutClick
        model.onViewLoaded += self.__showViewCallback
        model.onClose += self.__onClose
        model.intro.onClose += self.__onIntroCloseClick
        model.intro.onVideo += self.__showIntroVideo
        model.onBuyVehicleClick += self.__onBuyVehicleClick
        self.__battlePassController.onPointsUpdated += self.__onPointsUpdated
        self.__battlePassController.onVoted += self.__onVoted
        self.__battlePassController.onBattlePassIsBought += self.__onBattlePassBought
        self.__battlePassController.onUnlimitedPurchaseUnlocked += self.__updateBuyButtonState
        self.__battlePassController.getVotingRequester(
        ).onVotingResultsUpdated += self.__onVotingResultsUpdated
        self.__battlePassController.onBattlePassSettingsChange += self.__onBattlePassSettingsChange
        g_eventBus.addListener(events.MissionsEvent.ON_TAB_CHANGED,
                               self.__onMissionsTabChanged,
                               EVENT_BUS_SCOPE.LOBBY)
        g_eventBus.addListener(events.FocusEvent.COMPONENT_FOCUSED,
                               self.__onFocus)
        g_eventBus.addListener(events.BattlePassEvent.ON_PURCHASE_LEVELS,
                               self.__onPurchaseLevels, EVENT_BUS_SCOPE.LOBBY)

    def __removeListeners(self):
        model = self.viewModel
        model.onBuyClick -= self.__onBuyClick
        model.onVotingResultClick -= self.__onVotingResultClick
        model.onExtrasClick -= self.__onExtrasClick
        model.onAboutClick -= self.__onAboutClick
        model.onViewLoaded -= self.__showViewCallback
        model.onClose -= self.__onClose
        model.intro.onClose -= self.__onIntroCloseClick
        model.intro.onVideo -= self.__showIntroVideo
        model.onBuyVehicleClick -= self.__onBuyVehicleClick
        self.__battlePassController.onPointsUpdated -= self.__onPointsUpdated
        self.__battlePassController.onVoted -= self.__onVoted
        self.__battlePassController.onBattlePassIsBought -= self.__onBattlePassBought
        self.__battlePassController.onUnlimitedPurchaseUnlocked -= self.__updateBuyButtonState
        self.__battlePassController.getVotingRequester(
        ).onVotingResultsUpdated -= self.__onVotingResultsUpdated
        self.__battlePassController.onBattlePassSettingsChange -= self.__onBattlePassSettingsChange
        g_eventBus.removeListener(events.MissionsEvent.ON_TAB_CHANGED,
                                  self.__onMissionsTabChanged,
                                  EVENT_BUS_SCOPE.LOBBY)
        g_eventBus.removeListener(events.FocusEvent.COMPONENT_FOCUSED,
                                  self.__onFocus)
        g_eventBus.removeListener(events.BattlePassEvent.ON_PURCHASE_LEVELS,
                                  self.__onPurchaseLevels,
                                  EVENT_BUS_SCOPE.LOBBY)

    @staticmethod
    def __getDayMonth(timeStamp):
        timeStruct = time_utils.getTimeStructInUTC(timeStamp)
        return (timeStruct.tm_mday, timeStruct.tm_mon)

    def __onMissionsTabChanged(self, event):
        viewActive = event.ctx == QUESTS_ALIASES.BATTLE_PASS_MISSIONS_VIEW_PY_ALIAS
        if self.__viewActive == viewActive and self.__viewActive:
            self.__clearSubViews()
        self.__viewActive = viewActive

    def __clearSubViews(self):
        views = self.__gui.windowsManager.findViews(
            lambda view: view.viewFlags & ViewFlags.VIEW_TYPE_MASK == ViewFlags
            .LOBBY_TOP_SUB_VIEW)
        for view in views:
            view.destroyWindow()

    def __onFocus(self, event):
        context = event.ctx
        if context.get('alias') == VIEW_ALIAS.LOBBY_MISSIONS:
            if self.__viewActive:
                self.__setShowBuyAnimations()

    def __onBattlePassSettingsChange(self, *_):
        if not self.__battlePassController.isVisible(
        ) or self.__battlePassController.isPaused():
            showHangar()
        self.__updateProgressData()
        self.__updateBuyButtonState()

    def __onPointsUpdated(self):
        with self.viewModel.transaction() as model:
            oldPoints = model.getCurrentAllPoints()
            if model.getIsPostProgression():
                oldPoints += self.__battlePassController.getMaxPoints()
            newPoints = self.__battlePassController.getCurrentPoints()
            oldState, oldLevel = self.__battlePassController.getLevelByPoints(
                oldPoints)
            newState, newLevel = self.__battlePassController.getLevelByPoints(
                newPoints)
            if oldState == BattlePassState.BASE:
                if newState == oldState:
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_FREE,
                                                model.freeRewards, oldLevel,
                                                newLevel)
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                                model.paidRewards, oldLevel,
                                                newLevel)
                else:
                    maxLevel = self.__battlePassController.getMaxLevel() - 1
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_FREE,
                                                model.freeRewards, oldLevel,
                                                maxLevel)
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                                model.paidRewards, oldLevel,
                                                maxLevel)
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_POST,
                                                model.postRewards, 1, newLevel)
            elif oldState == BattlePassState.POST:
                if newState == oldState:
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_POST,
                                                model.postRewards, oldLevel,
                                                newLevel)
                else:
                    maxLevel = self.__battlePassController.getMaxLevel(
                        False) - 1
                    self.__resetRewardsInterval(BattlePassConsts.REWARD_POST,
                                                model.postRewards, oldLevel,
                                                maxLevel)
            self.__setCurrentLevelState(model=model)
        isDrawPoints = newLevel < oldLevel or newPoints < oldPoints
        if isDrawPoints:
            model.setShowLevelsAnimations(
                self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.__updateBuyButtonState()
        self.__updateExtrasAndVotingButtons()

    def __onVoted(self):
        self.__updateFinalRewardTooltips()
        self.__updateExtrasAndVotingButtons()

    def __updateFinalRewardTooltips(self):
        maxLevel = self.__battlePassController.getMaxLevel()
        freeRewards, paidRewards = self.__battlePassController.getSplitFinalAwards(
        )
        self.__updateTooltipsSingleCard(
            freeRewards, self.viewModel.freeRewards.getItem(maxLevel - 1))
        self.__updateTooltipsSingleCard(
            paidRewards, self.viewModel.paidRewards.getItem(maxLevel - 1))

    def __updateTooltipsSingleCard(self, rewards, model):
        tooltipIds = [
            item.getTooltipId() for item in model.rewardItems.getItems()
        ]
        tooltipIds = tooltipIds[:len(rewards)]
        changeBonusTooltipData(zip(rewards, tooltipIds), self.__tooltipItems)

    def __onBattlePassBought(self):
        with self.viewModel.transaction() as model:
            maxLevel = self.__battlePassController.getMaxLevel() - 1
            self.__resetRewardsInterval(BattlePassConsts.REWARD_PAID,
                                        model.paidRewards, 1, maxLevel)
            self.__setCurrentLevelState(model=model)
        self.__updateBuyButtonState()

    def __onPurchaseLevels(self, _):
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = True

    def __getTooltipContentCreator(self):
        return {
            R.views.lobby.battle_pass.tooltips.BattlePassPointsView():
            self.__getBattlePassPointsTooltipContent,
            R.views.lobby.battle_pass.tooltips.BattlePassLockIconTooltipView():
            self.__getBattlePassLockIconTooltipContent,
            R.views.lobby.battle_pass.tooltips.BattlePassProgressWarningTooltipView(
            ):
            self.__getBattlePassProgressWarningTooltipContent
        }

    @replaceNoneKwargsModel
    def __setShowBuyAnimations(self, model=None):
        showAnimations = False
        if self.__battlePassController.isBought():
            settings = self.__settingsCore.serverSettings
            if not settings.getBPStorage().get(
                    BattlePassStorageKeys.BUY_ANIMATION_WAS_SHOWN):
                showAnimations = True
                settings.saveInBPStorage(
                    {BattlePassStorageKeys.BUY_ANIMATION_WAS_SHOWN: True})
        model.setShowBuyAnimations(showAnimations)
        model.setShowLevelsAnimations(
            self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS])
        self.ANIMATIONS[self.ANIMATION_PURCHASE_LEVELS] = False

    @staticmethod
    def __getBattlePassPointsTooltipContent(_=None):
        return BattlePassPointsTooltip()

    @staticmethod
    def __getBattlePassLockIconTooltipContent(_=None):
        return BattlePassLockIconTooltipView()

    @staticmethod
    def __getBattlePassProgressWarningTooltipContent(_=None):
        return BattlePassProgressWarningTooltipView()

    def __showIntroVideo(self, onStart=False):
        settings = self.__settingsCore.serverSettings
        if onStart:
            if settings.getBPStorage().get(
                    BattlePassStorageKeys.INTRO_VIDEO_SHOWN):
                return
            settings.saveInBPStorage(
                {BattlePassStorageKeys.INTRO_VIDEO_SHOWN: True})
        showBrowserOverlayView(getIntroVideoURL(), VIEW_ALIAS.BROWSER_OVERLAY)

    def __makeSeasonTimeText(self, timeStamp):
        day, month = self.__getDayMonth(timeStamp)
        return backport.text(
            R.strings.battle_pass_2020.progression.seasonTime(),
            day=str(day),
            month=backport.text(R.strings.menu.dateTime.months.num(month)()))

    def __getSelectedVoteOptionFromTokens(self, seasonID, vehicleCDs):
        for vehCD in vehicleCDs:
            token = self.__itemsCache.items.tokens.getTokens().get(
                getBattlePassVoteToken(seasonID, vehCD))
            if token is not None:
                return vehCD

        return

    def __showBattlePassBuyWindow(self, backCallback=None):
        ctx = {'backCallback': backCallback}
        view = self.__gui.windowsManager.getViewByLayoutID(
            R.views.lobby.battle_pass.BattlePassBuyView())
        if view is None:
            window = BattlePassBuyWindow(ctx, self.getParentWindow())
            window.load()
        return