def __init__(self, layoutID, questID): settings = ViewSettings(layoutID) settings.model = ChallengeRewardViewModel() self.__questID = questID self.__viewLifecycleWatcher = ViewLifecycleWatcher() self._tooltips = {} super(ChallengeRewardView, self).__init__(settings)
def __init__(self, _=None): super(MainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self.__locatedOnEmbelem = False self.itemIsPicked = False self.__propertiesSheet = None self._seasonSoundAnimantion = None self._isPropertySheetShown = False self.__ctx = None self.__renderEnv = None return
def __init__(self, _=None): super(MainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self._currentSeason = SeasonType.SUMMER self._tabIndex = C11nTabs.PAINT self._lastTab = C11nTabs.PAINT self._originalStyle = None self._modifiedStyle = None self._isCurrentStyleInstalled = False self._originalOutfits = {} self._modifiedOutfits = {} self._currentOutfit = None self._mode = C11nMode.CUSTOM self._isDeferredRenderer = True self.__anchorPositionCallbackID = None self._state = {} self._needFullRebuild = False self.__locatedOnEmbelem = False self.itemIsPicked = False self._vehicleCustomizationAnchorsUpdater = None return
def __init__(self, _=None): super(CamoSelectorMainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self._currentSeason = SeasonType.SUMMER self._tabIndex = C11nTabs.CAMO_SHOP self._lastTab = C11nTabs.CAMO_SHOP self._originalOutfits = {} self._modifiedOutfits = {} self._currentOutfit = None self._setupOutfit = None self._mode = C11nMode.INSTALL self._currentSettings = {'custom': {}, 'remap': {}} self._randMode = RandMode.RANDOM self._ally = True self._enemy = True self._settingSeason = SeasonType.UNDEFINED self._isDeferredRenderer = True self.__anchorPositionCallbackID = None self._state = {} self._needFullRebuild = False self.__locatedOnEmbelem = False self.itemIsPicked = False self._vehicleCustomizationAnchorsUpdater = None
def __init__(self, ctx=None): super(LobbyView, self).__init__(ctx) self.__currIgrType = constants.IGR_TYPE.NONE self.__viewLifecycleWatcher = ViewLifecycleWatcher() self._entityEnqueueCancelCallback = None return
class LobbyView(LobbyPageMeta, IWaitingWidget): class COMPONENTS(object): HEADER = 'lobbyHeader' itemsCache = dependency.descriptor(IItemsCache) igrCtrl = dependency.descriptor(IIGRController) lobbyContext = dependency.descriptor(ILobbyContext) def __init__(self, ctx=None): super(LobbyView, self).__init__(ctx) self.__currIgrType = constants.IGR_TYPE.NONE self.__viewLifecycleWatcher = ViewLifecycleWatcher() self._entityEnqueueCancelCallback = None return @proto_getter(PROTO_TYPE.BW_CHAT2) def bwProto(self): return None def showWaiting(self, message, _=False): self.as_showWaitingS(backport.text(message)) def hideWaiting(self): self.as_hideWaitingS() def moveSpace(self, dx, dy, dz): self.fireEvent( CameraRelatedEvents(CameraRelatedEvents.LOBBY_VIEW_MOUSE_MOVE, ctx={ 'dx': dx, 'dy': dy, 'dz': dz })) self.fireEvent( events.LobbySimpleEvent(events.LobbySimpleEvent.NOTIFY_SPACE_MOVED, ctx={ 'dx': dx, 'dy': dy, 'dz': dz })) def notifyCursorOver3dScene(self, isOver3dScene): self.fireEvent( events.LobbySimpleEvent( events.LobbySimpleEvent.NOTIFY_CURSOR_OVER_3DSCENE, ctx={'isOver3dScene': isOver3dScene})) def notifyCursorDragging(self, isDragging): self.fireEvent( events.LobbySimpleEvent( events.LobbySimpleEvent.NOTIFY_CURSOR_DRAGGING, ctx={'isDragging': isDragging})) @uniprof.regionDecorator(label='account.show_gui', scope='enter') def _populate(self): View._populate(self) self.__currIgrType = self.igrCtrl.getRoomType() g_prbLoader.setEnabled(True) self.addListener(events.LobbySimpleEvent.SHOW_HELPLAYOUT, self.__showHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.addListener(events.LobbySimpleEvent.CLOSE_HELPLAYOUT, self.__closeHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.addListener(events.GameEvent.SCREEN_SHOT_MADE, self.__handleScreenShotMade, EVENT_BUS_SCOPE.GLOBAL) self.addListener(events.GameEvent.HIDE_LOBBY_SUB_CONTAINER_ITEMS, self.__hideSubContainerItems, EVENT_BUS_SCOPE.GLOBAL) self.addListener(events.GameEvent.REVEAL_LOBBY_SUB_CONTAINER_ITEMS, self.__revealSubContainerItems, EVENT_BUS_SCOPE.GLOBAL) self.addListener(events.LobbySimpleEvent.TURN_LOBBY_DRAGGING_ON, self.__turnLobbyDraggingOn, EVENT_BUS_SCOPE.LOBBY) self.addListener(events.LobbySimpleEvent.TURN_LOBBY_DRAGGING_OFF, self.__turnLobbyDraggingOff, EVENT_BUS_SCOPE.LOBBY) g_playerEvents.onEntityCheckOutEnqueued += self._onEntityCheckoutEnqueued g_playerEvents.onAccountBecomeNonPlayer += self._onAccountBecomeNonPlayer viewLifecycleHandler = _LobbySubViewsLifecycleHandler() self.__viewLifecycleWatcher.start(self.app.containerManager, [viewLifecycleHandler]) self.igrCtrl.onIgrTypeChanged += self.__onIgrTypeChanged battlesCount = self.itemsCache.items.getAccountDossier().getTotalStats( ).getBattlesCount() epicBattlesCount = self.itemsCache.items.getAccountDossier( ).getEpicBattleStats().getBattlesCount() self.lobbyContext.updateBattlesCount(battlesCount, epicBattlesCount) self.fireEvent( events.GUICommonEvent(events.GUICommonEvent.LOBBY_VIEW_LOADED)) self.bwProto.voipController.invalidateMicrophoneMute() def _invalidate(self, *args, **kwargs): g_prbLoader.setEnabled(True) super(LobbyView, self)._invalidate(*args, **kwargs) @uniprof.regionDecorator(label='account.show_gui', scope='exit') def _dispose(self): self.igrCtrl.onIgrTypeChanged -= self.__onIgrTypeChanged self.__viewLifecycleWatcher.stop() g_playerEvents.onEntityCheckOutEnqueued -= self._onEntityCheckoutEnqueued g_playerEvents.onAccountBecomeNonPlayer -= self._onAccountBecomeNonPlayer if self._entityEnqueueCancelCallback: self._entityEnqueueCancelCallback = None g_eventBus.removeListener(ViewEventType.LOAD_VIEW, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.LobbySimpleEvent.SHOW_HELPLAYOUT, self.__showHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.LobbySimpleEvent.CLOSE_HELPLAYOUT, self.__closeHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.GameEvent.SCREEN_SHOT_MADE, self.__handleScreenShotMade, EVENT_BUS_SCOPE.GLOBAL) self.removeListener(events.GameEvent.HIDE_LOBBY_SUB_CONTAINER_ITEMS, self.__hideSubContainerItems, EVENT_BUS_SCOPE.GLOBAL) self.removeListener(events.GameEvent.REVEAL_LOBBY_SUB_CONTAINER_ITEMS, self.__revealSubContainerItems, EVENT_BUS_SCOPE.GLOBAL) self.removeListener(events.LobbySimpleEvent.TURN_LOBBY_DRAGGING_ON, self.__turnLobbyDraggingOn, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.LobbySimpleEvent.TURN_LOBBY_DRAGGING_OFF, self.__turnLobbyDraggingOff, EVENT_BUS_SCOPE.LOBBY) View._dispose(self) return def _onEntityCheckoutEnqueued(self, cancelCallback): g_eventBus.addListener(ViewEventType.LOAD_VIEW, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) g_eventBus.handleEvent( LoadViewEvent( SFViewLoadParams(VIEW_ALIAS.BOOTCAMP_QUEUE_DIALOG_SHOW)), EVENT_BUS_SCOPE.LOBBY) self._entityEnqueueCancelCallback = cancelCallback def _onEntityCheckoutCanceled(self, event): if event.alias == VIEW_ALIAS.BOOTCAMP_QUEUE_DIALOG_CANCEL: g_eventBus.removeListener(ViewEventType.LOAD_VIEW, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) if self._entityEnqueueCancelCallback: self._entityEnqueueCancelCallback() self._entityEnqueueCancelCallback = None return def _onAccountBecomeNonPlayer(self): self._entityEnqueueCancelCallback = None g_eventBus.removeListener(ViewEventType.LOAD_VIEW, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) return def __showHelpLayout(self, _): self.as_showHelpLayoutS() def __closeHelpLayout(self, _): self.as_closeHelpLayoutS() def __handleScreenShotMade(self, event): if 'path' not in event.ctx: return SystemMessages.pushMessage( i18n.makeString('#menu:screenshot/save') % {'path': event.ctx['path']}, SystemMessages.SM_TYPE.Information) def __hideSubContainerItems(self, _): self.as_setSubContainerItemsVisibilityS(False) def __revealSubContainerItems(self, _): self.as_setSubContainerItemsVisibilityS(True) def __onIgrTypeChanged(self, roomType, xpFactor): icon = gui.makeHtmlString('html_templates:igr/iconSmall', 'premium') if roomType == constants.IGR_TYPE.PREMIUM: SystemMessages.pushMessage(i18n.makeString( SYSTEM_MESSAGES.IGR_CUSTOMIZATION_BEGIN, igrIcon=icon), type=SystemMessages.SM_TYPE.Information) elif roomType in [ constants.IGR_TYPE.BASE, constants.IGR_TYPE.NONE ] and self.__currIgrType == constants.IGR_TYPE.PREMIUM: SystemMessages.pushMessage(i18n.makeString( SYSTEM_MESSAGES.IGR_CUSTOMIZATION_END, igrIcon=icon), type=SystemMessages.SM_TYPE.Information) self.__currIgrType = roomType def __turnLobbyDraggingOn(self, _): self.as_switchLobbyDraggingS(True) def __turnLobbyDraggingOff(self, _): self.as_switchLobbyDraggingS(False)
class LobbyView(LobbyPageMeta): class COMPONENTS: HEADER = 'lobbyHeader' itemsCache = dependency.descriptor(IItemsCache) igrCtrl = dependency.descriptor(IIGRController) lobbyContext = dependency.descriptor(ILobbyContext) def __init__(self, ctx=None): super(LobbyView, self).__init__(ctx) self.__currIgrType = constants.IGR_TYPE.NONE self.__viewLifecycleWatcher = ViewLifecycleWatcher() self._entityEnqueueCancelCallback = None return @proto_getter(PROTO_TYPE.BW_CHAT2) def bwProto(self): return None def _populate(self): View._populate(self) self.__currIgrType = self.igrCtrl.getRoomType() g_prbLoader.setEnabled(True) self.addListener(events.LobbySimpleEvent.SHOW_HELPLAYOUT, self.__showHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.addListener(events.LobbySimpleEvent.CLOSE_HELPLAYOUT, self.__closeHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.addListener(events.GameEvent.SCREEN_SHOT_MADE, self.__handleScreenShotMade, EVENT_BUS_SCOPE.GLOBAL) g_playerEvents.onVehicleBecomeElite += self._onVehicleBecomeElite g_playerEvents.onEntityCheckOutEnqueued += self._onEntityCheckoutEnqueued g_playerEvents.onAccountBecomeNonPlayer += self._onAccountBecomeNonPlayer viewLifecycleHandler = _LobbySubViewsLifecycleHandler() self.__viewLifecycleWatcher.start(self.app.containerManager, [viewLifecycleHandler]) self.igrCtrl.onIgrTypeChanged += self.__onIgrTypeChanged battlesCount = self.itemsCache.items.getAccountDossier().getTotalStats( ).getBattlesCount() self.lobbyContext.updateBattlesCount(battlesCount) self.fireEvent( events.GUICommonEvent(events.GUICommonEvent.LOBBY_VIEW_LOADED)) self.bwProto.voipController.invalidateMicrophoneMute() def _invalidate(self, *args, **kwargs): g_prbLoader.setEnabled(True) super(LobbyView, self)._invalidate(*args, **kwargs) def _dispose(self): self.igrCtrl.onIgrTypeChanged -= self.__onIgrTypeChanged self.__viewLifecycleWatcher.stop() g_playerEvents.onVehicleBecomeElite -= self._onVehicleBecomeElite g_playerEvents.onEntityCheckOutEnqueued -= self._onEntityCheckoutEnqueued g_playerEvents.onAccountBecomeNonPlayer -= self._onAccountBecomeNonPlayer if self._entityEnqueueCancelCallback: self._entityEnqueueCancelCallback = None g_eventBus.removeListener(BootcampEvent.QUEUE_DIALOG_CANCEL, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.LobbySimpleEvent.SHOW_HELPLAYOUT, self.__showHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.LobbySimpleEvent.CLOSE_HELPLAYOUT, self.__closeHelpLayout, EVENT_BUS_SCOPE.LOBBY) self.removeListener(events.GameEvent.SCREEN_SHOT_MADE, self.__handleScreenShotMade, EVENT_BUS_SCOPE.GLOBAL) View._dispose(self) return def __showHelpLayout(self, _): self.as_showHelpLayoutS() def __closeHelpLayout(self, _): self.as_closeHelpLayoutS() def __handleScreenShotMade(self, event): if 'path' not in event.ctx: return SystemMessages.pushMessage( i18n.makeString('#menu:screenshot/save') % {'path': event.ctx['path']}, SystemMessages.SM_TYPE.Information) def _onVehicleBecomeElite(self, vehTypeCompDescr): if not isPopupsWindowsOpenDisabled(): self.fireEvent( events.LoadViewEvent( VIEW_ALIAS.ELITE_WINDOW, getViewName(VIEW_ALIAS.ELITE_WINDOW, vehTypeCompDescr), {'vehTypeCompDescr': vehTypeCompDescr}), EVENT_BUS_SCOPE.LOBBY) def _onEntityCheckoutEnqueued(self, cancelCallback): g_eventBus.addListener(BootcampEvent.QUEUE_DIALOG_CANCEL, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) g_eventBus.handleEvent(BootcampEvent(BootcampEvent.QUEUE_DIALOG_SHOW), EVENT_BUS_SCOPE.LOBBY) self._entityEnqueueCancelCallback = cancelCallback def _onEntityCheckoutCanceled(self, _): g_eventBus.removeListener(BootcampEvent.QUEUE_DIALOG_CANCEL, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) if self._entityEnqueueCancelCallback: self._entityEnqueueCancelCallback() self._entityEnqueueCancelCallback = None return def _onAccountBecomeNonPlayer(self): self._entityEnqueueCancelCallback = None g_eventBus.removeListener(BootcampEvent.QUEUE_DIALOG_CANCEL, self._onEntityCheckoutCanceled, EVENT_BUS_SCOPE.LOBBY) return def moveSpace(self, dx, dy, dz): dx, dy, dz = int(dx), int(dy), int(dz) if g_hangarSpace.space: g_hangarSpace.space.handleMouseEvent(dx, dy, dz) self.fireEvent( events.LobbySimpleEvent(events.LobbySimpleEvent.NOTIFY_SPACE_MOVED, ctx={ 'dx': dx, 'dy': dy, 'dz': dz })) def notifyCursorOver3dScene(self, isOver3dScene): self.fireEvent( events.LobbySimpleEvent( events.LobbySimpleEvent.NOTIFY_CURSOR_OVER_3DSCENE, ctx={'isOver3dScene': isOver3dScene})) def notifyCursorDragging(self, isDragging): self.fireEvent( events.LobbySimpleEvent( events.LobbySimpleEvent.NOTIFY_CURSOR_DRAGGING, ctx={'isDragging': isDragging})) def __onIgrTypeChanged(self, roomType, xpFactor): icon = gui.makeHtmlString('html_templates:igr/iconSmall', 'premium') if roomType == constants.IGR_TYPE.PREMIUM: SystemMessages.pushMessage(i18n.makeString( SYSTEM_MESSAGES.IGR_CUSTOMIZATION_BEGIN, igrIcon=icon), type=SystemMessages.SM_TYPE.Information) elif roomType in [ constants.IGR_TYPE.BASE, constants.IGR_TYPE.NONE ] and self.__currIgrType == constants.IGR_TYPE.PREMIUM: SystemMessages.pushMessage(i18n.makeString( SYSTEM_MESSAGES.IGR_CUSTOMIZATION_END, igrIcon=icon), type=SystemMessages.SM_TYPE.Information) self.__currIgrType = roomType
class CamoSelectorMainView(CustomizationMainViewMeta): _COMMON_SOUND_SPACE = C11N_SOUND_SPACE lobbyContext = dependency.descriptor(ILobbyContext) itemsCache = dependency.descriptor(IItemsCache) service = dependency.descriptor(ICustomizationService) settingsCore = dependency.descriptor(ISettingsCore) def __init__(self, _=None): super(CamoSelectorMainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self._currentSeason = SeasonType.SUMMER self._tabIndex = C11nTabs.CAMO_SHOP self._lastTab = C11nTabs.CAMO_SHOP self._originalOutfits = {} self._modifiedOutfits = {} self._currentOutfit = None self._setupOutfit = None self._mode = C11nMode.INSTALL self._currentSettings = {'custom': {}, 'remap': {}} self._randMode = RandMode.RANDOM self._ally = True self._enemy = True self._settingSeason = SeasonType.UNDEFINED self._isDeferredRenderer = True self.__anchorPositionCallbackID = None self._state = {} self._needFullRebuild = False self.__locatedOnEmbelem = False self.itemIsPicked = False self._vehicleCustomizationAnchorsUpdater = None def showBuyWindow(self): self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.SELECT) purchaseItems = self.getPurchaseItems() self.buyAndExit(purchaseItems) def onSelectItem(self, index): self._carouselDP.selectItemIdx(index) self.soundManager.playInstantSound(SOUNDS.SELECT) def onPickItem(self): if self._mode == C11nMode.SETUP: self.__onRegionHighlighted(GUI_ITEM_TYPE.CAMOUFLAGE, 1, 0, True, False) elif not self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.PICK) self.itemIsPicked = True def onReleaseItem(self): self.__releaseItemSound() def changeSeason(self, seasonIdx): self._currentSeason = SEASON_IDX_TO_TYPE[seasonIdx] seasonName = SEASON_TYPE_TO_NAME.get(self._currentSeason) self.soundManager.playInstantSound(SOUNDS.SEASON_SELECT.format(seasonName)) self.refreshOutfit() self.refreshCarousel(rebuild=True) self.as_refreshAnchorPropertySheetS() self.__setAnchorsInitData(self._tabIndex, self._tabIndex in C11nTabs.REGIONS, True) def changeCamoTeamMode(self, idx): self._ally = bool(idx & TeamMode.ALLY) self._enemy = bool(idx & TeamMode.ENEMY) self._updateCurrentSettings() self.__setBuyingPanelData() def changeCamoRandMode(self, idx): self._randMode = idx self._updateCurrentSettings() self.__setBuyingPanelData() def _updateCurrentSettings(self): item = self._currentOutfit.getContainer(1).slotFor(GUI_ITEM_TYPE.CAMOUFLAGE).getItem(0) itemName, itemKey = (item.descriptor.userKey, 'custom') if item.priceGroup == 'custom' else (item.id, 'remap') settings = self._currentSettings[itemKey].setdefault(itemName, {}) settings['useForAlly'] = self._ally settings['useForEnemy'] = self._enemy settings['random_mode'] = self._randMode def _cleanSettings(self, allSettings, checkSeasons=True): camouflages = items.vehicles.g_cache.customization20().camouflages for itemsKey in allSettings: itemSettings = allSettings[itemsKey] for camoID in itemSettings.keys(): origSetting = g_config.camouflages[itemsKey].get(camoID, {}) camoSetting = itemSettings[camoID] if 'season' in camoSetting: if checkSeasons and itemsKey == 'remap' and not self.itemsCache.items.getItemByCD( camouflages[camoID].compactDescr).isHidden: print g_config.ID + ': in-shop camouflage season changing is disabled (id:',\ camoID + ', season setting was', (camoSetting['season'] or 'empty') + ')' del camoSetting['season'] if 'season' in origSetting: del origSetting['season'] elif 'season' not in origSetting: itemSeasons = SeasonType.UNDEFINED for season in SEASONS_CONSTANTS.SEASONS: if season in camoSetting['season']: itemSeasons |= getattr(SeasonType, season.upper()) camoSeason = camouflages[camoID].season if itemSeasons == (camoSeason if camoSeason < 8 else camoSeason - 8): del camoSetting['season'] elif origSetting['season'] == camoSetting['season']: del camoSetting['season'] for team in ('useForAlly', 'useForEnemy'): if team in camoSetting: if origSetting.get(team, True) == camoSetting[team]: del camoSetting[team] if 'random_mode' in camoSetting: if camoSetting['random_mode'] == origSetting.get('random_mode', RandMode.RANDOM): del camoSetting['random_mode'] if not camoSetting: del itemSettings[camoID] return allSettings def refreshCarousel(self, rebuild=False): if rebuild: self._carouselDP.buildList(self._tabIndex, self._currentSeason, refresh=False) self.as_setCarouselDataS(self._buildCustomizationCarouselDataVO()) self._carouselDP.refresh() def refreshHotFilters(self): self.as_setCarouselFiltersDataS( {'hotFilters': [self._carouselDP.getOwnedFilter(), self._carouselDP.getAppliedFilter()]}) def refreshOutfit(self): if self._mode == C11nMode.INSTALL: self._currentOutfit = self._modifiedOutfits[self._currentSeason] else: self._currentOutfit = self._setupOutfit self.service.tryOnOutfit(self._currentOutfit) g_tankActiveCamouflage[g_currentVehicle.item.intCD] = self._currentSeason def showGroupFromTab(self, tabIndex): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self._tabIndex = tabIndex doRegions = self._tabIndex in C11nTabs.REGIONS self.service.stopHighlighter() if self._mode == C11nMode.INSTALL and doRegions: self.service.startHighlighter(chooseMode(tabToItem(self._tabIndex), g_currentVehicle.item)) self.__setAnchorsInitData(self._tabIndex, doRegions) if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__updateAnchorPositions() if self._tabIndex == C11nTabs.EFFECT: slotIdVO = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.MODIFICATION, 0)._asdict() else: slotIdVO = None self.as_updateSelectedRegionsS(slotIdVO) self.refreshCarousel(rebuild=True) if self._mode == C11nMode.SETUP: self.__onRegionHighlighted(GUI_ITEM_TYPE.CAMOUFLAGE, 1, 0, True, False) def installCustomizationElement(self, intCD, areaId, slotId, regionId, seasonIdx): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.APPLY) item = self.itemsCache.items.getItemByCD(intCD) if self._mode == C11nMode.INSTALL: season = SEASON_IDX_TO_TYPE.get(seasonIdx, self._currentSeason) outfit = self._modifiedOutfits[season] outfit.getContainer(areaId).slotFor(slotId).set(item, idx=regionId) else: outfit = self._setupOutfit for areaId in xrange(1, 4): outfit.getContainer(areaId).slotFor(slotId).set(item, idx=regionId) itemName, itemKey = (item.descriptor.userKey, 'custom') if item.priceGroup == 'custom' else (item.id, 'remap') itemSettings = self._currentSettings[itemKey].setdefault(itemName, {}) itemOrigSettings = g_config.camouflages[itemKey].get(itemName, {}) itemSeasonsStr = itemSettings.get('season', itemOrigSettings.get('season', None)) if itemSeasonsStr is not None: itemSeasons = SeasonType.UNDEFINED for season in SEASONS_CONSTANTS.SEASONS: if season in itemSeasonsStr: itemSeasons |= getattr(SeasonType, season.upper()) else: itemSeasons = item.season itemSeasonsStr = itemSettings['season'] = ','.join( x for x in SEASONS_CONSTANTS.SEASONS if getattr(SeasonType, x.upper()) & itemSeasons) if seasonIdx not in SEASON_IDX_TO_TYPE: # item is selected from carousel, not changed from property sheet self._settingSeason = itemSeasons self._randMode = itemSettings.get('random_mode', itemOrigSettings.get('random_mode', RandMode.RANDOM)) self._ally = itemSettings.get('useForAlly', itemOrigSettings.get('useForAlly', True)) self._enemy = itemSettings.get('useForEnemy', itemOrigSettings.get('useForEnemy', True)) else: self._settingSeason |= SEASON_IDX_TO_TYPE[seasonIdx] newSeasons = set(x for x in SEASONS_CONSTANTS.SEASONS if x in itemSeasonsStr) newSeasons.add(SEASON_TYPE_TO_NAME[SEASON_IDX_TO_TYPE[seasonIdx]]) itemSettings['season'] = ','.join(x for x in SEASONS_CONSTANTS.SEASONS if x in newSeasons) outfit.invalidate() self.refreshOutfit() self.__setBuyingPanelData() self.__setHeaderInitData() self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) def clearCustomizationItem(self, areaId, slotId, regionId, seasonIdx): self.soundManager.playInstantSound(SOUNDS.REMOVE) if self._mode == C11nMode.INSTALL: season = SEASON_IDX_TO_TYPE.get(seasonIdx, self._currentSeason) outfit = self._modifiedOutfits[season] outfit.getContainer(areaId).slotFor(slotId).remove(idx=regionId) else: item = self._setupOutfit.getContainer(areaId).slotFor(slotId).getItem(regionId) itemName, itemKey = (item.descriptor.userKey, 'custom') if item.priceGroup == 'custom' else (item.id, 'remap') itemSettings = self._currentSettings[itemKey].setdefault(itemName, {}) itemOrigSettings = g_config.camouflages[itemKey].get(itemName, {}) itemSeasonsStr = itemSettings.get('season', itemOrigSettings.get('season', None)) if seasonIdx not in SEASON_IDX_TO_TYPE: print 'WARNING', seasonIdx else: newSeasons = set() if itemSeasonsStr is not None: [newSeasons.add(x) for x in SEASONS_CONSTANTS.SEASONS if x in itemSeasonsStr] newSeasons.discard(SEASON_TYPE_TO_NAME[SEASON_IDX_TO_TYPE[seasonIdx]]) itemSettings['season'] = ','.join(x for x in SEASONS_CONSTANTS.SEASONS if x in newSeasons) self._settingSeason = SeasonType.UNDEFINED for season in newSeasons: self._settingSeason |= getattr(SeasonType, season.upper()) self.refreshOutfit() self.__setAnchorsInitData(self._tabIndex, self._tabIndex in C11nTabs.REGIONS, True) self.__setBuyingPanelData() self.__setHeaderInitData() self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) def switchToCustom(self, updateUI=True): self.service.startHighlighter(chooseMode(tabToItem(self._tabIndex), g_currentVehicle.item)) self.switchMode(C11nMode.INSTALL) def switchToStyle(self): if self._tabIndex not in C11nTabs.CAMO: self._tabIndex = C11nTabs.CAMO_SHOP self.switchMode(C11nMode.SETUP) self.__onRegionHighlighted(GUI_ITEM_TYPE.CAMOUFLAGE, 1, 0, True, False) self.service.stopHighlighter() def switchMode(self, mode): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self._mode = mode self.refreshOutfit() self.__setFooterInitData() self._carouselDP.selectItem() self.__setBuyingPanelData() self.__setHeaderInitData() def fadeOutAnchors(self, isFadeOut): self.fadeAnchorsOut = isFadeOut def closeWindow(self): purchaseItems = self.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.numTotal or any(self._cleanSettings(self._currentSettings).itervalues()): DialogsInterface.showDialog(I18nConfirmDialogMeta('customization/close'), self.__onConfirmCloseWindow) else: self.__onConfirmCloseWindow(proceed=True) def itemContextMenuDisplayed(self): cmHandler = self.app.contextMenuManager.getCurrentHandler() if isinstance(cmHandler, CustomizationItemCMHandler): cmHandler.onSelected += self._itemCtxMenuSelected def resetFilter(self): self.clearFilter() self.refreshFilterData() self.refreshHotFilters() self.refreshCarousel(rebuild=True) def clearFilter(self): self._carouselDP.clearFilter() def refreshFilterData(self): self.as_setFilterDataS(self._carouselDP.getFilterData()) def getHistoricalPopoverData(self): self.soundManager.playInstantSound(SOUNDS.SELECT) nonHistoricItems = [] for outfit in self._modifiedOutfits.itervalues(): nonHistoricItems.extend((item for item in outfit.items() if not item.isHistorical())) return {'items': [item.intCD for item in sorted(nonHistoricItems, key=comparisonKey)]} def removeItems(self, *intCDs): self.soundManager.playInstantSound(SOUNDS.REMOVE) for outfit in self._modifiedOutfits.itervalues(): for slot in outfit.slots(): for idx in range(slot.capacity()): item = slot.getItem(idx) if item and item.intCD in intCDs: slot.remove(idx) self.refreshOutfit() self.__setHeaderInitData() self.__setBuyingPanelData() self.as_refreshAnchorPropertySheetS() self.__setAnchorsInitData(self._tabIndex, self._tabIndex in C11nTabs.REGIONS, True) self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) def updatePropertySheetButtons(self, areaId, slotId, regionId): self.service.onPropertySheetShow(areaId, slotId, regionId) def onLobbyClick(self): if self._tabIndex in (C11nTabs.EMBLEM, C11nTabs.INSCRIPTION): self.as_hideAnchorPropertySheetS() if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__updateAnchorPositions() self.__locatedOnEmbelem = False def setEnableMultiselectRegions(self, isEnabled): pass def onChangeSize(self): self.__updateAnchorPositions() def onSelectAnchor(self, areaID, regionID): if g_hangarSpace.spaceInited: self.soundManager.playInstantSound(SOUNDS.CHOOSE) if self._tabIndex == C11nTabs.EMBLEM: emblemType = 'player' zoom = 0.06 else: emblemType = 'inscription' zoom = 0.1 self.__updateAnchorPositions() self.__locatedOnEmbelem = g_hangarSpace.space.locateCameraOnEmblem(areaID < 2, emblemType, regionID, zoom) self.as_cameraAutoRotateChangedS(True) BigWorld.callback(5, self.__cameraRotationFinished) def __cameraRotationFinished(self): self.as_cameraAutoRotateChangedS(False) def getOutfitsInfo(self): outfitsInfo = {} for season in SEASONS_ORDER: outfitsInfo[season] = OutfitInfo(self._originalOutfits[season], self._modifiedOutfits[season]) return outfitsInfo def getPurchaseItems(self): return getCustomPurchaseItems(self.getOutfitsInfo()) def getItemInventoryCount(self, item): return getItemInventoryCount(item, self.getOutfitsInfo()) def getCurrentOutfit(self): return self._currentOutfit def getModifiedOutfit(self, season): return self._modifiedOutfits.get(season) def getMode(self): return self._mode def getCurrentSeason(self): return self._currentSeason def getCurrentTab(self): return self._tabIndex def getRandMode(self): return self._randMode def getIsAlly(self): return self._ally def getIsEnemy(self): return self._enemy def getTeamMode(self): return 0 | (self._ally and TeamMode.ALLY) | (self._enemy and TeamMode.ENEMY) def getSettingSeason(self): return self._settingSeason def getAppliedItems(self, isOriginal=True): outfits = self._originalOutfits if isOriginal else self._modifiedOutfits seasons = SeasonType.COMMON_SEASONS if isOriginal else (self._currentSeason,) appliedItems = set() for seasonType in seasons: outfit = outfits[seasonType] appliedItems.update((i.intCD for i in outfit.items())) return appliedItems def isItemInOutfit(self, item): return any((outfit.has(item) for outfit in self._originalOutfits.itervalues())) or any( (outfit.has(item) for outfit in self._modifiedOutfits.itervalues())) def buyAndExit(self, purchaseItems): self._currentSettings = self._cleanSettings(self._currentSettings) for itemsKey in self._currentSettings: for camoName in self._currentSettings[itemsKey]: g_config.camouflages[itemsKey].setdefault(camoName, {}).update(self._currentSettings[itemsKey][camoName]) if self._currentSettings['remap']: newSettings = {'disable': g_config.disable, 'remap': g_config.camouflages['remap']} loadJson(g_config.ID, 'settings', newSettings, g_config.configPath, True) if self._currentSettings['custom']: for confFolderName in g_config.configFolders: configFolder = g_config.configFolders[confFolderName] loadJson(g_config.ID, 'settings', {key: g_config.camouflages['custom'][key] for key in configFolder}, g_config.configPath + 'camouflages/' + confFolderName + '/', True, False) if any(self._currentSettings.itervalues()): from ..processors import collectCamouflageData collectCamouflageData() self.itemsCache.onSyncCompleted -= self.__onCacheResync boughtOutfits = {season: self.service.getCustomOutfit(season) for season in SeasonType.COMMON_SEASONS} cart = getTotalPurchaseInfo(purchaseItems) nationName, vehicleName = g_currentVehicle.item.descriptor.name.split(':') vehConfig = g_config.outfitCache.get(nationName, {}).get(vehicleName, {}) for pItem in (x for x in purchaseItems if x.selected): seasonName = SEASON_TYPE_TO_NAME[pItem.group] if pItem.slot == GUI_ITEM_TYPE.CAMOUFLAGE: bItem, bComp = boughtOutfits[pItem.group].getContainer(pItem.areaID).slotFor(pItem.slot)._items.get( pItem.regionID, (None, None)) component = self._modifiedOutfits[pItem.group].getContainer(pItem.areaID).slotFor(pItem.slot).getComponent( pItem.regionID) if pItem.isDismantling and (not bItem or not bComp) or not pItem.isDismantling and pItem.item == bItem and \ component.palette == bComp.palette and component.patternSize == bComp.patternSize: vehConfig.get(seasonName, {}).get('camo', {}).pop(TankPartIndexes.getName(pItem.areaID), []) else: g_config.outfitCache.setdefault(nationName, {}).setdefault(vehicleName, {}).setdefault( seasonName, {}).setdefault('camo', {})[TankPartIndexes.getName(pItem.areaID)] = ( [pItem.item.id, component.palette, component.patternSize] if not pItem.isDismantling else []) g_config.hangarCamoCache.get(nationName, {}).get(vehicleName, {}).get(seasonName, {}).pop( TankPartIndexes.getName(pItem.areaID), {}) else: typeName = GUI_ITEM_TYPE_NAMES[pItem.slot] bItem = boughtOutfits[pItem.group].getContainer(pItem.areaID).slotFor(pItem.slot).getItem(pItem.regionID) if pItem.isDismantling and not bItem or not pItem.isDismantling and pItem.item == bItem: vehConfig.get(seasonName, {}).get(typeName, {}).get( TankPartIndexes.getName(pItem.areaID) if pItem.areaID < 4 else 'misc', {}).pop(str(pItem.regionID), None) else: g_config.outfitCache.setdefault(nationName, {}).setdefault(vehicleName, {}).setdefault( seasonName, {}).setdefault(typeName, {}).setdefault( TankPartIndexes.getName(pItem.areaID) if pItem.areaID < 4 else 'misc', {})[ str(pItem.regionID)] = (pItem.item.id if not pItem.isDismantling else None) for nationName in g_config.outfitCache.keys(): for vehicleName in g_config.outfitCache[nationName].keys(): for season in g_config.outfitCache[nationName][vehicleName].keys(): for itemType in g_config.outfitCache[nationName][vehicleName][season].keys(): if itemType == 'camo': if g_currentVehicle.item.turret.isGunCarriage: g_config.outfitCache[nationName][vehicleName][season][itemType].pop('turret', None) else: for areaName in g_config.outfitCache[nationName][vehicleName][season][itemType].keys(): if not g_config.outfitCache[nationName][vehicleName][season][itemType][areaName]: del g_config.outfitCache[nationName][vehicleName][season][itemType][areaName] if not g_config.outfitCache[nationName][vehicleName][season][itemType]: del g_config.outfitCache[nationName][vehicleName][season][itemType] if not g_config.outfitCache[nationName][vehicleName][season]: del g_config.outfitCache[nationName][vehicleName][season] if not g_config.outfitCache[nationName][vehicleName]: del g_config.outfitCache[nationName][vehicleName] if not g_config.outfitCache[nationName]: del g_config.outfitCache[nationName] loadJson(g_config.ID, 'outfitCache', g_config.outfitCache, g_config.configPath, True) if cart.totalPrice != ITEM_PRICE_EMPTY: msgCtx = {'money': formatPrice(cart.totalPrice.price), 'count': cart.numSelected} SystemMessages.pushMessage(g_config.i18n['UI_flashCol_applied_money'] % msgCtx, type=CURRENCY_TO_SM_TYPE.get(cart.totalPrice.getCurrency(byWeight=True), SM_TYPE.PurchaseForGold)) else: SystemMessages.pushI18nMessage(MESSENGER.SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONS, type=SM_TYPE.Information) self.__onCacheResync() self.itemsCache.onSyncCompleted += self.__onCacheResync # noinspection PyUnusedLocal @process('sellItem') def sellItem(self, intCD, shouldSell): assert False def onAnchorsShown(self, anchors): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setAnchors(anchors, self._tabIndex in C11nTabs.REGIONS) def _populate(self): super(CamoSelectorMainView, self)._populate() self.soundManager.playInstantSound(SOUNDS.ENTER) self.__viewLifecycleWatcher.start(self.app.containerManager, [_C11nWindowsLifecycleHandler()]) self._isDeferredRenderer = self.settingsCore.getSetting(GRAPHICS.RENDER_PIPELINE) == 0 g_clientUpdateManager.addMoneyCallback(self.__setBuyingPanelData) self.lobbyContext.addHeaderNavigationConfirmator(self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingChanged self.service.onCarouselFilter += self.__onCarouselFilter self.service.onRemoveItems += self.removeItems self.service.onOutfitChanged += self.__onOutfitChanged g_eventBus.addListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) g_hangarSpace.onSpaceCreate += self.__onSpaceCreateHandler g_hangarSpace.onSpaceDestroy += self.__onSpaceDestroyHandler g_hangarSpace.onSpaceRefresh += self.__onSpaceRefreshHandler self.service.onRegionHighlighted += self.__onRegionHighlighted self.itemsCache.onSyncCompleted += self.__onCacheResync self.__carveUpOutfits() self._carouselDP = CustomizationCarouselDataProvider(g_currentVehicle, self._carouseItemWrapper, self) self._carouselDP.setFlashObject(self.as_getDataProviderS()) self._carouselDP.setEnvironment(self.app) self.__setHeaderInitData() self.__setFooterInitData() self.__setBuyingPanelData() self.__setSeasonData() self._vehicleCustomizationAnchorsUpdater = _VehicleCustomizationAnchorsUpdater(self.service) self._vehicleCustomizationAnchorsUpdater.startUpdater(self.settingsCore.interfaceScale.get()) self.refreshOutfit() self.settingsCore.interfaceScale.onScaleExactlyChanged += self.__onInterfaceScaleChanged self.settingsCore.onSettingsChanged += self.__onSettingsChanged self.__updateCameraParalaxFlag() self.service.startHighlighter(chooseMode(tabToItem(self._tabIndex), g_currentVehicle.item)) def _dispose(self): if g_appLoader.getSpaceID() != _SPACE_ID.LOGIN: self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.EXIT) self.settingsCore.onSettingsChanged -= self.__onSettingsChanged self.settingsCore.interfaceScale.onScaleExactlyChanged -= self.__onInterfaceScaleChanged self._vehicleCustomizationAnchorsUpdater.stopUpdater() self._vehicleCustomizationAnchorsUpdater = None if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__viewLifecycleWatcher.stop() self.service.stopHighlighter() g_clientUpdateManager.removeObjectCallbacks(self) self.lobbyContext.deleteHeaderNavigationConfirmator(self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings().onServerSettingsChange -= self.__onServerSettingChanged self.service.onCarouselFilter -= self.__onCarouselFilter self.service.onRemoveItems -= self.removeItems self.service.onOutfitChanged -= self.__onOutfitChanged g_eventBus.removeListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) g_hangarSpace.onSpaceCreate -= self.__onSpaceCreateHandler g_hangarSpace.onSpaceDestroy -= self.__onSpaceDestroyHandler g_hangarSpace.onSpaceRefresh -= self.__onSpaceRefreshHandler self.service.onRegionHighlighted -= self.__onRegionHighlighted self.itemsCache.onSyncCompleted -= self.__onCacheResync if g_currentVehicle.item: g_tankActiveCamouflage[g_currentVehicle.item.intCD] = self._currentSeason g_currentVehicle.refreshModel() super(CamoSelectorMainView, self)._dispose() def _itemCtxMenuSelected(self, ctxMenuID, itemIntCD): item = self.itemsCache.items.getItemByCD(itemIntCD) if ctxMenuID == CustomizationOptions.REMOVE_FROM_TANK: self.removeItems(item.intCD) def _getUpdatedAnchorPositions(self): anchorVOs = [] anchorPosData = [] cType = tabToItem(self._tabIndex) outfit = self.service.getEmptyOutfit() for container in outfit.containers(): for slot in (x for x in container.slots() if x.getType() == cType): for regionId, region in enumerate(slot.getRegions()): slotId = CustomizationSlotIdVO(container.getAreaID(), slot.getType(), regionId) anchorData = self.__getAnchorPositionData(slotId, region) if anchorData is not None: anchorPosData.append(anchorData) for zIdx, posData in enumerate(anchorPosData): anchorVOs.append(CustomizationAnchorPositionVO(zIdx, posData.slotId._asdict())._asdict()) return CustomizationAnchorsSetVO(anchorVOs)._asdict() def _buildCustomizationCarouselDataVO(self): isZeroCount = self._carouselDP.itemCount == 0 countStyle = text_styles.error if isZeroCount else text_styles.main displayString = text_styles.main( '{} / {}'.format(countStyle(str(self._carouselDP.itemCount)), str(self._carouselDP.totalItemCount))) shouldShow = self._carouselDP.itemCount < self._carouselDP.totalItemCount return CustomizationCarouselDataVO(displayString, isZeroCount, shouldShow, itemLayoutSize=self._carouselDP.getItemSizeData(), bookmarks=self._carouselDP.getBookmarkData())._asdict() def _carouseItemWrapper(self, itemCD): item = self.itemsCache.items.getItemByCD(itemCD) itemInventoryCount = self.getItemInventoryCount(item) if item.itemTypeID == GUI_ITEM_TYPE.MODIFICATION: showUnsupportedAlert = not self._isDeferredRenderer else: showUnsupportedAlert = False isCurrentlyApplied = itemCD in self._carouselDP.getCurrentlyApplied() return buildCustomizationItemDataVO(item, itemInventoryCount, showUnsupportedAlert=showUnsupportedAlert, isCurrentlyApplied=isCurrentlyApplied, plainView=True) def __carveUpOutfits(self): from ..processors import applyCamoCache, applyPlayerCache self._setupOutfit = self.service.getEmptyOutfit() descriptor = g_currentVehicle.item.descriptor nationName, vehName = descriptor.name.split(':') for season in SeasonType.COMMON_SEASONS: outfit = self.service.getCustomOutfit(season).copy() seasonName = SEASON_TYPE_TO_NAME[season] seasonCache = g_config.outfitCache.get(nationName, {}).get(vehName, {}).get(seasonName, {}) applyCamoCache(outfit, vehName, seasonCache.get('camo', {})) applyPlayerCache(outfit, vehName, seasonCache) self._originalOutfits[season] = outfit.copy() applyCamoCache(outfit, vehName, g_config.hangarCamoCache.get(nationName, {}).get(vehName, {}).get(seasonName, {})) self._modifiedOutfits[season] = outfit.copy() if self._mode == C11nMode.INSTALL: self._currentOutfit = self._modifiedOutfits[self._currentSeason] else: self._currentOutfit = self._setupOutfit def __updateAnchorPositions(self, _=None): self.as_setAnchorPositionsS(self._getUpdatedAnchorPositions()) def __onRegionHighlighted(self, typeID, tankPartID, regionID, selected, hovered): slotId = None if hovered: self.soundManager.playInstantSound(SOUNDS.HOVER) return if self._tabIndex == C11nTabs.EFFECT: tankPartID = Area.MISC typeID = GUI_ITEM_TYPE.MODIFICATION if tankPartID != -1 and regionID != -1: slotId = CustomizationSlotIdVO(tankPartID if self._mode == C11nMode.INSTALL else 1, typeID, regionID)._asdict() if selected: self.soundManager.playInstantSound(SOUNDS.CHOOSE) if self._mode == C11nMode.INSTALL or slotId is not None: self.as_onRegionHighlightedS(slotId) def __onSpaceCreateHandler(self): Waiting.hide('loadHangarSpace') self.refreshOutfit() self.__updateAnchorPositions() def __onSpaceDestroyHandler(self, _): Waiting.hide('loadHangarSpace') self.__onConfirmCloseWindow(proceed=True) def __onSpaceRefreshHandler(self): Waiting.show('loadHangarSpace') def __onConfirmCloseWindow(self, proceed): if proceed: self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY) def __onCarouselFilter(self, **kwargs): if 'group' in kwargs: self._carouselDP.setActiveGroupIndex(kwargs['group']) if 'historic' in kwargs: self._carouselDP.setHistoricalFilter(kwargs['historic']) if 'inventory' in kwargs: self._carouselDP.setOwnedFilter(kwargs['inventory']) if 'applied' in kwargs: self._carouselDP.setAppliedFilter(kwargs['applied']) self.refreshCarousel(rebuild=True) self.refreshHotFilters() def __onOutfitChanged(self): self.refreshOutfit() self.__setBuyingPanelData() def __onCacheResync(self, *_): if not g_currentVehicle.isPresent(): self.__onConfirmCloseWindow(proceed=True) return self.__preserveState() self.__carveUpOutfits() self.__restoreState() self.__setHeaderInitData() self.__setBuyingPanelData() self.refreshCarousel(rebuild=self._needFullRebuild) self.refreshOutfit() self.as_refreshAnchorPropertySheetS() self._needFullRebuild = False def __preserveState(self): self._state.update(modifiedOutfits={season: outfit.copy() for season, outfit in self._modifiedOutfits.iteritems()}) def __restoreState(self): self._modifiedOutfits = self._state.get('modifiedOutfits') self._state.clear() def __onServerSettingChanged(self, diff): if 'isCustomizationEnabled' in diff and not diff.get('isCustomizationEnabled', True): SystemMessages.pushI18nMessage(SYSTEM_MESSAGES.CUSTOMIZATION_UNAVAILABLE, type=SystemMessages.SM_TYPE.Warning) self.__onConfirmCloseWindow(proceed=True) def __setBuyingPanelData(self, *_): purchaseItems = self.getPurchaseItems() cartInfo = getTotalPurchaseInfo(purchaseItems) totalPriceVO = getItemPricesVO(cartInfo.totalPrice) cleanSettings = self._cleanSettings(self._currentSettings, checkSeasons=False) keys = [] if cartInfo.numTotal: keys.append('install') if cartInfo.totalPrice != ITEM_PRICE_EMPTY: self.as_showBuyingPanelS() else: self.as_hideBuyingPanelS() if any(cleanSettings.itervalues()) or not keys: keys.append('apply') label = g_config.i18n['UI_flash_commit_' + '_and_'.join(keys)] isApplyEnabled = bool(cartInfo.numTotal) or any(cleanSettings.itervalues()) shortage = self.itemsCache.items.stats.money.getShortage(cartInfo.totalPrice.price) self.as_setBottomPanelHeaderS({'buyBtnEnabled': isApplyEnabled, 'buyBtnLabel': label, 'enoughMoney': getItemPricesVO(ItemPrice(shortage, shortage))[0], 'pricePanel': totalPriceVO[0]}) def __setSeasonData(self): seasonRenderersList = [] for season in SEASONS_ORDER: seasonName = SEASON_TYPE_TO_NAME.get(season) seasonRenderersList.append({'seasonName': VEHICLE_CUSTOMIZATION.getSeasonName(seasonName), 'seasonIconSmall': RES_ICONS.getSeasonIcon(seasonName)}) self.as_setSeasonPanelDataS({'seasonRenderersList': seasonRenderersList}) # noinspection PyUnusedLocal def __setAnchorsInitData(self, tabIndex, doRegions, update=False): def customizationSlotIdToUid(customizationSlotIdVO): s = struct.pack('bbh', customizationSlotIdVO.areaId, customizationSlotIdVO.slotId, customizationSlotIdVO.regionId) return struct.unpack('I', s)[0] anchorVOs = [] cType = tabToItem(self._tabIndex) for container in self._currentOutfit.containers(): for slot in (x for x in container.slots() if x.getType() == cType): for regionId, region in enumerate(slot.getRegions()): slotId = CustomizationSlotIdVO(container.getAreaID(), slot.getType(), regionId) popoverAlias = CUSTOMIZATION_POPOVER_ALIASES[slot.getType()] item = slot.getItem(regionId) itemIntCD = item.intCD if item is not None else 0 uid = customizationSlotIdToUid(slotId) if self.__getAnchorPositionData(slotId, region) is not None: anchorVOs.append(CustomizationSlotUpdateVO(slotId._asdict(), popoverAlias, itemIntCD, uid)._asdict()) if update: self.as_updateAnchorDataS(CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) else: self.as_setAnchorInitS(CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) def __setHeaderInitData(self): vehicle = g_currentVehicle.item self.as_setHeaderDataS({'tankTier': str(int2roman(vehicle.level)), 'tankName': vehicle.shortUserName, 'tankType': '{}_elite'.format(vehicle.type) if vehicle.isElite else vehicle.type, 'isElite': vehicle.isElite, 'closeBtnTooltip': VEHICLE_CUSTOMIZATION.CUSTOMIZATION_HEADERCLOSEBTN, 'historicVO': self.__getHistoricIndicatorData()}) def __setFooterInitData(self): self.as_setBottomPanelInitDataS( {'tabData': { 'tabData': self.__getItemTabsData(), 'selectedTab': self._tabIndex}, 'tabsAvailableRegions': C11nTabs.AVAILABLE_REGIONS, 'defaultStyleLabel': VEHICLE_CUSTOMIZATION.DEFAULTSTYLE_LABEL, 'carouselInitData': self.__getCarouselInitData(), 'switcherInitData': self.__getSwitcherInitData()}) self.as_setCarouselFiltersInitDataS( {'popoverAlias': VIEW_ALIAS.CUSTOMIZATION_FILTER_POPOVER, 'mainBtn': {'value': RES_ICONS.MAPS_ICONS_BUTTONS_FILTER, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_MAINBTN}, 'hotFilters': [{'value': RES_ICONS.MAPS_ICONS_CUSTOMIZATION_STORAGE_ICON, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_STORAGEBTN, 'selected': self._carouselDP.getOwnedFilter()}, {'value': RES_ICONS.MAPS_ICONS_BUTTONS_EQUIPPED_ICON, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_EQUIPPEDBTN, 'selected': self._carouselDP.getAppliedFilter()}]}) def onSelectHotFilter(self, index, value): (self._carouselDP.setOwnedFilter, self._carouselDP.setAppliedFilter)[index](value) self.refreshCarousel(rebuild=True) def __getSwitcherInitData(self): return {'leftLabel': g_config.i18n['UI_flash_switcher_' + C11nMode.NAMES[self._mode]], 'rightLabel': g_config.i18n['UI_flash_switcher_' + C11nMode.NAMES[not self._mode]], 'leftEvent': 'installStyle' + ('s' if self._mode else ''), 'rightEvent': 'installStyle' + ('s' if not self._mode else ''), 'isLeft': True} def __getHistoricIndicatorData(self): isDefault = all((outfit.isEmpty() for outfit in self._modifiedOutfits.itervalues())) isHistorical = all((outfit.isHistorical() for outfit in self._modifiedOutfits.itervalues())) name = _ms(VEHICLE_CUSTOMIZATION.HISTORICINDICATOR_STYLENAME_CUSTSOMSTYLE) if not isDefault else '' txtStyle = text_styles.stats if isHistorical else text_styles.tutorial return {'historicText': txtStyle(toUpper(name)), 'isDefaultAppearance': isDefault, 'isHistoric': isHistorical, 'tooltip': TOOLTIPS.CUSTOMIZATION_NONHISTORICINDICATOR if not isHistorical else ''} @staticmethod def __getCarouselInitData(): return {'message': '{}{}\n{}'.format(icons.makeImageTag(RES_ICONS.MAPS_ICONS_LIBRARY_ATTENTIONICONFILLED, vSpace=-3), text_styles.neutral(VEHICLE_CUSTOMIZATION.CAROUSEL_MESSAGE_HEADER), text_styles.main(VEHICLE_CUSTOMIZATION.CAROUSEL_MESSAGE_DESCRIPTION))} def __getAnchorPositionData(self, slotId, region): if self._tabIndex in C11nTabs.REGIONS: anchorPos = self.service.getPointForRegionLeaderLine(region) anchorNorm = anchorPos else: anchorPos = self.service.getPointForAnchorLeaderLine(slotId.areaId, slotId.slotId, slotId.regionId) anchorNorm = self.service.getNormalForAnchorLeaderLine(slotId.areaId, slotId.slotId, slotId.regionId) return None if anchorPos is None or anchorNorm is None else AnchorPositionData( cameras.get2DAngleFromCamera(anchorNorm), cameras.projectPoint(anchorPos), slotId) def __getItemTabsData(self): data = [] for tabIdx in self.__getVisibleTabs(): data.append({'label': g_config.i18n['UI_flash_tabs_%s_label' % tabIdx], 'tooltip': makeTooltip(g_config.i18n['UI_flashCol_tabs_%s_text' % tabIdx], g_config.i18n['UI_flashCol_tabs_%s_tooltip' % tabIdx]), 'id': tabIdx}) return data def __getVisibleTabs(self): visibleTabs = [] anchorsData = g_currentVehicle.hangarSpace.getSlotPositions() for tabIdx in C11nTabs.VISIBLE: if self._mode == C11nMode.SETUP and tabIdx not in C11nTabs.CAMO: continue itemTypeID = tabToItem(tabIdx) data = self._carouselDP.getSeasonAndTabData(tabIdx, self._currentSeason) if not data.itemCount: continue if itemTypeID in (GUI_ITEM_TYPE.INSCRIPTION, GUI_ITEM_TYPE.EMBLEM): for areaData in anchorsData.itervalues(): if areaData.get(itemTypeID): hasSlots = True break else: hasSlots = False if not hasSlots: continue visibleTabs.append(tabIdx) return visibleTabs def __onNotifyHangarCameraIdleStateChanged(self, event): isIdle = event.ctx.get('started', False) self.as_cameraAutoRotateChangedS(isIdle) @async @adisp_process def __confirmHeaderNavigation(self, callback): purchaseItems = self.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.numTotal: result = yield DialogsInterface.showI18nConfirmDialog('customization/close') else: result = True callback(result) def __releaseItemSound(self): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.RELEASE) self.itemIsPicked = False def __onSettingsChanged(self, diff): if GAME.HANGAR_CAM_PARALLAX_ENABLED in diff: self.__updateCameraParalaxFlag() def __updateCameraParalaxFlag(self): paralaxEnabled = bool(self.settingsCore.getSetting(GAME.HANGAR_CAM_PARALLAX_ENABLED)) self.as_setParallaxFlagS(paralaxEnabled) def __onInterfaceScaleChanged(self, scale): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setInterfaceScale(scale)
class MainView(CustomizationMainViewMeta): _COMMON_SOUND_SPACE = C11N_SOUND_SPACE _ZOOM_ON_EMBLEM = 0.6 _ZOOM_ON_INSCRIPTION = 0.1 lobbyContext = dependency.descriptor(ILobbyContext) itemsCache = dependency.descriptor(IItemsCache) service = dependency.descriptor(ICustomizationService) hangarSpace = dependency.descriptor(IHangarSpace) def __init__(self, _=None): super(MainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self.__locatedOnEmbelem = False self.itemIsPicked = False self.__propertiesSheet = None self._seasonSoundAnimantion = None self._isPropertySheetShown = False self.__ctx = None self.__renderEnv = None return def showBuyWindow(self): self.changeVisible(False) self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.SELECT) purchaseItems = self.__ctx.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.totalPrice == ITEM_PRICE_EMPTY: self.__ctx.applyItems(purchaseItems) else: self.fireEvent( events.LoadViewEvent(VIEW_ALIAS.CUSTOMIZATION_PURCHASE_WINDOW), EVENT_BUS_SCOPE.LOBBY) def onPressClearBtn(self): self.__ctx.cancelChanges() def onPressEscBtn(self): tabIndex = self.__ctx.currentTab if tabIndex not in C11nTabs.REGIONS and self.__ctx.isAnyAnchorSelected( ) or self.service.isRegionSelected(): self.__clearItem() if self._isPropertySheetShown: self.__hidePropertiesSheet() self.as_enableDNDS(True) else: self.onCloseWindow() def onPressSelectNextItem(self): self.__installNextCarouselItem(shift=1) def onPressSelectPrevItem(self): self.__installNextCarouselItem(shift=-1) def __installNextCarouselItem(self, shift=1): if not self.__ctx.isAnyAnchorSelected( ) or self.__ctx.isCaruselItemSelected(): return else: c11nBottomPanel = self.components[ VIEW_ALIAS.CUSTOMIZATION_BOTTOM_PANEL] tabIndex = self.__ctx.currentTab if tabIndex == C11nTabs.STYLE: item = self.__ctx.modifiedStyle else: item = self.__ctx.getItemFromSelectedRegion() if item is not None: carouselItems = c11nBottomPanel.carouselItems index = carouselItems.index(item.intCD) + shift if 0 <= index < len(carouselItems): intCD = carouselItems[index] self.__ctx.caruselItemSelected(index, intCD) return def changeVisible(self, value): _, slotType, _ = self.__ctx.selectedAnchor self.__ctx.anchorSelected(slotType, -1, -1) self.as_hideS(value) def onReleaseItem(self): self.__ctx.caruselItemUnselected() self.__releaseItemSound() def _onRegisterFlashComponent(self, viewPy, alias): if alias == VIEW_ALIAS.CUSTOMIZATION_PROPERTIES_SHEET: self.__propertiesSheet = viewPy def changeSeason(self, seasonIdx): if seasonIdx in SEASON_IDX_TO_TYPE: self.__ctx.changeSeason(SEASON_IDX_TO_TYPE[seasonIdx]) else: _logger.error('Wrong season index %(seasonIdx)d', {'seasonIdx': seasonIdx}) if self.__ctx.isAnyAnchorSelected(): self.service.selectRegions(ApplyArea.NONE) self.__ctx.anchorSelected(-1, -1, -1) tabIndex = self.__ctx.currentTab if tabIndex not in C11nTabs.REGIONS: self.as_updateSelectedRegionsS(-1) self.as_enableDNDS(True) self.__resetCameraFocus() if self._isPropertySheetShown: self.__hidePropertiesSheet() def __onSeasonChanged(self, seasonType): seasonName = SEASON_TYPE_TO_NAME.get(seasonType) self.soundManager.playInstantSound( SOUNDS.SEASON_SELECT.format(seasonName)) self.__setAnchorsInitData(True) def __onTabChanged(self, tabIndex): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self.service.stopHighlighter() if tabIndex in C11nTabs.REGIONS: itemTypeID = TABS_ITEM_MAPPING[tabIndex] self.service.startHighlighter( chooseMode(itemTypeID, g_currentVehicle.item)) self.__setAnchorsInitData() if self.__locatedOnEmbelem and self.__ctx.c11CameraManager is not None: self.__ctx.c11CameraManager.clearSelectedEmblemInfo() self.__ctx.c11CameraManager.locateCameraToCustomizationPreview() self.__updateAnchorsData() if tabIndex == C11nTabs.STYLE: slotIdVO = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.STYLE, 0)._asdict() elif tabIndex == C11nTabs.EFFECT: slotIdVO = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.MODIFICATION, 0)._asdict() else: slotIdVO = None self.as_updateSelectedRegionsS(slotIdVO) self.__updateDnd() self.__hidePropertiesSheet() return def __onItemsInstalled(self, item, slotId, limitReached): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.APPLY) else: areaId, slotType, regionIdx = self.__ctx.selectedAnchor self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) self.__setHeaderInitData() self.__setSeasonData() self.__setAnchorsInitData(True) if limitReached: self.__clearItem() def __onItemsRemoved(self): self.soundManager.playInstantSound(SOUNDS.REMOVE) self.__setHeaderInitData() self.__setSeasonData() self.__setAnchorsInitData(True) self.__clearItem() def __onModeChanged(self, mode): self.__setHeaderInitData() self.__setSeasonData(True) def fadeOutAnchors(self, isFadeOut): self.fadeAnchorsOut = isFadeOut def onCloseWindow(self): if self.isDisposed(): return if self._isPropertySheetShown: self.__clearItem() if self.__ctx.isOutfitsModified(): DialogsInterface.showDialog( I18nConfirmDialogMeta('customization/close'), self.__onCloseWindow) else: self.__onCloseWindow(proceed=True) def itemContextMenuDisplayed(self): cmHandler = self.app.contextMenuManager.getCurrentHandler() if isinstance(cmHandler, CustomizationItemCMHandler): cmHandler.onSelected += self._itemCtxMenuSelected def onLobbyClick(self): if self.__ctx.currentTab in (C11nTabs.EMBLEM, C11nTabs.INSCRIPTION, C11nTabs.PROJECTION_DECAL): self.__hidePropertiesSheet() self.__clearItem() if not self.__ctx.isCaruselItemSelected(): self.as_enableDNDS(True) def onChangeSize(self): self.__updateAnchorsData() def playCustomSound(self, sound): self.soundManager.playInstantSound(sound) def onSelectAnchor(self, areaId, slotType, regionIdx): if not self.__ctx.isCaruselItemSelected(): self.as_enableDNDS(False) anchorSelected = self.__ctx.isAnchorSelected(slotType=slotType, areaId=areaId, regionIdx=regionIdx) itemInstalled = self.__ctx.anchorSelected(slotType, areaId, regionIdx) self.__hideAnchorSwitchers() if self.__ctx.isSlotFilled(self.__ctx.selectedAnchor): if self.__ctx.isCaruselItemSelected(): if anchorSelected and not itemInstalled: self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) else: self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) else: self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__hidePropertiesSheet() def __locateCameraOnAnchor(self, areaId, slotType, regionIdx): if self.__ctx.c11CameraManager is None: return else: self.__updateAnchorsData() if slotType in (GUI_ITEM_TYPE.EMBLEM, GUI_ITEM_TYPE.INSCRIPTION): if slotType == GUI_ITEM_TYPE.EMBLEM: emblemType = 'player' zoom = MainView._ZOOM_ON_EMBLEM else: emblemType = 'inscription' zoom = MainView._ZOOM_ON_INSCRIPTION self.__locatedOnEmbelem = self.__ctx.c11CameraManager.locateCameraOnEmblem( areaId == Area.HULL, emblemType, regionIdx, zoom) else: anchorParams = self.service.getAnchorParams( areaId, slotType, regionIdx) if slotType == GUI_ITEM_TYPE.PROJECTION_DECAL: self.__locatedOnEmbelem = self.__ctx.c11CameraManager.locateCameraOnAnchor( anchorParams.pos, anchorParams.normal) else: self.__locatedOnEmbelem = self.__ctx.c11CameraManager.locateCameraOnAnchor( anchorParams.pos, None) return def __onItemsBought(self, purchaseItems, results): errorCount = 0 for result in results: if not result.success: errorCount += 1 if result.userMsg: SystemMessages.pushI18nMessage(result.userMsg, type=result.sysMsgType) if not errorCount: cart = getTotalPurchaseInfo(purchaseItems) if cart.totalPrice != ITEM_PRICE_EMPTY: msgCtx = { 'money': formatPrice(cart.totalPrice.price), 'count': cart.numSelected } SystemMessages.pushI18nMessage( MESSENGER. SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONSBUY, type=CURRENCY_TO_SM_TYPE.get( cart.totalPrice.getCurrency(byWeight=True), SM_TYPE.PurchaseForGold), **msgCtx) else: SystemMessages.pushI18nMessage( MESSENGER. SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONS, type=SM_TYPE.Information) self.__onCloseWindow(proceed=True) def onAnchorsShown(self, anchors): if self.__ctx.vehicleAnchorsUpdater is not None: self.__ctx.vehicleAnchorsUpdater.setAnchors(anchors) return def propertiesSheetSet(self, sheet, width, height, crnterX, centerY): if self.__ctx.vehicleAnchorsUpdater is not None: self.__ctx.vehicleAnchorsUpdater.setMenuParams( sheet, width, height, crnterX, centerY) return def _populate(self): super(MainView, self)._populate() self.__ctx = self.service.getCtx() self.__ctx.onCustomizationSeasonChanged += self.__onSeasonChanged self.__ctx.onCustomizationModeChanged += self.__onModeChanged self.__ctx.onCustomizationTabChanged += self.__onTabChanged self.__ctx.onCustomizationItemInstalled += self.__onItemsInstalled self.__ctx.onCustomizationItemsRemoved += self.__onItemsRemoved self.__ctx.onCustomizationItemsBought += self.__onItemsBought self.__ctx.onCacheResync += self.__onCacheResync self.__ctx.onChangesCanceled += self.__onChangesCanceled self.__ctx.onCaruselItemSelected += self.__onCarouselItemSelected self.__ctx.onPropertySheetHidden += self.__onPropertySheetHidden self.__ctx.onPropertySheetShown += self.__onPropertySheetShown self.__ctx.onClearItem += self.__onClearItem self.soundManager.playInstantSound(SOUNDS.ENTER) self.__viewLifecycleWatcher.start(self.app.containerManager, [ _ModalWindowsPopupHandler(), _C11ViewsPopupHandler(self.__hidePropertiesSheet) ]) self.lobbyContext.addHeaderNavigationConfirmator( self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings( ).onServerSettingsChange += self.__onServerSettingChanged self.hangarSpace.onSpaceCreate += self.__onSpaceCreateHandler self.hangarSpace.onSpaceDestroy += self.__onSpaceDestroyHandler self.hangarSpace.onSpaceRefresh += self.__onSpaceRefreshHandler self.service.onRegionHighlighted += self.__onRegionHighlighted self._seasonSoundAnimantion = _SeasonSoundAnimantion( len(SeasonType.COMMON_SEASONS), self.soundManager) self.__setHeaderInitData() self.__setSeasonData() self.__ctx.refreshOutfit() self.as_selectSeasonS(SEASON_TYPE_TO_IDX[self.__ctx.currentSeason]) self.fireEvent( CameraRelatedEvents( CameraRelatedEvents.FORCE_DISABLE_IDLE_PARALAX_MOVEMENT, ctx={'isDisable': True}), EVENT_BUS_SCOPE.LOBBY) self.fireEvent( LobbyHeaderMenuEvent( LobbyHeaderMenuEvent.TOGGLE_VISIBILITY, ctx={'state': HeaderMenuVisibilityState.ONLINE_COUNTER}), EVENT_BUS_SCOPE.LOBBY) self._isPropertySheetShown = False if self.__ctx.c11CameraManager is not None: self.__ctx.c11CameraManager.locateCameraToCustomizationPreview( forceLocate=True) self.__renderEnv = BigWorld.CustomizationEnvironment() self.__renderEnv.enable(True) if self.__ctx.vehicleAnchorsUpdater is not None: self.__ctx.vehicleAnchorsUpdater.setMainView(self.flashObject) return def _dispose(self): self.fireEvent(events.HangarCustomizationEvent( events.HangarCustomizationEvent.RESET_VEHICLE_MODEL_TRANSFORM), scope=EVENT_BUS_SCOPE.LOBBY) self.fireEvent( LobbyHeaderMenuEvent(LobbyHeaderMenuEvent.TOGGLE_VISIBILITY, ctx={'state': HeaderMenuVisibilityState.ALL}), EVENT_BUS_SCOPE.LOBBY) self.fireEvent( CameraRelatedEvents( CameraRelatedEvents.FORCE_DISABLE_IDLE_PARALAX_MOVEMENT, ctx={'isDisable': False}), EVENT_BUS_SCOPE.LOBBY) if g_appLoader.getSpaceID() != _SPACE_ID.LOGIN: self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.EXIT) if self.__ctx.c11CameraManager is not None: if self.__locatedOnEmbelem: self.__ctx.c11CameraManager.clearSelectedEmblemInfo() self.__ctx.c11CameraManager.locateCameraToStartState() self._seasonSoundAnimantion = None self.__renderEnv.enable(False) self.__renderEnv = None self.__viewLifecycleWatcher.stop() self.service.stopHighlighter() self.lobbyContext.deleteHeaderNavigationConfirmator( self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings( ).onServerSettingsChange -= self.__onServerSettingChanged self.hangarSpace.onSpaceCreate -= self.__onSpaceCreateHandler self.hangarSpace.onSpaceDestroy -= self.__onSpaceDestroyHandler self.hangarSpace.onSpaceRefresh -= self.__onSpaceRefreshHandler self.service.onRegionHighlighted -= self.__onRegionHighlighted if g_currentVehicle.item: g_tankActiveCamouflage[ g_currentVehicle.item.intCD] = self.__ctx.currentSeason g_currentVehicle.refreshModel() self.__hidePropertiesSheet() self.__propertiesSheet = None self.__ctx.onPropertySheetShown -= self.__onPropertySheetShown self.__ctx.onPropertySheetHidden -= self.__onPropertySheetHidden self.__ctx.onCaruselItemSelected -= self.__onCarouselItemSelected self.__ctx.onChangesCanceled -= self.__onChangesCanceled self.__ctx.onCacheResync -= self.__onCacheResync self.__ctx.onCustomizationItemsBought -= self.__onItemsBought self.__ctx.onCustomizationItemsRemoved -= self.__onItemsRemoved self.__ctx.onCustomizationItemInstalled -= self.__onItemsInstalled self.__ctx.onCustomizationTabChanged -= self.__onTabChanged self.__ctx.onCustomizationModeChanged -= self.__onModeChanged self.__ctx.onCustomizationSeasonChanged -= self.__onSeasonChanged self.__ctx.onClearItem -= self.__onClearItem self.__ctx = None self.service.destroyCtx() super(MainView, self)._dispose() return @adisp_process def _itemCtxMenuSelected(self, ctxMenuID, itemIntCD): item = self.itemsCache.items.getItemByCD(itemIntCD) if ctxMenuID == CustomizationOptions.BUY: yield DialogsInterface.showDialog(ConfirmC11nBuyMeta(itemIntCD)) elif ctxMenuID == CustomizationOptions.SELL: inventoryCount = self.__ctx.getItemInventoryCount(item) yield DialogsInterface.showDialog( ConfirmC11nSellMeta(itemIntCD, inventoryCount, self.__ctx.sellItem)) elif ctxMenuID == CustomizationOptions.REMOVE_FROM_TANK: if self.__ctx.mode == C11nMode.CUSTOM: self.__ctx.removeItems(False, itemIntCD) else: self.__ctx.removeStyle(itemIntCD) def _getUpdatedAnchorsData(self): tabIndex = self.__ctx.currentTab cType = TABS_ITEM_MAPPING[tabIndex] slotIds = [] if tabIndex == C11nTabs.STYLE: slotId = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.STYLE, 0) slotIds.append(slotId) else: for areaId in Area.ALL: regionsIndexes = getAppliedRegionsForCurrentHangarVehicle( areaId, cType) for regionsIndex in regionsIndexes: slotId = CustomizationSlotIdVO(areaId, cType, regionsIndex) slotIds.append(slotId) anchorVOs = [] for zIdx, slotId in enumerate(slotIds): anchorVOs.append( CustomizationAnchorPositionVO(zIdx, slotId._asdict())._asdict()) return CustomizationAnchorsSetVO(anchorVOs)._asdict() def __updateAnchorsData(self): self.as_setAnchorsDataS(self._getUpdatedAnchorsData()) def __onRegionHighlighted(self, slotType, areaId, regionIdx, highlightingType, highlightingResult): region = None if self.__ctx.currentTab == C11nTabs.EFFECT: areaId = Area.MISC slotType = GUI_ITEM_TYPE.MODIFICATION if areaId != -1 and regionIdx != -1: region = CustomizationSlotIdVO(areaId, slotType, regionIdx)._asdict() else: self.__hidePropertiesSheet() self.as_onRegionHighlightedS(region, highlightingType, highlightingResult) if highlightingType: if highlightingResult: anchorSelected = self.__ctx.isAnchorSelected( slotType=slotType, areaId=areaId, regionIdx=regionIdx) itemInstalled = self.__ctx.anchorSelected( slotType, areaId, regionIdx) slotFilled = self.__ctx.isSlotFilled(self.__ctx.selectedAnchor) if self.__ctx.currentTab in (C11nTabs.EFFECT, C11nTabs.STYLE): applyArea = ApplyArea.ALL else: applyArea = appliedToFromSlotsIds( [self.__ctx.selectedAnchor]) if self.__ctx.isCaruselItemSelected(): self.service.highlightRegions(self.__ctx.getEmptyRegions()) if slotFilled and anchorSelected and not itemInstalled: self.service.selectRegions(applyArea) self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) self.soundManager.playInstantSound(SOUNDS.CHOOSE) else: self.service.selectRegions(ApplyArea.NONE) self.__hidePropertiesSheet() self.soundManager.playInstantSound(SOUNDS.CHOOSE) else: if slotFilled: self.__locateCameraOnAnchor(areaId, slotType, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) else: self.__resetCameraFocus() self.__hidePropertiesSheet() self.service.selectRegions(applyArea) else: self.__clearItem() elif highlightingResult: self.soundManager.playInstantSound(SOUNDS.HOVER) return def __onSpaceCreateHandler(self): Waiting.hide(_WAITING_MESSAGE) self.__ctx.refreshOutfit() self.__updateAnchorsData() def __onSpaceDestroyHandler(self, _): Waiting.hide(_WAITING_MESSAGE) self.__onCloseWindow(proceed=True) def __onSpaceRefreshHandler(self): Waiting.show(_WAITING_MESSAGE) def __onCloseWindow(self, proceed): if proceed: if self._isPropertySheetShown: self.__clearItem() self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY) def __onCacheResync(self, *_): if not g_currentVehicle.isPresent(): self.__onCloseWindow(proceed=True) return self.__setHeaderInitData() self.__setSeasonData() def __onChangesCanceled(self): self.__setHeaderInitData() self.__setSeasonData() self.__setAnchorsInitData(True) self.__hidePropertiesSheet() self.__clearItem() def __onCarouselItemSelected(self, index, intCD): tabIndex = self.__ctx.currentTab if tabIndex == C11nTabs.STYLE or tabIndex == C11nTabs.EFFECT: self.service.selectRegions(ApplyArea.ALL) areaId, slotType, regionIdx = self.__ctx.selectedAnchor self.onSelectAnchor(areaId, slotType, regionIdx) if not self.__propertiesSheet.isVisible and not self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.PICK) self.itemIsPicked = True if self.__ctx.isAnyAnchorSelected( ) and not self.__ctx.isCaruselItemSelected(): areaId, slotType, regionIdx = self.__ctx.selectedAnchor self.__showPropertiesSheet(areaId, slotType, regionIdx) def __onServerSettingChanged(self, diff): if 'isCustomizationEnabled' in diff and not diff.get( 'isCustomizationEnabled', True): SystemMessages.pushI18nMessage( SYSTEM_MESSAGES.CUSTOMIZATION_UNAVAILABLE, type=SystemMessages.SM_TYPE.Warning) self.__onCloseWindow(proceed=True) def __onPropertySheetShown(self): self._isPropertySheetShown = True self.__updateDnd() def __onPropertySheetHidden(self): tabIndex = self.__ctx.currentTab if tabIndex in C11nTabs.REGIONS: self.service.resetHighlighting() else: self.__hideAnchorSwitchers() self._isPropertySheetShown = False self.__updateDnd() def __updateDnd(self): isDndEnable = False if not self._isPropertySheetShown: isDndEnable = self.__ctx.currentTab not in DRAG_AND_DROP_INACTIVE_TABS self.as_enableDNDS(isDndEnable) def __setSeasonData(self, forceAnim=False): seasonRenderersList = [] filledSeasonSlots = 0 for season in SEASONS_ORDER: seasonName = SEASON_TYPE_TO_NAME.get(season) if self.__ctx.mode == C11nMode.CUSTOM: isFilled = self.__ctx.checkSlotsFillingForSeason(season) else: isFilled = self.__ctx.modifiedStyle is not None filledSeasonSlots += int(isFilled) seasonRenderersList.append({ 'nameText': VEHICLE_CUSTOMIZATION.getSeasonName(seasonName), 'nameSelectedText': VEHICLE_CUSTOMIZATION.getSeasonSelectedName(seasonName), 'seasonImageSrc': RES_ICONS.getSeasonImage(seasonName), 'seasonBGImageSrc': RES_ICONS.getSeasonBGImage(seasonName), 'seasonShineImageSrc': RES_ICONS.getSeasonShineImage(seasonName), 'isFilled': isFilled, 'forceAnim': forceAnim, 'tooltip': makeTooltip( body=VEHICLE_CUSTOMIZATION.getSheetSeasonName(seasonName)) }) self.as_setSeasonsBarDataS(seasonRenderersList) self._seasonSoundAnimantion.setFilledSeasonSlots( filledSeasonSlots, forceAnim) return def __setAnchorsInitData(self, update=False): def customizationSlotIdToUid(customizationSlotIdVO): s = struct.pack('bbh', customizationSlotIdVO.areaId, customizationSlotIdVO.slotId, customizationSlotIdVO.regionId) return struct.unpack('I', s)[0] tabIndex = self.__ctx.currentTab anchorVOs = [] cType = TABS_ITEM_MAPPING[tabIndex] maxItemsReached = False if tabIndex == C11nTabs.STYLE: anchorId = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.STYLE, 0) uid = customizationSlotIdToUid(anchorId) anchorVOs.append( CustomizationSlotUpdateVO( anchorId._asdict(), self.__ctx.modifiedStyle.intCD if self.__ctx.modifiedStyle is not None else 0, uid, None)._asdict()) else: potentialPlaceTooltip = None if cType in QUANTITY_LIMITED_CUSTOMIZATION_TYPES: outfit = self.__ctx.getModifiedOutfit(self.__ctx.currentSeason) if self.__ctx.isC11nItemsQuantityLimitReached(outfit, cType): maxItemsReached = True potentialPlaceTooltip = makeTooltip( VEHICLE_CUSTOMIZATION. CUSTOMIZATION_TOOLTIP_POTENTIALPROJDECALPLACE_TITLE, VEHICLE_CUSTOMIZATION. CUSTOMIZATION_TOOLTIP_POTENTIALPROJDECALPLACE_TEXT) for areaId in Area.ALL: regionsIndexes = getAppliedRegionsForCurrentHangarVehicle( areaId, cType) slot = self.__ctx.currentOutfit.getContainer(areaId).slotFor( cType) for regionsIndex in regionsIndexes: anchorId = CustomizationSlotIdVO(areaId, cType, regionsIndex) slotId = self.__ctx.getSlotIdByAnchorId( C11nId(areaId=areaId, slotType=cType, regionIdx=regionsIndex)) itemIntCD = 0 if slotId is not None: item = slot.getItem(slotId.regionIdx) itemIntCD = item.intCD if item is not None else 0 tooltip = None if not itemIntCD: tooltip = potentialPlaceTooltip uid = customizationSlotIdToUid(anchorId) anchorVOs.append( CustomizationSlotUpdateVO(anchorId._asdict(), itemIntCD, uid, tooltip)._asdict()) if tabIndex in C11nTabs.REGIONS: typeRegions = CUSTOMIZATION_ALIASES.ANCHOR_TYPE_REGION elif tabIndex == C11nTabs.PROJECTION_DECAL: typeRegions = CUSTOMIZATION_ALIASES.ANCHOR_TYPE_PROJECTION_DECAL else: typeRegions = CUSTOMIZATION_ALIASES.ANCHOR_TYPE_DECAL if update: self.as_updateAnchorDataS( CustomizationAnchorInitVO(anchorVOs, typeRegions, maxItemsReached)._asdict()) else: self.as_setAnchorInitS( CustomizationAnchorInitVO(anchorVOs, typeRegions, maxItemsReached)._asdict()) return def __setHeaderInitData(self): vehicle = g_currentVehicle.item self.as_setHeaderDataS({ 'tankTier': str(int2roman(vehicle.level)), 'tankName': vehicle.shortUserName, 'tankType': '{}_elite'.format(vehicle.type) if vehicle.isElite else vehicle.type, 'isElite': vehicle.isElite, 'closeBtnTooltip': VEHICLE_CUSTOMIZATION.CUSTOMIZATION_HEADERCLOSEBTN }) def __showPropertiesSheet(self, areaId, slotType, regionIdx): if self.__propertiesSheet: if self.__ctx.vehicleAnchorsUpdater is not None: self.__ctx.vehicleAnchorsUpdater.attachMenuToAnchor( self.__ctx.selectedAnchor) if self.__ctx.currentTab in C11nTabs.REGIONS: self.__ctx.vehicleAnchorsUpdater.changeAnchorParams( self.__ctx.selectedAnchor, True, False) if self.__propertiesSheet.isVisible: self.soundManager.playInstantSound(SOUNDS.CHOOSE) self.__propertiesSheet.show(areaId, slotType, regionIdx) tabIndex = self.__ctx.currentTab if tabIndex not in C11nTabs.REGIONS: self.__showAnchorSwitchers(tabIndex == C11nTabs.EMBLEM) return def __hidePropertiesSheet(self): if self.__propertiesSheet: if self.__ctx.vehicleAnchorsUpdater is not None and self.__ctx.currentTab in C11nTabs.REGIONS: self.__ctx.vehicleAnchorsUpdater.changeAnchorParams( self.__ctx.selectedAnchor, True, True) self.__propertiesSheet.hide() return def getItemTabsData(self): data = [] pluses = [] for tabIdx in self.__ctx.visibleTabs: itemTypeID = TABS_ITEM_MAPPING[tabIdx] typeName = GUI_ITEM_TYPE_NAMES[itemTypeID] showPlus = not self.__checkSlotsFilling(itemTypeID, self._currentSeason) data.append({ 'label': _ms(ITEM_TYPES.customizationPlural(typeName)), 'tooltip': makeTooltip(ITEM_TYPES.customizationPlural(typeName), TOOLTIPS.customizationItemTab(typeName)), 'id': tabIdx }) pluses.append(showPlus) return (data, pluses) @async @adisp_process def __confirmHeaderNavigation(self, callback): if self._isPropertySheetShown: self.__clearItem() if self.__ctx.isOutfitsModified(): result = yield DialogsInterface.showI18nConfirmDialog( 'customization/close') else: result = True if result: self.__onCloseWindow(proceed=True) callback(result) def __releaseItemSound(self): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.RELEASE) self.itemIsPicked = False def __resetCameraFocus(self): if self.__locatedOnEmbelem: if self.__ctx.c11CameraManager is not None: self.__ctx.c11CameraManager.clearSelectedEmblemInfo() self.__ctx.c11CameraManager.locateCameraToCustomizationPreview( preserveAngles=True) self.__updateAnchorsData() self.__locatedOnEmbelem = False return def __resetUIFocus(self): self.as_onRegionHighlightedS(-1, True, False) def __onClearItem(self): self.__clearItem() def __clearItem(self): self.service.highlightRegions(ApplyArea.NONE) self.service.selectRegions(ApplyArea.NONE) self.__resetCameraFocus() _, slotType, _ = self.__ctx.selectedAnchor self.__ctx.anchorSelected(slotType, -1, -1) self.__resetUIFocus() self.as_releaseItemS() def __hideAnchorSwitchers(self, anchor=None): if anchor is not None: areaId, slotType, regionIdx = anchor else: areaId, slotType, regionIdx = (-1, -1, -1) self.as_setAnchorSwitchersVisibleS( False, CustomizationSlotIdVO(areaId, slotType, regionIdx)._asdict()) return def __showAnchorSwitchers(self, isNarrowSlot): areaId, slotType, regionIdx = self.__ctx.selectedAnchor self.as_setAnchorSwitchersVisibleS( True, CustomizationSlotIdVO(areaId, slotType, regionIdx)._asdict(), isNarrowSlot)
class MainView(CustomizationMainViewMeta): _COMMON_SOUND_SPACE = C11N_SOUND_SPACE lobbyContext = dependency.descriptor(ILobbyContext) itemsCache = dependency.descriptor(IItemsCache) service = dependency.descriptor(ICustomizationService) settingsCore = dependency.descriptor(ISettingsCore) def __init__(self, _=None): super(MainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self._currentSeason = SeasonType.SUMMER self._tabIndex = C11nTabs.PAINT self._lastTab = C11nTabs.PAINT self._originalStyle = None self._modifiedStyle = None self._isCurrentStyleInstalled = False self._originalOutfits = {} self._modifiedOutfits = {} self._currentOutfit = None self._mode = C11nMode.CUSTOM self._isDeferredRenderer = True self.__anchorPositionCallbackID = None self._state = {} self._needFullRebuild = False self.__locatedOnEmbelem = False self.itemIsPicked = False self._vehicleCustomizationAnchorsUpdater = None return def showBuyWindow(self): self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.SELECT) purchaseItems = self.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.totalPrice == ITEM_PRICE_EMPTY: self.buyAndExit(purchaseItems) else: self.as_hideAnchorPropertySheetS() self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.CUSTOMIZATION_PURCHASE_WINDOW), EVENT_BUS_SCOPE.LOBBY) def onSelectItem(self, index): self._carouselDP.selectItemIdx(index) self.soundManager.playInstantSound(SOUNDS.SELECT) def onPickItem(self): if not self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.PICK) self.itemIsPicked = True def onReleaseItem(self): self.__releaseItemSound() def changeSeason(self, seasonIdx): self._currentSeason = SEASON_IDX_TO_TYPE[seasonIdx] seasonName = SEASON_TYPE_TO_NAME.get(self._currentSeason) self.soundManager.playInstantSound(SOUNDS.SEASON_SELECT.format(seasonName)) self.refreshOutfit() self.refreshCarousel(rebuild=True) self.as_refreshAnchorPropertySheetS() doRegions = self._tabIndex in C11nTabs.REGIONS self.__setAnchorsInitData(self._tabIndex, doRegions, True) def refreshCarousel(self, rebuild=False): if rebuild: self._carouselDP.buildList(self._tabIndex, self._currentSeason, refresh=False) self.as_setCarouselDataS(self._buildCustomizationCarouselDataVO()) self._carouselDP.refresh() def refreshHotFilters(self): self.as_setCarouselFiltersDataS({'hotFilters': [self._carouselDP.getOwnedFilter(), self._carouselDP.getAppliedFilter()]}) def refreshOutfit(self): if self._mode == C11nMode.STYLE: if self._modifiedStyle: self._currentOutfit = self._modifiedStyle.getOutfit(self._currentSeason) else: self._currentOutfit = self.service.getEmptyOutfit() else: self._currentOutfit = self._modifiedOutfits[self._currentSeason] self.service.tryOnOutfit(self._currentOutfit) g_tankActiveCamouflage[g_currentVehicle.item.intCD] = self._currentSeason def showGroupFromTab(self, tabIndex): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self._tabIndex = tabIndex doRegions = self._tabIndex in C11nTabs.REGIONS self.service.stopHighlighter() if doRegions: itemTypeID = TABS_ITEM_MAPPING[self._tabIndex] self.service.startHighlighter(chooseMode(itemTypeID, g_currentVehicle.item)) self.__setAnchorsInitData(self._tabIndex, doRegions) if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__updateAnchorPositions() if self._tabIndex == C11nTabs.STYLE: slotIdVO = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0)._asdict() elif self._tabIndex == C11nTabs.EFFECT: slotIdVO = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.MODIFICATION, 0)._asdict() else: slotIdVO = None self.as_updateSelectedRegionsS(slotIdVO) self.refreshCarousel(rebuild=True) return def installCustomizationElement(self, intCD, areaId, slotId, regionId, seasonIdx): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.APPLY) item = self.itemsCache.items.getItemByCD(intCD) if item.isHidden and not self.getItemInventoryCount(item): SystemMessages.pushI18nMessage(SYSTEM_MESSAGES.CUSTOMIZATION_PROHIBITED, type=SystemMessages.SM_TYPE.Warning, itemName=item.userName) return if self._mode == C11nMode.STYLE: self._modifiedStyle = item else: season = SEASON_IDX_TO_TYPE.get(seasonIdx, self._currentSeason) outfit = self._modifiedOutfits[season] outfit.getContainer(areaId).slotFor(slotId).set(item, idx=regionId) outfit.invalidate() self.refreshOutfit() self.__setBuyingPanelData() self.__setHeaderInitData() self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) def clearCustomizationItem(self, areaId, slotId, regionId, seasonIdx): self.soundManager.playInstantSound(SOUNDS.REMOVE) season = SEASON_IDX_TO_TYPE.get(seasonIdx, self._currentSeason) outfit = self._modifiedOutfits[season] outfit.getContainer(areaId).slotFor(slotId).remove(idx=regionId) self.refreshOutfit() doRegions = self._tabIndex in C11nTabs.REGIONS self.__setAnchorsInitData(self._tabIndex, doRegions, True) self.__setBuyingPanelData() self.__setHeaderInitData() self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) def switchToCustom(self, updateUI=True): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self._mode = C11nMode.CUSTOM self._tabIndex = self._lastTab self.refreshOutfit() self.as_setBottomPanelTabsDataS({'tabData': self.__getItemTabsData(), 'selectedTab': self._tabIndex}) self._carouselDP.selectItem() self.__setBuyingPanelData() self.__setHeaderInitData() def switchToStyle(self): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self._mode = C11nMode.STYLE self._lastTab = self._tabIndex self._tabIndex = C11nTabs.STYLE self.refreshOutfit() self.as_setBottomPanelTabsDataS({'tabData': self.__getItemTabsData(), 'selectedTab': self._tabIndex}) self._carouselDP.selectItem() self.__setBuyingPanelData() self.__setHeaderInitData() def fadeOutAnchors(self, isFadeOut): self.fadeAnchorsOut = isFadeOut def closeWindow(self): purchaseItems = self.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.numTotal: DialogsInterface.showDialog(I18nConfirmDialogMeta('customization/close'), self.__onConfirmCloseWindow) else: self.__onConfirmCloseWindow(proceed=True) def itemContextMenuDisplayed(self): cmHandler = self.app.contextMenuManager.getCurrentHandler() if isinstance(cmHandler, CustomizationItemCMHandler): cmHandler.onSelected += self._itemCtxMenuSelected def resetFilter(self): self.clearFilter() self.refreshFilterData() self.refreshHotFilters() self.refreshCarousel(rebuild=True) def clearFilter(self): self._carouselDP.clearFilter() def refreshFilterData(self): self.as_setFilterDataS(self._carouselDP.getFilterData()) def getHistoricalPopoverData(self): self.soundManager.playInstantSound(SOUNDS.SELECT) if self._mode == C11nMode.STYLE and self._modifiedStyle: if not self._modifiedStyle.isHistorical(): return {'items': [self._modifiedStyle.intCD]} return {'items': []} items = [] for outfit in self._modifiedOutfits.itervalues(): items.extend((item for item in outfit.items() if not item.isHistorical())) return {'items': [ item.intCD for item in sorted(items, key=comparisonKey) ]} def removeItems(self, *intCDs): self.soundManager.playInstantSound(SOUNDS.REMOVE) if self._modifiedStyle and self._modifiedStyle.intCD in intCDs: self._modifiedStyle = None for outfit in self._modifiedOutfits.itervalues(): for slot in outfit.slots(): for idx in range(slot.capacity()): item = slot.getItem(idx) if item and item.intCD in intCDs: slot.remove(idx) self.refreshOutfit() self.__setHeaderInitData() self.__setBuyingPanelData() self.as_refreshAnchorPropertySheetS() doRegions = self._tabIndex in C11nTabs.REGIONS self.__setAnchorsInitData(self._tabIndex, doRegions, True) self.refreshCarousel(rebuild=self._carouselDP.getAppliedFilter() or self._carouselDP.getOwnedFilter()) return def updatePropertySheetButtons(self, areaId, slotId, regionId): self.service.onPropertySheetShow(areaId, slotId, regionId) def onLobbyClick(self): if self._tabIndex in (C11nTabs.EMBLEM, C11nTabs.INSCRIPTION): self.as_hideAnchorPropertySheetS() if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__updateAnchorPositions() self.__locatedOnEmbelem = False def setEnableMultiselectRegions(self, isEnabled): pass def onChangeSize(self): self.__updateAnchorPositions() def onSelectAnchor(self, areaID, regionID): if g_hangarSpace.spaceInited: self.soundManager.playInstantSound(SOUNDS.CHOOSE) if self._tabIndex == C11nTabs.EMBLEM: emblemType = 'player' zoom = 0.06 else: emblemType = 'inscription' zoom = 0.1 self.__updateAnchorPositions() self.__locatedOnEmbelem = g_hangarSpace.space.locateCameraOnEmblem(areaID < 2, emblemType, regionID, zoom) self.as_cameraAutoRotateChangedS(True) BigWorld.callback(5, self.__cameraRotationFinished) def __cameraRotationFinished(self): self.as_cameraAutoRotateChangedS(False) def getOutfitsInfo(self): outfitsInfo = {} for season in SEASONS_ORDER: outfitsInfo[season] = OutfitInfo(self._originalOutfits[season], self._modifiedOutfits[season]) return outfitsInfo def getStyleInfo(self): return OutfitInfo(self._originalStyle, self._modifiedStyle) def getPurchaseItems(self): return getCustomPurchaseItems(self.getOutfitsInfo()) if self._mode == C11nMode.CUSTOM else getStylePurchaseItems(self.getStyleInfo(), self._isCurrentStyleInstalled) def getItemInventoryCount(self, item): return getItemInventoryCount(item, self.getOutfitsInfo()) if self._mode == C11nMode.CUSTOM else getStyleInventoryCount(item, self.getStyleInfo()) def getCurrentOutfit(self): return self._currentOutfit def getModifiedStyle(self): return self._modifiedStyle def getModifiedOutfit(self, season): return self._modifiedOutfits.get(season) def getMode(self): return self._mode def getCurrentSeason(self): return self._currentSeason def getCurrentTab(self): return self._tabIndex def getAppliedItems(self, isOriginal=True): outfits = self._originalOutfits if isOriginal else self._modifiedOutfits style = self._originalStyle if isOriginal else self._modifiedStyle seasons = SeasonType.COMMON_SEASONS if isOriginal else (self._currentSeason,) appliedItems = set() for seasonType in seasons: outfit = outfits[seasonType] appliedItems.update((i.intCD for i in outfit.items())) if style: appliedItems.add(style.intCD) return appliedItems def isItemInOutfit(self, item): return any((outfit.has(item) for outfit in self._originalOutfits.itervalues())) or any((outfit.has(item) for outfit in self._modifiedOutfits.itervalues())) @process('buyAndInstall') def buyAndExit(self, purchaseItems): self.itemsCache.onSyncCompleted -= self.__onCacheResync cart = getTotalPurchaseInfo(purchaseItems) groupHasItems = {AdditionalPurchaseGroups.STYLES_GROUP_ID: False, SeasonType.WINTER: False, SeasonType.SUMMER: False, SeasonType.DESERT: False} modifiedOutfits = {season:outfit.copy() for season, outfit in self._modifiedOutfits.iteritems()} results = [] for pItem in purchaseItems: if not pItem.selected: if pItem.slot: slot = modifiedOutfits[pItem.group].getContainer(pItem.areaID).slotFor(pItem.slot) slot.remove(pItem.regionID) groupHasItems[pItem.group] = True if self._mode == C11nMode.CUSTOM: groupHasItems[self._currentSeason] = True empty = self.service.getEmptyOutfit() for season in SeasonType.COMMON_SEASONS: if groupHasItems[season]: yield OutfitApplier(g_currentVehicle.item, empty, season).request() for season in SeasonType.COMMON_SEASONS: if groupHasItems[season]: outfit = modifiedOutfits[season] result = yield OutfitApplier(g_currentVehicle.item, outfit, season).request() results.append(result) if groupHasItems[AdditionalPurchaseGroups.STYLES_GROUP_ID]: result = yield StyleApplier(g_currentVehicle.item, self._modifiedStyle).request() results.append(result) errorCount = 0 for result in results: if not result.success: errorCount += 1 if result.userMsg: SystemMessages.pushI18nMessage(result.userMsg, type=result.sysMsgType) if not errorCount: if cart.totalPrice != ITEM_PRICE_EMPTY: msgCtx = {'money': formatPrice(cart.totalPrice.price), 'count': cart.numSelected} SystemMessages.pushI18nMessage(MESSENGER.SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONSBUY, type=CURRENCY_TO_SM_TYPE.get(cart.totalPrice.getCurrency(byWeight=True), SM_TYPE.PurchaseForGold), **msgCtx) else: SystemMessages.pushI18nMessage(MESSENGER.SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONS, type=SM_TYPE.Information) self.__onConfirmCloseWindow(proceed=True) else: self.__onCacheResync() self.itemsCache.onSyncCompleted += self.__onCacheResync @process('sellItem') def sellItem(self, intCD, count): if not count: return self._needFullRebuild = self._carouselDP.getOwnedFilter() item = self.itemsCache.items.getItemByCD(intCD) if item.fullInventoryCount(g_currentVehicle.item) < count: if self._mode == C11nMode.CUSTOM: for season, outfit in getOutfitWithoutItems(self.getOutfitsInfo(), intCD, count): yield OutfitApplier(g_currentVehicle.item, outfit, season).request() else: yield StyleApplier(g_currentVehicle.item).request() yield CustomizationsSeller(g_currentVehicle.item, item, count).request() nextTick(self.refreshOutfit)() def onAnchorsShown(self, anchors): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setAnchors(anchors, self._tabIndex in C11nTabs.REGIONS) return def _populate(self): super(MainView, self)._populate() self.soundManager.playInstantSound(SOUNDS.ENTER) self.__viewLifecycleWatcher.start(self.app.containerManager, [_C11nWindowsLifecycleHandler()]) self._isDeferredRenderer = self.settingsCore.getSetting(GRAPHICS.RENDER_PIPELINE) == 0 g_clientUpdateManager.addMoneyCallback(self.__setBuyingPanelData) self.lobbyContext.addHeaderNavigationConfirmator(self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingChanged self.service.onCarouselFilter += self.__onCarouselFilter self.service.onRemoveItems += self.removeItems self.service.onOutfitChanged += self.__onOutfitChanged g_eventBus.addListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) g_hangarSpace.onSpaceCreate += self.__onSpaceCreateHandler g_hangarSpace.onSpaceDestroy += self.__onSpaceDestroyHandler g_hangarSpace.onSpaceRefresh += self.__onSpaceRefreshHandler self.service.onRegionHighlighted += self.__onRegionHighlighted self.itemsCache.onSyncCompleted += self.__onCacheResync self.__carveUpOutfits() if self._originalStyle and self._isCurrentStyleInstalled: self._mode = C11nMode.STYLE elif self._originalOutfits[self._currentSeason].isInstalled(): self._mode = C11nMode.CUSTOM else: self._mode = C11nMode.STYLE self._carouselDP = CustomizationCarouselDataProvider(g_currentVehicle, self._carouseItemWrapper, self) self._carouselDP.setFlashObject(self.as_getDataProviderS()) self._carouselDP.setEnvironment(self.app) self.__setHeaderInitData() self.__setFooterInitData() self.__setBuyingPanelData() self.__setSeasonData() self._vehicleCustomizationAnchorsUpdater = _VehicleCustomizationAnchorsUpdater(self.service) self._vehicleCustomizationAnchorsUpdater.startUpdater(self.settingsCore.interfaceScale.get()) self.refreshOutfit() self.settingsCore.interfaceScale.onScaleExactlyChanged += self.__onInterfaceScaleChanged self.settingsCore.onSettingsChanged += self.__onSettingsChanged self.__updateCameraParalaxFlag() def _dispose(self): if g_appLoader.getSpaceID() != _SPACE_ID.LOGIN: self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.EXIT) self.settingsCore.onSettingsChanged -= self.__onSettingsChanged self.settingsCore.interfaceScale.onScaleExactlyChanged -= self.__onInterfaceScaleChanged self._vehicleCustomizationAnchorsUpdater.stopUpdater() self._vehicleCustomizationAnchorsUpdater = None if self.__locatedOnEmbelem and g_hangarSpace.spaceInited: space = g_hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToPreview() self.__viewLifecycleWatcher.stop() self.service.stopHighlighter() g_clientUpdateManager.removeObjectCallbacks(self) self.lobbyContext.deleteHeaderNavigationConfirmator(self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings().onServerSettingsChange -= self.__onServerSettingChanged self.service.onCarouselFilter -= self.__onCarouselFilter self.service.onRemoveItems -= self.removeItems self.service.onOutfitChanged -= self.__onOutfitChanged g_eventBus.removeListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) g_hangarSpace.onSpaceCreate -= self.__onSpaceCreateHandler g_hangarSpace.onSpaceDestroy -= self.__onSpaceDestroyHandler g_hangarSpace.onSpaceRefresh -= self.__onSpaceRefreshHandler self.service.onRegionHighlighted -= self.__onRegionHighlighted self.itemsCache.onSyncCompleted -= self.__onCacheResync if g_currentVehicle.item: g_tankActiveCamouflage[g_currentVehicle.item.intCD] = self._currentSeason g_currentVehicle.refreshModel() self._isCurrentStyleInstalled = False super(MainView, self)._dispose() return @adisp_process def _itemCtxMenuSelected(self, ctxMenuID, itemIntCD): item = self.itemsCache.items.getItemByCD(itemIntCD) if ctxMenuID == CustomizationOptions.BUY: yield DialogsInterface.showDialog(ConfirmC11nBuyMeta(itemIntCD)) elif ctxMenuID == CustomizationOptions.SELL: inventoryCount = self.getItemInventoryCount(item) yield DialogsInterface.showDialog(ConfirmC11nSellMeta(itemIntCD, inventoryCount, self.sellItem)) elif ctxMenuID == CustomizationOptions.REMOVE_FROM_TANK: self.removeItems(itemIntCD) def _getUpdatedAnchorPositions(self): anchorVOs = [] anchorPosData = [] cType = TABS_ITEM_MAPPING[self._tabIndex] if self._tabIndex == C11nTabs.STYLE: slotId = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0) anchorData = self.__getAnchorPositionData(slotId, 0) anchorPosData.append(anchorData) else: outfit = self.service.getEmptyOutfit() for container in outfit.containers(): for slot in (x for x in container.slots() if x.getType() == cType): for regionId, region in enumerate(slot.getRegions()): slotId = CustomizationSlotIdVO(container.getAreaID(), slot.getType(), regionId) anchorData = self.__getAnchorPositionData(slotId, region) if anchorData is not None: anchorPosData.append(anchorData) for zIdx, posData in enumerate(anchorPosData): anchorVOs.append(CustomizationAnchorPositionVO(zIdx, posData.slotId._asdict())._asdict()) return CustomizationAnchorsSetVO(anchorVOs)._asdict() def _buildCustomizationCarouselDataVO(self): isZeroCount = self._carouselDP.itemCount == 0 countStyle = text_styles.error if isZeroCount else text_styles.main displayString = text_styles.main('{} / {}'.format(countStyle(str(self._carouselDP.itemCount)), str(self._carouselDP.totalItemCount))) shouldShow = self._carouselDP.itemCount < self._carouselDP.totalItemCount return CustomizationCarouselDataVO(displayString, isZeroCount, shouldShow, itemLayoutSize=self._carouselDP.getItemSizeData(), bookmarks=self._carouselDP.getBookmarkData())._asdict() def _carouseItemWrapper(self, itemCD): item = self.itemsCache.items.getItemByCD(itemCD) itemInventoryCount = self.getItemInventoryCount(item) if item.itemTypeID == GUI_ITEM_TYPE.MODIFICATION: showUnsupportedAlert = not self._isDeferredRenderer else: showUnsupportedAlert = False isCurrentlyApplied = itemCD in self._carouselDP.getCurrentlyApplied() return buildCustomizationItemDataVO(item, itemInventoryCount, showUnsupportedAlert=showUnsupportedAlert, isCurrentlyApplied=isCurrentlyApplied) def __carveUpOutfits(self): for season in SeasonType.COMMON_SEASONS: outfit = self.service.getCustomOutfit(season) self._modifiedOutfits[season] = outfit.copy() if outfit.isInstalled(): self._originalOutfits[season] = outfit.copy() self._originalOutfits[season] = self.service.getEmptyOutfit() for slot in self._modifiedOutfits[season].slots(): for idx in range(slot.capacity()): item = slot.getItem(idx) if item and item.isHidden and item.fullInventoryCount(g_currentVehicle.item) == 0: slot.remove(idx) style = self.service.getCurrentStyle() self._isCurrentStyleInstalled = self.service.isCurrentStyleInstalled() if self._isCurrentStyleInstalled: self._originalStyle = style self._modifiedStyle = style else: self._originalStyle = None if style and style.isHidden and style.fullInventoryCount(g_currentVehicle.item) == 0: self._modifiedStyle = None else: self._modifiedStyle = style return def __updateAnchorPositions(self, _=None): self.as_setAnchorPositionsS(self._getUpdatedAnchorPositions()) def __onRegionHighlighted(self, typeID, tankPartID, regionID, selected, hovered): slotId = None if hovered: self.soundManager.playInstantSound(SOUNDS.HOVER) return else: if self._tabIndex == C11nTabs.EFFECT: tankPartID = Area.MISC typeID = GUI_ITEM_TYPE.MODIFICATION if tankPartID != -1 and regionID != -1: slotId = CustomizationSlotIdVO(tankPartID, typeID, regionID)._asdict() if selected: self.soundManager.playInstantSound(SOUNDS.CHOOSE) self.as_onRegionHighlightedS(slotId) return def __onSpaceCreateHandler(self): Waiting.hide('loadHangarSpace') self.refreshOutfit() self.__updateAnchorPositions() def __onSpaceDestroyHandler(self, _): Waiting.hide('loadHangarSpace') self.__onConfirmCloseWindow(proceed=True) def __onSpaceRefreshHandler(self): Waiting.show('loadHangarSpace') def __onConfirmCloseWindow(self, proceed): if proceed: self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY) def __onCarouselFilter(self, **kwargs): if 'group' in kwargs: self._carouselDP.setActiveGroupIndex(kwargs['group']) if 'historic' in kwargs: self._carouselDP.setHistoricalFilter(kwargs['historic']) if 'inventory' in kwargs: self._carouselDP.setOwnedFilter(kwargs['inventory']) if 'applied' in kwargs: self._carouselDP.setAppliedFilter(kwargs['applied']) self.refreshCarousel(rebuild=True) self.refreshHotFilters() def __onOutfitChanged(self): self.refreshOutfit() self.__setBuyingPanelData() def __onCacheResync(self, *_): if not g_currentVehicle.isPresent(): self.__onConfirmCloseWindow(proceed=True) return self.__preserveState() self.__carveUpOutfits() self.__restoreState() self.__setHeaderInitData() self.__setBuyingPanelData() if self._mode == C11nMode.CUSTOM: self.as_hideAnchorPropertySheetS() else: self.as_refreshAnchorPropertySheetS() self.refreshCarousel(rebuild=self._needFullRebuild) self.refreshOutfit() self._needFullRebuild = False def __preserveState(self): self._state.update(modifiedStyle=self._modifiedStyle, modifiedOutfits={season:outfit.copy() for season, outfit in self._modifiedOutfits.iteritems()}) def __restoreState(self): self._modifiedStyle = self._state.get('modifiedStyle') self._modifiedOutfits = self._state.get('modifiedOutfits') if self._modifiedStyle: self._modifiedStyle = self.itemsCache.items.getItemByCD(self._modifiedStyle.intCD) self._state.clear() def __onServerSettingChanged(self, diff): if 'isCustomizationEnabled' in diff and not diff.get('isCustomizationEnabled', True): SystemMessages.pushI18nMessage(SYSTEM_MESSAGES.CUSTOMIZATION_UNAVAILABLE, type=SystemMessages.SM_TYPE.Warning) self.__onConfirmCloseWindow(proceed=True) def __setBuyingPanelData(self, *_): purchaseItems = self.getPurchaseItems() cartInfo = getTotalPurchaseInfo(purchaseItems) totalPriceVO = getItemPricesVO(cartInfo.totalPrice) accountMoney = self.itemsCache.items.stats.money if cartInfo.totalPrice != ITEM_PRICE_EMPTY: label = _ms(VEHICLE_CUSTOMIZATION.COMMIT_BUY) self.as_showBuyingPanelS() else: label = _ms(VEHICLE_CUSTOMIZATION.COMMIT_APPLY) self.as_hideBuyingPanelS() isAtLeastOneOufitNotEmpty = False for season in SeasonType.COMMON_SEASONS: if not self._modifiedOutfits[season].isEmpty(): isAtLeastOneOufitNotEmpty = True break isApplyEnabled = cartInfo.minPriceItem.isDefined() and cartInfo.minPriceItem <= accountMoney or cartInfo.isAtLeastOneItemFromInventory or cartInfo.isAtLeastOneItemDismantled or self._mode == C11nMode.CUSTOM and not self._originalOutfits[self._currentSeason].isInstalled() and isAtLeastOneOufitNotEmpty shortage = self.itemsCache.items.stats.money.getShortage(cartInfo.totalPrice.price) self.as_setBottomPanelHeaderS({'buyBtnEnabled': isApplyEnabled, 'buyBtnLabel': label, 'enoughMoney': getItemPricesVO(ItemPrice(shortage, shortage))[0], 'pricePanel': totalPriceVO[0]}) def __setSeasonData(self): seasonRenderersList = [] for season in SEASONS_ORDER: seasonName = SEASON_TYPE_TO_NAME.get(season) seasonRenderersList.append({'seasonName': VEHICLE_CUSTOMIZATION.getSeasonName(seasonName), 'seasonIconSmall': RES_ICONS.getSeasonIcon(seasonName)}) self.as_setSeasonPanelDataS({'seasonRenderersList': seasonRenderersList}) def __setAnchorsInitData(self, tabIndex, doRegions, update=False): def customizationSlotIdToUid(customizationSlotIdVO): s = struct.pack('bbh', customizationSlotIdVO.areaId, customizationSlotIdVO.slotId, customizationSlotIdVO.regionId) return struct.unpack('I', s)[0] anchorVOs = [] cType = TABS_ITEM_MAPPING[tabIndex] if tabIndex == C11nTabs.STYLE: slotId = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0) uid = customizationSlotIdToUid(slotId) popoverAlias = CUSTOMIZATION_POPOVER_ALIASES[GUI_ITEM_TYPE.STYLE] anchorVOs.append(CustomizationSlotUpdateVO(slotId._asdict(), popoverAlias, -1, uid)._asdict()) else: for container in self._currentOutfit.containers(): for slot in (x for x in container.slots() if x.getType() == cType): for regionId, region in enumerate(slot.getRegions()): slotId = CustomizationSlotIdVO(container.getAreaID(), slot.getType(), regionId) popoverAlias = CUSTOMIZATION_POPOVER_ALIASES[slot.getType()] item = slot.getItem(regionId) itemIntCD = item.intCD if item is not None else 0 uid = customizationSlotIdToUid(slotId) if self.__getAnchorPositionData(slotId, region) is not None: anchorVOs.append(CustomizationSlotUpdateVO(slotId._asdict(), popoverAlias, itemIntCD, uid)._asdict()) if update: self.as_updateAnchorDataS(CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) else: self.as_setAnchorInitS(CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) return def __setHeaderInitData(self): vehicle = g_currentVehicle.item self.as_setHeaderDataS({'tankTier': str(int2roman(vehicle.level)), 'tankName': vehicle.shortUserName, 'tankType': '{}_elite'.format(vehicle.type) if vehicle.isElite else vehicle.type, 'isElite': vehicle.isElite, 'closeBtnTooltip': VEHICLE_CUSTOMIZATION.CUSTOMIZATION_HEADERCLOSEBTN, 'historicVO': self.__getHistoricIndicatorData()}) def __setFooterInitData(self): tabsData = self.__getItemTabsData() self._tabIndex = first(tabsData, {}).get('id') self.as_setBottomPanelInitDataS({'tabData': {'tabData': tabsData, 'selectedTab': self._tabIndex}, 'tabsAvailableRegions': C11nTabs.AVAILABLE_REGIONS, 'defaultStyleLabel': VEHICLE_CUSTOMIZATION.DEFAULTSTYLE_LABEL, 'carouselInitData': self.__getCarouselInitData(), 'switcherInitData': self.__getSwitcherInitData()}) self.as_setCarouselFiltersInitDataS({'popoverAlias': VIEW_ALIAS.CUSTOMIZATION_FILTER_POPOVER, 'mainBtn': {'value': RES_ICONS.MAPS_ICONS_BUTTONS_FILTER, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_MAINBTN}, 'hotFilters': [{'value': RES_ICONS.MAPS_ICONS_CUSTOMIZATION_STORAGE_ICON, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_STORAGEBTN, 'selected': self._carouselDP.getOwnedFilter()}, {'value': RES_ICONS.MAPS_ICONS_BUTTONS_EQUIPPED_ICON, 'tooltip': VEHICLE_CUSTOMIZATION.CAROUSEL_FILTER_EQUIPPEDBTN, 'selected': self._carouselDP.getAppliedFilter()}]}) def onSelectHotFilter(self, index, value): (self._carouselDP.setOwnedFilter, self._carouselDP.setAppliedFilter)[index](value) self.refreshCarousel(rebuild=True) def __getSwitcherInitData(self): return {'leftLabel': VEHICLE_CUSTOMIZATION.SWITCHER_NAME_CUSTSOMSTYLE, 'rightLabel': VEHICLE_CUSTOMIZATION.SWITCHER_NAME_DEFAULTSTYLE, 'leftEvent': 'installStyle', 'rightEvent': 'installStyles', 'isLeft': self._mode == C11nMode.CUSTOM} def __getHistoricIndicatorData(self): isDefault = all((outfit.isEmpty() for outfit in self._modifiedOutfits.itervalues())) if self._mode == C11nMode.STYLE: if self._modifiedStyle: isHistorical = self._modifiedStyle.isHistorical() name = self._modifiedStyle.userName else: isHistorical = True name = '' else: isHistorical = all((outfit.isHistorical() for outfit in self._modifiedOutfits.itervalues())) name = _ms(VEHICLE_CUSTOMIZATION.HISTORICINDICATOR_STYLENAME_CUSTSOMSTYLE) if not isDefault else '' txtStyle = text_styles.stats if isHistorical else text_styles.tutorial return {'historicText': txtStyle(toUpper(name)), 'isDefaultAppearance': isDefault, 'isHistoric': isHistorical, 'tooltip': TOOLTIPS.CUSTOMIZATION_NONHISTORICINDICATOR if not isHistorical else ''} @staticmethod def __getCarouselInitData(): return {'message': '{}{}\n{}'.format(icons.makeImageTag(RES_ICONS.MAPS_ICONS_LIBRARY_ATTENTIONICONFILLED, vSpace=-3), text_styles.neutral(VEHICLE_CUSTOMIZATION.CAROUSEL_MESSAGE_HEADER), text_styles.main(VEHICLE_CUSTOMIZATION.CAROUSEL_MESSAGE_DESCRIPTION))} def __getAnchorPositionData(self, slotId, region): if self._tabIndex in C11nTabs.REGIONS: anchorPos = self.service.getPointForRegionLeaderLine(region) anchorNorm = anchorPos else: anchorPos = self.service.getPointForAnchorLeaderLine(slotId.areaId, slotId.slotId, slotId.regionId) anchorNorm = self.service.getNormalForAnchorLeaderLine(slotId.areaId, slotId.slotId, slotId.regionId) return None if anchorPos is None or anchorNorm is None else AnchorPositionData(cameras.get2DAngleFromCamera(anchorNorm), cameras.projectPoint(anchorPos), slotId) def __getItemTabsData(self): data = [] for tabIdx in self.__getVisibleTabs(): itemTypeID = TABS_ITEM_MAPPING[tabIdx] typeName = GUI_ITEM_TYPE_NAMES[itemTypeID] data.append({'label': _ms(ITEM_TYPES.customizationPlural(typeName)), 'tooltip': makeTooltip(ITEM_TYPES.customizationPlural(typeName), TOOLTIPS.customizationItemTab(typeName)), 'id': tabIdx}) return data def __getVisibleTabs(self): visibleTabs = [] anchorsData = g_currentVehicle.hangarSpace.getSlotPositions() for tabIdx in C11nTabs.VISIBLE: if tabIdx == C11nTabs.CAMOUFLAGE and g_currentVehicle.item.descriptor.type.hasCustomDefaultCamouflage: continue itemTypeID = TABS_ITEM_MAPPING[tabIdx] data = self._carouselDP.getSeasonAndTabData(tabIdx, self._currentSeason) if not data.itemCount: continue if itemTypeID in (GUI_ITEM_TYPE.INSCRIPTION, GUI_ITEM_TYPE.EMBLEM): for areaData in anchorsData.itervalues(): if areaData.get(itemTypeID): hasSlots = True break else: hasSlots = False if not hasSlots: continue visibleTabs.append(tabIdx) return visibleTabs def __onNotifyHangarCameraIdleStateChanged(self, event): isIdle = event.ctx.get('started', False) self.as_cameraAutoRotateChangedS(isIdle) @async @adisp_process def __confirmHeaderNavigation(self, callback): purchaseItems = self.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.numTotal: result = yield DialogsInterface.showI18nConfirmDialog('customization/close') else: result = True callback(result) def __releaseItemSound(self): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.RELEASE) self.itemIsPicked = False def __onSettingsChanged(self, diff): if GAME.HANGAR_CAM_PARALLAX_ENABLED in diff: self.__updateCameraParalaxFlag() def __updateCameraParalaxFlag(self): paralaxEnabled = bool(self.settingsCore.getSetting(GAME.HANGAR_CAM_PARALLAX_ENABLED)) self.as_setParallaxFlagS(paralaxEnabled) def __onInterfaceScaleChanged(self, scale): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setInterfaceScale(scale) return
class MainView(CustomizationMainViewMeta): _COMMON_SOUND_SPACE = C11N_SOUND_SPACE _ZOOM_ON_EMBLEM = 0.6 _ZOOM_ON_INSCRIPTION = 0.1 lobbyContext = dependency.descriptor(ILobbyContext) itemsCache = dependency.descriptor(IItemsCache) service = dependency.descriptor(ICustomizationService) settingsCore = dependency.descriptor(ISettingsCore) hangarSpace = dependency.descriptor(IHangarSpace) def __init__(self, _=None): super(MainView, self).__init__() self.__viewLifecycleWatcher = ViewLifecycleWatcher() self.fadeAnchorsOut = False self.__locatedOnEmbelem = False self.itemIsPicked = False self.__propertiesSheet = None self._seasonSoundAnimantion = None self._vehicleCustomizationAnchorsUpdater = None self._isPropertySheetShown = False self.__ctx = None self.__renderEnv = None return def showBuyWindow(self): self.changeVisible(False) self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.SELECT) purchaseItems = self.__ctx.getPurchaseItems() cart = getTotalPurchaseInfo(purchaseItems) if cart.totalPrice == ITEM_PRICE_EMPTY: self.__ctx.applyItems(purchaseItems) else: self.fireEvent( events.LoadViewEvent(VIEW_ALIAS.CUSTOMIZATION_PURCHASE_WINDOW), EVENT_BUS_SCOPE.LOBBY) def onPressClearBtn(self): self.__ctx.cancelChanges() def onPressEscBtn(self): if self._isPropertySheetShown: self.__clearItem() else: self.onCloseWindow() def changeVisible(self, value): slotType, _, _ = self.__ctx.selectedRegion self.__ctx.regionSelected(slotType, -1, -1) self.as_hideS(value) def onReleaseItem(self): self.__ctx.caruselItemUnselected() self.__releaseItemSound() def _onRegisterFlashComponent(self, viewPy, alias): if alias == VIEW_ALIAS.CUSTOMIZATION_PROPERTIES_SHEET: self.__propertiesSheet = viewPy def changeSeason(self, seasonIdx): self.__ctx.changeSeason(seasonIdx) def __onSeasonChanged(self, seasonIdx): seasonName = SEASON_TYPE_TO_NAME.get(self.__ctx.currentSeason) self.soundManager.playInstantSound( SOUNDS.SEASON_SELECT.format(seasonName)) self.__setAnchorsInitData(True) def __onTabChanged(self, tabIndex): self.soundManager.playInstantSound(SOUNDS.TAB_SWITCH) self.service.stopHighlighter() if tabIndex in C11nTabs.REGIONS: itemTypeID = TABS_ITEM_MAPPING[tabIndex] self.service.startHighlighter( chooseMode(itemTypeID, g_currentVehicle.item)) self.__setAnchorsInitData() if self.__locatedOnEmbelem and self.hangarSpace.spaceInited: space = self.hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToCustomizationPreview() self.__updateAnchorPositions() if tabIndex == C11nTabs.STYLE: slotIdVO = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0)._asdict() elif tabIndex == C11nTabs.EFFECT: slotIdVO = CustomizationSlotIdVO(Area.MISC, GUI_ITEM_TYPE.MODIFICATION, 0)._asdict() else: slotIdVO = None self.as_updateSelectedRegionsS(slotIdVO) self.as_enableDNDS(tabIndex not in DRAG_AND_DROP_INACTIVE_TABS) self.__hidePropertiesSheet() return def __onItemsInstalled(self): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.APPLY) self.__setHeaderInitData() self.__setSeasonData() slotType, areaId, regionIdx = self.__ctx.selectedRegion self.__showPropertiesSheet(areaId, slotType, regionIdx) self.__setAnchorsInitData(True) def __onItemsRemoved(self): self.soundManager.playInstantSound(SOUNDS.REMOVE) self.__setHeaderInitData() self.__setSeasonData() self.__setAnchorsInitData(True) def __onModeChanged(self, mode): self.__setHeaderInitData() self.__setSeasonData(True) def fadeOutAnchors(self, isFadeOut): self.fadeAnchorsOut = isFadeOut def onCloseWindow(self): if self.__ctx.isOutfitsModified(): DialogsInterface.showDialog( I18nConfirmDialogMeta('customization/close'), self.__onCloseWindow) else: self.__onCloseWindow(proceed=True) def itemContextMenuDisplayed(self): cmHandler = self.app.contextMenuManager.getCurrentHandler() if isinstance(cmHandler, CustomizationItemCMHandler): cmHandler.onSelected += self._itemCtxMenuSelected def onLobbyClick(self): if self.__ctx.currentTab in (C11nTabs.EMBLEM, C11nTabs.INSCRIPTION): self.__clearItem() def onChangeSize(self): self.__updateAnchorPositions() def onSelectAnchor(self, areaId, slotType, regionIdx): if slotType not in (GUI_ITEM_TYPE.EMBLEM, GUI_ITEM_TYPE.INSCRIPTION): return if self.hangarSpace.spaceInited: self.soundManager.playInstantSound(SOUNDS.CHOOSE) if slotType == GUI_ITEM_TYPE.EMBLEM: emblemType = 'player' zoom = MainView._ZOOM_ON_EMBLEM else: emblemType = 'inscription' zoom = MainView._ZOOM_ON_INSCRIPTION self.__updateAnchorPositions() self.__locatedOnEmbelem = self.hangarSpace.space.locateCameraOnEmblem( areaId == Area.HULL, emblemType, regionIdx, zoom) self.as_cameraAutoRotateChangedS(True) BigWorld.callback(5, self.__cameraRotationFinished) self.__ctx.regionSelected(slotType, areaId, regionIdx) self.__showPropertiesSheet(areaId, slotType, regionIdx) def __cameraRotationFinished(self): self.as_cameraAutoRotateChangedS(False) def __onItemsBought(self, purchaseItems, results): errorCount = 0 for result in results: if not result.success: errorCount += 1 if result.userMsg: SystemMessages.pushI18nMessage(result.userMsg, type=result.sysMsgType) if not errorCount: cart = getTotalPurchaseInfo(purchaseItems) if cart.totalPrice != ITEM_PRICE_EMPTY: msgCtx = { 'money': formatPrice(cart.totalPrice.price), 'count': cart.numSelected } SystemMessages.pushI18nMessage( MESSENGER. SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONSBUY, type=CURRENCY_TO_SM_TYPE.get( cart.totalPrice.getCurrency(byWeight=True), SM_TYPE.PurchaseForGold), **msgCtx) else: SystemMessages.pushI18nMessage( MESSENGER. SERVICECHANNELMESSAGES_SYSMSG_CONVERTER_CUSTOMIZATIONS, type=SM_TYPE.Information) self.__onCloseWindow(proceed=True) def onAnchorsShown(self, anchors): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setAnchors( anchors, self.__ctx.currentTab in C11nTabs.REGIONS) return def _populate(self): super(MainView, self)._populate() self.__ctx = self.service.getCtx() self.__ctx.onCustomizationSeasonChanged += self.__onSeasonChanged self.__ctx.onCustomizationModeChanged += self.__onModeChanged self.__ctx.onCustomizationTabChanged += self.__onTabChanged self.__ctx.onCustomizationItemInstalled += self.__onItemsInstalled self.__ctx.onCustomizationItemsRemoved += self.__onItemsRemoved self.__ctx.onCustomizationItemsBought += self.__onItemsBought self.__ctx.onCacheResync += self.__onCacheResync self.__ctx.onChangesCanceled += self.__onChangesCanceled self.__ctx.onCaruselItemSelected += self.__onCaruselItemSelected self.__ctx.onPropertySheetHidden += self.__onPropertySheetHidden self.__ctx.onPropertySheetShown += self.__onPropertySheetShown self.soundManager.playInstantSound(SOUNDS.ENTER) self.__viewLifecycleWatcher.start(self.app.containerManager, [ _ModalWindowsPopupHandler(), _C11ViewsPopupHandler(self.__hidePropertiesSheet) ]) self.lobbyContext.addHeaderNavigationConfirmator( self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings( ).onServerSettingsChange += self.__onServerSettingChanged g_eventBus.addListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) self.hangarSpace.onSpaceCreate += self.__onSpaceCreateHandler self.hangarSpace.onSpaceDestroy += self.__onSpaceDestroyHandler self.hangarSpace.onSpaceRefresh += self.__onSpaceRefreshHandler self.service.onRegionHighlighted += self.__onRegionHighlighted self._seasonSoundAnimantion = _SeasonSoundAnimantion( len(SeasonType.COMMON_SEASONS), self.soundManager) self.__setHeaderInitData() self.__setSeasonData() self._vehicleCustomizationAnchorsUpdater = _VehicleCustomizationAnchorsUpdater( self.service) self._vehicleCustomizationAnchorsUpdater.startUpdater( self.settingsCore.interfaceScale.get()) self.__ctx.refreshOutfit() self.settingsCore.interfaceScale.onScaleExactlyChanged += self.__onInterfaceScaleChanged self.fireEvent( CameraRelatedEvents( CameraRelatedEvents.FORCE_DISABLE_IDLE_PARALAX_MOVEMENT, ctx={'isDisable': True}), EVENT_BUS_SCOPE.LOBBY) if self.hangarSpace.spaceInited: self.hangarSpace.space.locateCameraToCustomizationPreview() self.__renderEnv = BigWorld.CustomizationEnvironment() self.__renderEnv.enable(True) self._isPropertySheetShown = False def _dispose(self): self.fireEvent(events.HangarCustomizationEvent( events.HangarCustomizationEvent.RESET_VEHICLE_MODEL_TRANSFORM), scope=EVENT_BUS_SCOPE.LOBBY) self.fireEvent( CameraRelatedEvents( CameraRelatedEvents.FORCE_DISABLE_IDLE_PARALAX_MOVEMENT, ctx={'isDisable': False}), EVENT_BUS_SCOPE.LOBBY) if g_appLoader.getSpaceID() != _SPACE_ID.LOGIN: self.__releaseItemSound() self.soundManager.playInstantSound(SOUNDS.EXIT) self.settingsCore.interfaceScale.onScaleExactlyChanged -= self.__onInterfaceScaleChanged self._vehicleCustomizationAnchorsUpdater.stopUpdater() self._vehicleCustomizationAnchorsUpdater = None if self.hangarSpace.spaceInited: space = self.hangarSpace.space if self.__locatedOnEmbelem: space.clearSelectedEmblemInfo() space.locateCameraToStartState() self._seasonSoundAnimantion = None self.__renderEnv.enable(False) self.__renderEnv = None self.__viewLifecycleWatcher.stop() self.service.stopHighlighter() self.lobbyContext.deleteHeaderNavigationConfirmator( self.__confirmHeaderNavigation) self.lobbyContext.getServerSettings( ).onServerSettingsChange -= self.__onServerSettingChanged g_eventBus.removeListener(CameraRelatedEvents.IDLE_CAMERA, self.__onNotifyHangarCameraIdleStateChanged) self.hangarSpace.onSpaceCreate -= self.__onSpaceCreateHandler self.hangarSpace.onSpaceDestroy -= self.__onSpaceDestroyHandler self.hangarSpace.onSpaceRefresh -= self.__onSpaceRefreshHandler self.service.onRegionHighlighted -= self.__onRegionHighlighted if g_currentVehicle.item: g_tankActiveCamouflage[ g_currentVehicle.item.intCD] = self.__ctx.currentSeason g_currentVehicle.refreshModel() self.__hidePropertiesSheet() self.__propertiesSheet = None self.__ctx.onPropertySheetShown -= self.__onPropertySheetShown self.__ctx.onPropertySheetHidden -= self.__onPropertySheetHidden self.__ctx.onCaruselItemSelected -= self.__onCaruselItemSelected self.__ctx.onChangesCanceled -= self.__onChangesCanceled self.__ctx.onCacheResync -= self.__onCacheResync self.__ctx.onCustomizationItemsBought -= self.__onItemsBought self.__ctx.onCustomizationItemsRemoved -= self.__onItemsRemoved self.__ctx.onCustomizationItemInstalled -= self.__onItemsInstalled self.__ctx.onCustomizationTabChanged -= self.__onTabChanged self.__ctx.onCustomizationModeChanged -= self.__onModeChanged self.__ctx.onCustomizationSeasonChanged -= self.__onSeasonChanged self.__ctx = None self.service.destroyCtx() super(MainView, self)._dispose() return @adisp_process def _itemCtxMenuSelected(self, ctxMenuID, itemIntCD): item = self.itemsCache.items.getItemByCD(itemIntCD) if ctxMenuID == CustomizationOptions.BUY: yield DialogsInterface.showDialog(ConfirmC11nBuyMeta(itemIntCD)) elif ctxMenuID == CustomizationOptions.SELL: inventoryCount = self.__ctx.getItemInventoryCount(item) yield DialogsInterface.showDialog( ConfirmC11nSellMeta(itemIntCD, inventoryCount, self.__ctx.sellItem)) elif ctxMenuID == CustomizationOptions.REMOVE_FROM_TANK: if self.__ctx.mode == C11nMode.CUSTOM: self.__ctx.removeItems(False, itemIntCD) else: self.__ctx.removeStyle(itemIntCD) def _getUpdatedAnchorsData(self): tabIndex = self.__ctx.currentTab cType = TABS_ITEM_MAPPING[tabIndex] slotIds = [] if tabIndex == C11nTabs.STYLE: slotId = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0) slotIds.append(slotId) else: for areaId in Area.ALL: regionsIndexes = getAppliedRegionsForCurrentHangarVehicle( areaId, cType) for regionsIndex in regionsIndexes: slotId = CustomizationSlotIdVO(areaId, cType, regionsIndex) slotIds.append(slotId) anchorVOs = [] for zIdx, slotId in enumerate(slotIds): anchorVOs.append( CustomizationAnchorPositionVO(zIdx, slotId._asdict())._asdict()) return CustomizationAnchorsSetVO(anchorVOs)._asdict() def __updateAnchorPositions(self, _=None): self.as_setAnchorsDataS(self._getUpdatedAnchorsData()) def __onRegionHighlighted(self, slotType, areaId, regionIdx, selected, hovered): region = None if hovered: self.soundManager.playInstantSound(SOUNDS.HOVER) return else: if self.__ctx.currentTab == C11nTabs.EFFECT: areaId = Area.MISC slotType = GUI_ITEM_TYPE.MODIFICATION if areaId != -1 and regionIdx != -1: region = CustomizationSlotIdVO(areaId, slotType, regionIdx)._asdict() if selected: self.soundManager.playInstantSound(SOUNDS.CHOOSE) else: self.__hidePropertiesSheet() self.__ctx.regionSelected(slotType, areaId, regionIdx) if self.__ctx.isRegionSelected(): self.as_onRegionHighlightedS(region) self.__showPropertiesSheet(areaId, slotType, regionIdx) else: self.__clearItem() return def __onSpaceCreateHandler(self): Waiting.hide(_WAITING_MESSAGE) self.__ctx.refreshOutfit() self.__updateAnchorPositions() def __onSpaceDestroyHandler(self, _): Waiting.hide(_WAITING_MESSAGE) self.__onCloseWindow(proceed=True) def __onSpaceRefreshHandler(self): Waiting.show(_WAITING_MESSAGE) def __onCloseWindow(self, proceed): if proceed: if self._isPropertySheetShown: self.__clearItem() self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY) def __onCacheResync(self, *_): if not g_currentVehicle.isPresent(): self.__onCloseWindow(proceed=True) return self.__setHeaderInitData() self.__setSeasonData() def __onChangesCanceled(self): self.__hidePropertiesSheet() def __onCaruselItemSelected(self, index, intCD): tabIndex = self.__ctx.currentTab if tabIndex == C11nTabs.STYLE or tabIndex == C11nTabs.EFFECT: slotType, areaId, regionIdx = self.__ctx.selectedRegion self.__onRegionHighlighted(slotType, areaId, regionIdx, True, False) if not self.__propertiesSheet.isVisible and not self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.PICK) self.itemIsPicked = True def __onServerSettingChanged(self, diff): if 'isCustomizationEnabled' in diff and not diff.get( 'isCustomizationEnabled', True): SystemMessages.pushI18nMessage( SYSTEM_MESSAGES.CUSTOMIZATION_UNAVAILABLE, type=SystemMessages.SM_TYPE.Warning) self.__onCloseWindow(proceed=True) def __onPropertySheetShown(self): self._isPropertySheetShown = True def __onPropertySheetHidden(self): self.service.resetHighlighting() self.__clearItem() self._isPropertySheetShown = False def __setSeasonData(self, forceAnim=False): seasonRenderersList = [] filledSeasonSlots = 0 for season in SEASONS_ORDER: seasonName = SEASON_TYPE_TO_NAME.get(season) if self.__ctx.mode == C11nMode.CUSTOM: isFilled = self.__ctx.checkSlotsFillingForSeason(season) else: isFilled = self.__ctx.modifiedStyle is not None filledSeasonSlots += int(isFilled) seasonRenderersList.append({ 'nameText': VEHICLE_CUSTOMIZATION.getSeasonName(seasonName), 'nameSelectedText': VEHICLE_CUSTOMIZATION.getSeasonSelectedName(seasonName), 'seasonImageSrc': RES_ICONS.getSeasonImage(seasonName), 'seasonBGImageSrc': RES_ICONS.getSeasonBGImage(seasonName), 'isFilled': isFilled, 'forceAnim': forceAnim }) self.as_setSeasonsBarDataS(seasonRenderersList) self._seasonSoundAnimantion.setFilledSeasonSlots( filledSeasonSlots, forceAnim) return def __setAnchorsInitData(self, update=False): def customizationSlotIdToUid(customizationSlotIdVO): s = struct.pack('bbh', customizationSlotIdVO.areaId, customizationSlotIdVO.slotId, customizationSlotIdVO.regionId) return struct.unpack('I', s)[0] tabIndex = self.__ctx.currentTab anchorVOs = [] cType = TABS_ITEM_MAPPING[tabIndex] if tabIndex == C11nTabs.STYLE: slotId = CustomizationSlotIdVO(0, GUI_ITEM_TYPE.STYLE, 0) uid = customizationSlotIdToUid(slotId) anchorVOs.append( CustomizationSlotUpdateVO(slotId._asdict(), -1, uid)._asdict()) else: for areaId in Area.ALL: regionsIndexes = getAppliedRegionsForCurrentHangarVehicle( areaId, cType) slot = self.__ctx.currentOutfit.getContainer(areaId).slotFor( cType) for regionsIndex in regionsIndexes: slotId = CustomizationSlotIdVO(areaId, cType, regionsIndex) item = slot.getItem(regionsIndex) itemIntCD = item.intCD if item is not None else 0 uid = customizationSlotIdToUid(slotId) anchorVOs.append( CustomizationSlotUpdateVO(slotId._asdict(), itemIntCD, uid)._asdict()) doRegions = tabIndex in C11nTabs.REGIONS if update: self.as_updateAnchorDataS( CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) else: self.as_setAnchorInitS( CustomizationAnchorInitVO(anchorVOs, doRegions)._asdict()) return def __setHeaderInitData(self): vehicle = g_currentVehicle.item self.as_setHeaderDataS({ 'tankTier': str(int2roman(vehicle.level)), 'tankName': vehicle.shortUserName, 'tankType': '{}_elite'.format(vehicle.type) if vehicle.isElite else vehicle.type, 'isElite': vehicle.isElite, 'closeBtnTooltip': VEHICLE_CUSTOMIZATION.CUSTOMIZATION_HEADERCLOSEBTN }) def __showPropertiesSheet(self, areaId, slotId, regionId): if self.__propertiesSheet: self.__propertiesSheet.show(areaId, slotId, regionId) def __hidePropertiesSheet(self): if self.__propertiesSheet: self.__propertiesSheet.hide() def getItemTabsData(self): data = [] pluses = [] for tabIdx in self.__ctx.visibleTabs: itemTypeID = TABS_ITEM_MAPPING[tabIdx] typeName = GUI_ITEM_TYPE_NAMES[itemTypeID] showPlus = not self.__checkSlotsFilling(itemTypeID, self._currentSeason) data.append({ 'label': _ms(ITEM_TYPES.customizationPlural(typeName)), 'tooltip': makeTooltip(ITEM_TYPES.customizationPlural(typeName), TOOLTIPS.customizationItemTab(typeName)), 'id': tabIdx }) pluses.append(showPlus) return (data, pluses) def __onNotifyHangarCameraIdleStateChanged(self, event): isIdle = event.ctx.get('started', False) self.as_cameraAutoRotateChangedS(isIdle) @async @adisp_process def __confirmHeaderNavigation(self, callback): if self.__ctx.isOutfitsModified(): result = yield DialogsInterface.showI18nConfirmDialog( 'customization/close') else: result = True if result: self.__onCloseWindow(proceed=True) callback(result) def __releaseItemSound(self): if self.itemIsPicked: self.soundManager.playInstantSound(SOUNDS.RELEASE) self.itemIsPicked = False def __onInterfaceScaleChanged(self, scale): if self._vehicleCustomizationAnchorsUpdater is not None: self._vehicleCustomizationAnchorsUpdater.setInterfaceScale(scale) return def __resetCameraFocus(self): if self.__locatedOnEmbelem and self.hangarSpace.spaceInited: space = self.hangarSpace.space space.clearSelectedEmblemInfo() space.locateCameraToCustomizationPreview() self.__updateAnchorPositions() self.__locatedOnEmbelem = False def __resetUIFocus(self): self.as_onRegionHighlightedS(-1) def __clearItem(self): self.__hidePropertiesSheet() if self.__ctx.currentTab in (C11nTabs.EMBLEM, C11nTabs.INSCRIPTION): self.__resetCameraFocus() slotType, _, _ = self.__ctx.selectedRegion self.__ctx.regionSelected(slotType, -1, -1) self.__resetUIFocus()
class ChallengeRewardView(ViewImpl): __eventsCache = dependency.descriptor(IEventsCache) __nyController = dependency.descriptor(INewYearController) def __init__(self, layoutID, questID): settings = ViewSettings(layoutID) settings.model = ChallengeRewardViewModel() self.__questID = questID self.__viewLifecycleWatcher = ViewLifecycleWatcher() self._tooltips = {} super(ChallengeRewardView, self).__init__(settings) @property def viewModel(self): return super(ChallengeRewardView, self).getViewModel() def createPopOverContent(self, event): if event.contentID == R.views.common.pop_over_window.backport_pop_over.BackportPopOverContent( ): if event.getArgument( 'popoverId' ) == Discount.NEW_YEAR_DISCOUNT_APPLY_POPOVER_ID: alias = VIEW_ALIAS.NY_SELECT_VEHICLE_FOR_DISCOUNT_POPOVER variadicID = event.getArgument('variadicID') data = createPopOverData(alias, {'variadicID': variadicID}) return BackportPopOverContent(popOverData=data) return super(ChallengeRewardView, self).createPopOverContent(event) @nyCreateToolTipContentDecorator def createToolTipContent(self, event, contentID): if contentID == R.views.lobby.new_year.tooltips.NyVehicleSlotTooltip(): tooltipData = self._tooltips.get(event.getArgument('tooltipId')) if tooltipData is None: return return NyVehicleSlotTooltip(*tooltipData.specialArgs) else: return super(ChallengeRewardView, self).createToolTipContent(event, contentID) @backportTooltipDecorator() def createToolTip(self, event): return super(ChallengeRewardView, self).createToolTip(event) def _onLoaded(self, *args, **kwargs): setOverlayHangarGeneral(onState=True) NewYearSoundsManager.playEvent( NewYearSoundEvents.CELEBRITY_SCREEN_REWARD) super(ChallengeRewardView, self)._onLoaded(*args, **kwargs) def _onLoading(self, *args, **kwargs): quest = self.__eventsCache.getQuestByID(self.__questID) with self.viewModel.transaction() as model: model.setRecommendedGraphicsPreset( BigWorld.detectGraphicsPresetFromSystemSettings()) packBonusModelAndTooltipData(quest.getBonuses(), model.getRewards(), getNewYearBonusPacker(), self._tooltips) tokenCount = marathonTokenCountExtractor(quest) self.viewModel.setCompletedQuests(tokenCount) finalQuest = getFinalCelebrityMarathonQuest() self.viewModel.setIsFinal(finalQuest.getID() == quest.getID()) def _initialize(self, *args, **kwargs): super(ChallengeRewardView, self)._initialize() self.__addListeners() def _finalize(self): self.__removeListeners() setOverlayHangarGeneral(onState=False) def __updateVariadicRewards(self): with self.viewModel.transaction() as model: for reward in model.getRewards(): if reward.getName() == VARIADIC_DISCOUNT_NAME: updateSelectedVehicleForBonus(reward) model.setSyncInitiator((model.getSyncInitiator() + 1) % 1000) def __addListeners(self): model = self.viewModel model.sendCloseEvent += self.__onClose self.viewModel.goToNyVehicleBranch += self.__onToVehicleBranch self.__nyController.onDataUpdated += self.__onDataUpdated self.__nyController.onStateChanged += self.__onEventStateChanged self.__viewLifecycleWatcher.start( dependency.instance(IAppLoader).getApp().containerManager, [ DiscountPopoverHandler(self.__onDiscountPopoverOpened, self.__onDiscountPopoverClosed) ]) def __removeListeners(self): model = self.viewModel model.sendCloseEvent -= self.__onClose self.viewModel.goToNyVehicleBranch -= self.__onToVehicleBranch self.__nyController.onDataUpdated -= self.__onDataUpdated self.__nyController.onStateChanged -= self.__onEventStateChanged self.__viewLifecycleWatcher.stop() def __onDataUpdated(self, keys): if SyncDataKeys.SELECTED_DISCOUNTS in keys: self.__updateVariadicRewards() def __onToVehicleBranch(self): showNewYearVehiclesView() self.__onClose() def __onClose(self, *_): self.destroyWindow() def __onEventStateChanged(self): if not self.__nyController.isEnabled(): self.destroyWindow() def __onDiscountPopoverOpened(self): self.viewModel.setIsDiscountPopoverOpened(True) def __onDiscountPopoverClosed(self): self.viewModel.setIsDiscountPopoverOpened(False)