class OperationReceiver(OperationReceiverBase): """ Operation receiver """ def __init__(self, sender, loadsTransferType, dumpsTransferType, streamer=None): """ Constructor @param sender: operation sender @type sender: MAILBOX """ OperationReceiverBase.__init__(self, sender, loadsTransferType, dumpsTransferType, streamer) self.onReceiveOperation = Event() def _onReceiveOperation(self, operation): self.onReceiveOperation(operation) def destroy(self): """ Destructor """ OperationReceiverBase.destroy(self) self.onReceiveOperation.clear() self.onReceiveOperation = None return
class DisposableEntity(object): def __init__(self): super(DisposableEntity, self).__init__() self.onModuleDispose = Event() self.__created = False self.__disposed = False def create(self): self.__created = True self.__disposed = False self._populate() def destroy(self): if self.__disposed: return self.onModuleDispose(self) self.onModuleDispose.clear() self._dispose() self.__disposed = True def _populate(self): pass def _dispose(self): pass def _isCreated(self): return self.__created def isDisposed(self): return self.__disposed
class _SettingsCache(object): def __init__(self): self.__intSettings = IntSettingsRequester() self.__waitForSync = False self.onSyncStarted = Event() self.onSyncCompleted = Event() def init(self): g_clientUpdateManager.addCallbacks({"intUserSettings": self._onResync}) def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() g_clientUpdateManager.removeObjectCallbacks(self) @property def waitForSync(self): return self.__waitForSync @property def settings(self): return self.__intSettings def _onResync(self, *args): self.__invalidateData() @async def update(self, callback=None): self.__invalidateData(callback) def getSectionSettings(self, section, defaultValue=0): return self.__intSettings.getSetting(section, defaultValue) def setSectionSettings(self, section, value): self.__intSettings.setSetting(section, value) def setSettings(self, settings): self.__intSettings.setSettings(settings) def getSetting(self, key, defaultValue=0): return self.__intSettings.getSetting(key, defaultValue) def getVersion(self, defaultValue=0): return self.__intSettings.getSetting("VERSION", defaultValue) def setVersion(self, value): self.__intSettings.setSetting("VERSION", value) def __invalidateData(self, callback=lambda *args: None): def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted() callback(*args) self.__waitForSync = True self.onSyncStarted() if BattleReplay.g_replayCtrl.isPlaying: cbWrapper(dict()) return self.__intSettings.request()(cbWrapper)
class _ItemsCache(object): def __init__(self): self.__items = ItemsRequester() self.__waitForSync = False self.onSyncStarted = Event() self.onSyncCompleted = Event() def init(self): g_playerEvents.onInventoryResync += self._onResync g_playerEvents.onDossiersResync += self._onResync g_playerEvents.onStatsResync += self._onResync g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected g_playerEvents.onStatsResync -= self._onResync g_playerEvents.onDossiersResync -= self._onResync g_playerEvents.onInventoryResync -= self._onResync @property def waitForSync(self): return self.__waitForSync @property def items(self): return self.__items @async def update(self, diff = None, callback = None): self.__invalidateData(diff, callback) def clear(self): return self.items.clear() def _onResync(self, *args): if not self.__waitForSync: self.__invalidateData() def _onCenterIsLongDisconnected(self, isLongDisconnected): self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected) def __invalidateData(self, diff = None, callback = lambda *args: None): def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted() callback(*args) self.__waitForSync = True self.onSyncStarted() self.__items.invalidateCache(diff) self.__items.request()(cbWrapper) def isSynced(self): return self.items.isSynced()
class SoundEnv(object): """Root sound environment class. Contains of one music event and one ambient event, also has bunch of filters, that can be applied to the sound system at @start method """ def __init__(self, soundsCtrl, envId, music=None, ambient=None, filters=None): self._soundsCtrl = soundsCtrl self._music = music or EmptySound() self._ambient = ambient or EmptySound() self._filters = filters or [] self.__envID = envId self.onChanged = Event() def start(self): self._soundsCtrl.system.onEnvStart(self.__envID) def stop(self): self.onChanged.clear() self._soundsCtrl.system.onEnvStop(self.__envID) self._ambient.clear() self._music.clear() def getMusicEvent(self): """:return: SoundEvent object instance """ return self._music def getAmbientEvent(self): """:return: SoundEvent object instance """ return self._ambient def getFilters(self): """:return: list, filters ids """ return self._filters def _onChanged(self): self.onChanged(self) def _setAmbientParam(self, paramName, value): SOUND_DEBUG('Change ambient parameter', paramName, value) self._ambient.setParam(paramName, value) def _setMusicParam(self, paramName, value): SOUND_DEBUG('Change music parameter', paramName, value) self._music.setParam(paramName, value) def __repr__(self): return '%s(music = %s, ambient = %s, filters = %d)' % ( self.__class__.__name__, self._music, self._ambient, len(self._filters))
class AvatarQuestsInterfaceClient(object): def __init__(self): """ @type self: Avatar.Avatar """ self.eQuestCompleted = Event() def onLeaveWorld(self): self.eQuestCompleted.clear() def onQuestCompleted(self, questID): self.eQuestCompleted(questID)
class SoundEnv(object): """Root sound environment class. Contains of one music event and one ambient event, also has bunch of filters, that can be applied to the sound system at @start method """ def __init__(self, soundsCtrl, envId, music = None, ambient = None, filters = None): self._soundsCtrl = soundsCtrl self._music = music or EmptySound() self._ambient = ambient or EmptySound() self._filters = filters or [] self.__envID = envId self.onChanged = Event() def start(self): self._soundsCtrl.system.onEnvStart(self.__envID) def stop(self): self.onChanged.clear() self._soundsCtrl.system.onEnvStop(self.__envID) def getMusicEvent(self): """:return: SoundEvent object instance """ return self._music def getAmbientEvent(self): """:return: SoundEvent object instance """ return self._ambient def getFilters(self): """:return: list, filters ids """ return self._filters def _onChanged(self): self.onChanged(self) def _setAmbientParam(self, paramName, value): SOUND_DEBUG('Change ambient parameter', paramName, value) self._ambient.setParam(paramName, value) def _setMusicParam(self, paramName, value): SOUND_DEBUG('Change music parameter', paramName, value) self._music.setParam(paramName, value) def __repr__(self): return '%s(music = %s, ambient = %s, filters = %d)' % (self.__class__.__name__, self._music, self._ambient, len(self._filters))
class BCVehicleBuyView(BCVehicleBuyViewMeta): def __init__(self): super(BCVehicleBuyView, self).__init__() self.__academySelected = False self.onAcademyClicked = Event() def onAcademyClick(self): if not self.__academySelected: self.__academySelected = True self.onAcademyClicked() def _dispose(self): self.onAcademyClicked.clear() super(BCVehicleBuyView, self)._dispose()
class SoundEnv(object): def __init__(self, soundsCtrl, envId, music=None, ambient=None, filters=None): self._soundsCtrl = soundsCtrl self._music = music or EmptySound() self._ambient = ambient or EmptySound() self._filters = filters or [] self.__envID = envId self.onChanged = Event() def start(self): self._soundsCtrl.system.onEnvStart(self.__envID) def stop(self): self.onChanged.clear() self._soundsCtrl.system.onEnvStop(self.__envID) self._ambient.clear() self._music.clear() def getMusicEvent(self): return self._music def getAmbientEvent(self): return self._ambient def getFilters(self): return self._filters def _onChanged(self): self.onChanged(self) def _setAmbientParam(self, paramName, value): SOUND_DEBUG('Change ambient parameter', paramName, value) self._ambient.setParam(paramName, value) def _setMusicParam(self, paramName, value): SOUND_DEBUG('Change music parameter', paramName, value) self._music.setParam(paramName, value) def __repr__(self): return '%s(music = %s, ambient = %s, filters = %d)' % ( self.__class__.__name__, self._music, self._ambient, len(self._filters))
class SiegeModeControl(InputHandlerCommand): def __init__(self): self.onSiegeStateChanged = Event() self.onRequestFail = Event() self.__currentState = VEHICLE_SIEGE_STATE.DISABLED def destroy(self): self.onSiegeStateChanged.clear() self.onRequestFail.clear() def handleKeyEvent(self, isDown, key, mods, event=None): cmdMap = CommandMapping.g_instance keyCaptured = cmdMap.isFired( CommandMapping.CMD_CM_VEHICLE_SWITCH_AUTOROTATION, key) and isDown if not keyCaptured: return False else: vehicle = BigWorld.player().getVehicleAttached() if vehicle is not None and vehicle.typeDescriptor.type.isDualgunVehicleType: return False if vehicle is not None and vehicle.isPlayerVehicle and vehicle.isAlive( ): self.__switchSiegeMode() return True def notifySiegeModeChanged(self, vehicle, newState, timeToNextMode): if not vehicle.isPlayerVehicle: return LOG_DEBUG('SiegeMode: new state received: {}'.format( (newState, timeToNextMode))) self.onSiegeStateChanged(newState, timeToNextMode) self.__currentState = newState self.__timeToNextMode = timeToNextMode def __switchSiegeMode(self): if BigWorld.player().deviceStates.get('engine') == 'destroyed': if self.__currentState not in VEHICLE_SIEGE_STATE.SWITCHING: self.onRequestFail() return if self.__currentState in (VEHICLE_SIEGE_STATE.SWITCHING_ON, VEHICLE_SIEGE_STATE.ENABLED): enableSiegeMode = False else: enableSiegeMode = True BigWorld.player().base.vehicle_changeSetting( VEHICLE_SETTING.SIEGE_MODE_ENABLED, enableSiegeMode)
class Command(PyObjectEntity): __slots__ = ('__event',) def __init__(self, name): super(Command, self).__init__(GUI.PyObjectCommand(name)) self.__event = Event() @property def name(self): return self.proxy.name def execute(self, args=None): if args is not None: args = (args,) else: args = () self.proxy.execute(*args) return def _unbind(self): self.__event.clear() super(Command, self)._unbind() def _cNotify(self, args=None): if args is not None: args = (args,) else: args = () self.__event(*args) return def __iadd__(self, delegate): self.__event += delegate return self def __isub__(self, delegate): self.__event -= delegate return self
class AbstractLock(object): def __init__(self): super(AbstractLock, self).__init__() self.onLocked = Event() self.onUnlocked = Event() def dispose(self): self.onLocked.clear() self.onUnlocked.clear() def getID(self): raise NotImplementedError def lock(self): raise NotImplementedError def unlock(self): raise NotImplementedError def isLocked(self): raise NotImplementedError def tryLock(self): raise NotImplementedError
class ServerSettings(object): def __init__(self, serverSettings): self.onServerSettingsChange = Event() self.__serverSettings = serverSettings if serverSettings else {} if 'roaming' in self.__serverSettings: roamingSettings = self.__serverSettings['roaming'] self.__roamingSettings = RoamingSettings(roamingSettings[0], roamingSettings[1], [ _ServerInfo(*s) for s in roamingSettings[2] ]) else: self.__roamingSettings = RoamingSettings.defaults() if 'file_server' in self.__serverSettings: self.__fileServerSettings = _FileServerSettings(self.__serverSettings['file_server']) else: self.__fileServerSettings = _FileServerSettings.defaults() if 'regional_settings' in self.__serverSettings: self.__regionalSettings = makeTupleByDict(_RegionalSettings, self.__serverSettings['regional_settings']) else: self.__regionalSettings = _RegionalSettings.defaults() try: self.__eSportCurrentSeason = makeTupleByDict(_ESportCurrentSeason, self.__serverSettings) except TypeError: self.__eSportCurrentSeason = _ESportCurrentSeason.defaults() self.__updateClanProfile(self.__serverSettings) def update(self, serverSettingsDiff): self.__serverSettings.update(serverSettingsDiff) self.__updateClanProfile(serverSettingsDiff) self.onServerSettingsChange(serverSettingsDiff) def clear(self): self.onServerSettingsChange.clear() def getSettings(self): return self.__serverSettings @property def roaming(self): return self.__roamingSettings @property def fileServer(self): return self.__fileServerSettings @property def regionals(self): return self.__regionalSettings @property def eSportCurrentSeason(self): return self.__eSportCurrentSeason @property def clanProfile(self): return self.__clanProfile def isPotapovQuestEnabled(self): return self.isFalloutQuestEnabled() or self.isRegularQuestEnabled() def isRegularQuestEnabled(self): return self.__getGlobalSetting('isRegularQuestEnabled', True) def isFalloutQuestEnabled(self): return self.__getGlobalSetting('isFalloutQuestEnabled', True) def isBuyPotapovQuestTileEnabled(self): return self.__getGlobalSetting('isBuyPotapovQuestTileEnabled', False) def isBuyPotapovQuestSlotEnabled(self): return self.__getGlobalSetting('isBuyPotapovQuestSlotEnabled', False) def isFortBattlesEnabled(self): return not self.__getGlobalSetting('isFortBattlesDisabled', True) def isClubsEnabled(self): return self.__getGlobalSetting('isClubsEnabled', False) def isGoldFishEnabled(self): return self.__getGlobalSetting('isGoldFishEnabled', False) def isTutorialEnabled(self): return self.__getGlobalSetting('isTutorialEnabled', IS_TUTORIAL_ENABLED) def isSandboxEnabled(self): return self.__getGlobalSetting('isSandboxEnabled', False) def isPromoAutoViewsEnabled(self): return True def getForbiddenFortDefenseHours(self): return self.__getGlobalSetting('forbiddenFortDefenseHours', tuple()) def getForbiddenSortieHours(self): return self.__getGlobalSetting('forbiddenSortieHours', tuple()) def getForbiddenSortiePeripheryIDs(self): return self.__getGlobalSetting('forbiddenSortiePeripheryIDs', tuple()) def getForbiddenRatedBattles(self): return self.__getGlobalSetting('forbiddenRatedBattles', {}) def isPremiumInPostBattleEnabled(self): return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True) def __getGlobalSetting(self, settingsName, default = None): return self.__serverSettings.get(settingsName, default) def __updateClanProfile(self, targetSettings): if 'clanProfile' in targetSettings: cProfile = targetSettings['clanProfile'] self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False), cProfile.get('gateUrl', ''), cProfile.get('type', 'gateway')) else: self.__clanProfile = _ClanProfile.defaults()
class _CurrentVehicle(): def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.onChanged = Event() self.onChangeStarted = Event() self.__crew = {} def init(self): g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate, 'cache.vehsLock': self.onLocksUpdate}) prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) g_hangarSpace.removeVehicle() self.selectNoVehicle() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']: isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() elif 'repair' in vehsDiff: isRepaired = self.__vehInvID in vehsDiff['repair'] if not GUI_ITEM_TYPE.TURRET in invDiff: isComponentsChanged = GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive, vehsDiff.itervalues())) > 0 (isComponentsChanged or isRepaired or isVehicleDescrChanged) and self.refreshModel() (isVehicleChanged or isRepaired) and self.onChanged() if self.isPresent(): self.__updateViewRange() def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: g_hangarSpace.updateVehicle(self.item) else: g_hangarSpace.removeVehicle() @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): if self.isPresent() and self.item.isAutoLoad: for shell in self.item.shells: if shell.count != shell.defaultCount: return False return True def isAutoEquipFull(self): if self.isPresent() and self.item.isAutoEquip: return self.item.eqs == self.item.eqsLayout return True def selectVehicle(self, vehInvID = 0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) return def selectNoVehicle(self): self.__selectVehicle(0) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() return ('#menu:currentVehicleStatus/' + state, stateLvl) return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL) def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show('updateCurrentVehicle', isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) if self.isPresent(): self.__updateViewRange() def __updateViewRange(self): # Set Defaults xvm_conf = {} # Load configuration xvm_configuration_file = os.getcwd() + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc' if not os.path.exists(xvm_configuration_file): LOG_NOTE("Configuration file missing (" + xvm_configuration_file + "). Creating.") else: data = "" blockComment = False f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"') for line in f.read().split('\n'): line = line.strip() if line != "": # Start of block comment comment = line.find("/*") if comment != -1 and comment == 0: blockComment = True continue # End of block comment comment = line.find("*/") if comment != -1: blockComment = False continue # Block Comment if blockComment == True: continue # Start of line comment comment = line.find("//") if comment != -1 and comment == 0: continue # Remove end of line comments position = 0 for i in range(0,line.count("//")): comment = line.find("//", position+2) if comment != -1: colon = line.find(":") startSpeach = line.find("\"", colon+1) if startSpeach > comment: line = line[:comment].strip() endSpeach = line.find("\"", startSpeach+1) if comment > endSpeach: line = line[:comment].strip() position += comment if line != "": data += line + '\n' f.close() xvm_conf = json.loads(data) # add spotting_limit option to old configs (new in 1.6) if not xvm_conf["tankrange"].has_key("spotting_limit"): LOG_NOTE("add missing spotting_limit option") xvm_conf["tankrange"]["spotting_limit"] = True # Get name tank_name = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.name.split(":")[1].lower().replace("-","_") if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Tank Name: ", tank_name) # without a crew calculation Cancel if not self.isCrewFull(): if xvm_conf['tankrange']['logging']: LOG_NOTE('no full crew') return # Remove current circles remaining = [] for tank_data in xvm_conf["circles"]["special"]: if tank_data.keys()[0] != tank_name: remaining.append(tank_data) xvm_conf["circles"]["special"] = remaining # Get type if xvm_conf["tankrange"]["ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags: f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2))) f.close() if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Ignoring " + vehicle_type + " tank.") return # Get view distance view_distance = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.turret["circularVisionRadius"] if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Base View Range: ", view_distance) # Check for Ventilation ventilation = self.__isOptionalEquipped("improvedVentilation") if xvm_conf["tankrange"]["logging"] and ventilation: LOG_NOTE("Ventilation Found") # Check for Consumable consumable = self.__isConsumableEquipped("ration") if xvm_conf["tankrange"]["logging"] and consumable: LOG_NOTE("Premium Consumable Found") # Update crew self.__updateCrew() # Check for Brothers In Arms brothers_in_arms = True if len(self.__crew) == 0: brothers_in_arms = False else: for name, data in self.__crew.iteritems(): if "brotherhood" not in data["skill"]: brothers_in_arms = False if xvm_conf["tankrange"]["logging"] and brothers_in_arms: LOG_NOTE("BIA Found") # Calculate commander bonus commander_skill = 0 if "commander" in self.__crew: commander_skill = self.__crew["commander"]["level"] if brothers_in_arms == True: commander_skill += 5 if ventilation == True: commander_skill += 5 if consumable == True: commander_skill += 10 if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Commander Skill: ", commander_skill) # Calculate other bonuses other_bonus = 1.0 for name, data in self.__crew.iteritems(): # Calculate recon skills if "commander_eagleEye" in data["skill"]: other_bonus *= 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] ) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Recon Bonus: ", 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] )) # Calculate Situational Awareness Skill if "radioman_finder" in data["skill"]: other_bonus *= 1.0 + ( 0.0002 * data["skill"]["radioman_finder"] ) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Situational Awareness Bonus: ", 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] )) # Check for Binoculars binoculars = self.__isOptionalEquipped("stereoscope") if xvm_conf["tankrange"]["logging"] and binoculars: LOG_NOTE("Binoculars Found") # Check for Coated Optics coated_optics = self.__isOptionalEquipped("coatedOptics") if xvm_conf["tankrange"]["logging"] and coated_optics: LOG_NOTE("Coated Optics Found") # Calculate final value view_distance = ((view_distance / 0.875) * (0.00375* commander_skill + 0.5)) * other_bonus if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Other Bonus:", other_bonus) LOG_NOTE("Final View Range: ", view_distance) # Add binocular Circles if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars: binocular_distance = view_distance * 1.25 if xvm_conf["tankrange"]["spotting_limit"]: binocular_distance = min(445, binocular_distance); if not xvm_conf["tankrange"]["circle_binocular"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "distance": binocular_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "thickness": (binocular_distance*0.25)-14, "distance": binocular_distance*0.5 } }) # Add standard Circles if coated_optics == True: view_distance = min(view_distance * 1.1, 500) if xvm_conf["tankrange"]["circle_view"]["enabled"]: if xvm_conf["tankrange"]["spotting_limit"]: view_distance = min(445, view_distance); if not xvm_conf["tankrange"]["circle_view"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "distance": view_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "thickness": (view_distance*0.25)-14, "distance": view_distance*0.5 } }) # Add Artillery Range if xvm_conf["tankrange"]["circle_artillery"]["enabled"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags: artillery_range = 0 for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]: artillery_range = max(artillery_range, round(math.pow(shell["speed"],2) / shell["gravity"])) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Calculated Firing Range:", artillery_range) if not xvm_conf["tankrange"]["circle_artillery"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "distance": artillery_range } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "thickness": (artillery_range*0.25)-14, "distance": artillery_range*0.5 } }) # Write result f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2, sort_keys=True))) f.close() @process def __updateCrew(self): from gui.shared.utils.requesters import Requester self.__crew.clear() barracks = yield Requester('tankman').getFromInventory() for tankman in barracks: for crewman in self.item.crew: if crewman[1] is not None and crewman[1].invID == tankman.inventoryId: crew_member = { "level": tankman.descriptor.roleLevel, "skill": {} } skills = [] for skill_name in tankman.descriptor.skills: skills.append({ "name": skill_name, "level": 100 }) if len(skills) != 0: skills[-1]["level"] = tankman.descriptor.lastSkillLevel for skill in skills: crew_member["skill"][skill["name"]] = skill["level"] self.__crew[tankman.descriptor.role] = crew_member def __isOptionalEquipped(self, optional_name): for item in self.item.descriptor.optionalDevices: if item is not None and optional_name in item.name: return True return False def __isConsumableEquipped(self, consumable_name): from gui.shared.utils.requesters import VehicleItemsRequester for item in self.item.eqsLayout: if item is not None and consumable_name in item.descriptor.name: return True return False def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide('updateCurrentVehicle') def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None def __checkPrebattleLockedVehicle(self): clientPrb = prb_control.getClientPrebattle() if clientPrb is not None: rosters = prb_control.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '') if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __repr__(self): return 'CurrentVehicle(%s)' % str(self.item)
class SettingsCache(ISettingsCache): def __init__(self): self.__intSettings = IntSettingsRequester() self.__waitForSync = False self.onSyncStarted = Event() self.onSyncCompleted = Event() def init(self): g_clientUpdateManager.addCallbacks({'intUserSettings': self._onResync}) def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() g_clientUpdateManager.removeObjectCallbacks(self) @property def waitForSync(self): return self.__waitForSync @property def settings(self): return self.__intSettings def _onResync(self, *args): self.__invalidateData() @async def update(self, callback=None): self.__invalidateData(callback) def getSectionSettings(self, section, defaultValue=0): return self.__intSettings.getSetting(section, defaultValue) def setSectionSettings(self, section, value): self.__intSettings.setSetting(section, value) def setSettings(self, settings): self.__intSettings.setSettings(settings) def getSetting(self, key, defaultValue=0): return self.__intSettings.getSetting(key, defaultValue) def getVersion(self, defaultValue=0): return self.__intSettings.getSetting(VERSION, defaultValue) def setVersion(self, value): self.__intSettings.setSetting(VERSION, value) def delSettings(self, settings): self.__intSettings.delSettings(settings) def __invalidateData(self, callback=lambda *args: None): def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted() callback(*args) self.__waitForSync = True self.onSyncStarted() import BattleReplay if BattleReplay.g_replayCtrl.isPlaying: cbWrapper(dict()) return self.__intSettings.request()(cbWrapper)
class NYScreen(NYHelperView, NYScreenMeta): _newYearController = dependency.descriptor(INewYearController) tabSlotsMapping = {'tree': ['top', 'hanging', 'garland', 'gift'], 'snowman': ['snowman'], 'house': ['house_decoration', 'house_lamp'], 'light': ['street_garland']} __background_alpha__ = 0.0 def __init__(self, ctx = None): super(NYScreen, self).__init__(ctx) self.__currentTabId = None self._initialize(ctx) self.__mouseEvent = Event() return def onClose(self): self.__switchToHangar() def onCraftButtonClick(self): NYSoundEvents.playSound(NYSoundEvents.ON_CRAFT_CLICK) self._switchToCraft(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN) def onCollectionButtonClick(self): NYSoundEvents.playCloseCustomization(Mappings.ID_TO_ANCHOR[self.__currentTabId]) self._switchToGroups(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN, tabId=self.__currentTabId) def onToyFragmentButtonClick(self): NYSoundEvents.playSound(NYSoundEvents.ON_TOY_FRAGMENT_CLICK) self._switchToBreak(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN) def onTabButtonClick(self, tabID): if tabID == self.__currentTabId: return self.__currentTabId = tabID self.as_enableBtnsS(False) NYSoundEvents.playSound(NYSoundEvents.ON_TAB_CLICK) if tabID in Mappings.ID_TO_ANCHOR: newState = Mappings.ID_TO_ANCHOR[tabID] if self._customizableObjMgr.state != newState: self._customizableObjMgr.switchTo(Mappings.ID_TO_ANCHOR[tabID], partial(self.__showViewById, tabID)) else: self.__showViewById(tabID) def onAwardsButtonClick(self): NYSoundEvents.playCloseCustomization(Mappings.ID_TO_ANCHOR[self.__currentTabId]) self._switchToRewards(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN) def moveSpace(self, x, y, delta): self.__mouseEvent(x, y, delta) def _invalidate(self, ctx = None): super(NYScreen, self)._invalidate(ctx) self._initialize(ctx) def _initialize(self, ctx = None): if ctx and 'tabId' in ctx: self.__currentTabId = ctx['tabId'] else: default = NY_CONSTANTS.SIDE_BAR_TREE_ID state = self._customizableObjMgr.state self.__currentTabId = Mappings.ANCHOR_TO_ID[state] if state in Mappings.ANCHOR_TO_ID else default def _populate(self): super(NYScreen, self)._populate() self._newYearController.boxStorage.onCountChanged += self.__onBoxCountChanged self._newYearController.onProgressChanged += self.__onProgressUpdated self._newYearController.onToyFragmentsChanged += self.__onToyFragmentsChanged self._newYearController.onInventoryUpdated += self.__onInventoryUpdated self._newYearController.onToysBreakStarted += self._onToysBreakStarted self._newYearController.onToysBreak += self._onToysBreak self._newYearController.onToysBreakFailed += self._onToysBreakFailed self.__linkCameraWithMouseEvents() NYSoundEvents.playOpenCustomization(self.__currentTabId) data, awardsCounter, progress = self.__makeVO() self.as_initS(data) self.as_updateNYAwardsCounterS(awardsCounter) self.__updateCounter() self.as_updateNYProgressS(progress) self.__onInventoryUpdated() def __onInventoryUpdated(self): newToys = dict.fromkeys(self.tabSlotsMapping.keys(), 0) for type, toys in self._newYearController.getInventory().iteritems(): for toy in toys.values(): for tab, slots in self.tabSlotsMapping.iteritems(): if type in slots: newToys[tab] += toy.newCount break for tab, newCount in newToys.iteritems(): self.as_setTabButtonCounterS(tab, str(newCount)) def _dispose(self): self._newYearController.boxStorage.onCountChanged -= self.__onBoxCountChanged self._newYearController.onProgressChanged -= self.__onProgressUpdated self._newYearController.onToyFragmentsChanged -= self.__onToyFragmentsChanged self._newYearController.onInventoryUpdated -= self.__onInventoryUpdated self._newYearController.onToysBreakStarted -= self._onToysBreakStarted self._newYearController.onToysBreak -= self._onToysBreak self._newYearController.onToysBreakFailed -= self._onToysBreakFailed self.__unlinkCameraFromMouseEvents() self.__mouseEvent.clear() super(NYScreen, self)._dispose() def __switchToHangar(self): self._customizableObjMgr.switchTo(None, lambda : self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY)) return def _onToysBreakStarted(self): self.as_onBreakStartS() def _onToysBreak(self, toyIndexes, fromSlot): self.as_onBreakS() def _onToysBreakFailed(self): self.as_onBreakFailS() def __onProgressUpdated(self, nyProgress): self.as_updateNYLevelS(nyProgress.level) self.as_updateNYProgressS(nyProgress.progress / float(nyProgress.bound)) def __onToyFragmentsChanged(self, fragmentsCount): self.as_updateNYTOYFragmentS(BigWorld.wg_getIntegralFormat(fragmentsCount)) def __onBoxCountChanged(self, *args): self.__updateCounter() def __updateCounter(self): self.as_updateNYBoxCounterS(self._newYearController.boxStorage.count) def __makeVO(self): nyLevel, _, nyProgress, nyBound = self._newYearController.getProgress() normalizedProgress = nyProgress / float(nyBound) nyAwardsCounter = str(self.__getRewardsCounter()) toyFragment = BigWorld.wg_getIntegralFormat(self._newYearController.getToyFragments()) tabIndex = NewYearObjectIDs.ALL.index(self.__currentTabId) self.__currentTabId = None res = {'craftBtnLabel': NY.SCREEN_CRAFTBTN_LABEL, 'sideBarData': UiTabs.ALL, 'level': nyLevel, 'toyFragment': toyFragment, 'sideBarSelectedItemIndex': tabIndex} return (res, nyAwardsCounter, normalizedProgress) def __showViewById(self, tabID): self.as_showViewByIdS(tabID) self.as_enableBtnsS(True) def __linkCameraWithMouseEvents(self): cameraSwitcher = self._customizableObjMgr.getSwitchHandler(CameraSwitcher) if cameraSwitcher is not None: cameraSwitcher.subscribeToMouseEvents(self.__mouseEvent) return def __unlinkCameraFromMouseEvents(self): cameraSwitcher = self._customizableObjMgr.getSwitchHandler(CameraSwitcher) if cameraSwitcher is not None: cameraSwitcher.unsubscribeFromMouseEvents(self.__mouseEvent) return def __getRewardsCounter(self): discountSums = (sum(self._newYearController.vehDiscountsStorage.getDiscounts().values()), sum(self._newYearController.tankmanDiscountsStorage.getDiscounts().values())) counter = sum(discountSums) return counter
class CompanyBattleController(Notifiable): def __init__(self, eventsCache): self.__eventsCache = weakref.proxy(eventsCache) self.onCompanyStateChanged = Event() super(CompanyBattleController, self).__init__() self.__isLobbyLoaded = False self.__delayedCompanyState = [] def start(self): g_eventBus.addListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited) g_playerEvents.onAvatarBecomePlayer += self.__onAvatarBecomePlayer g_connectionManager.onDisconnected += self.__onDisconnected self.setNotificators() def stop(self): self.onCompanyStateChanged.clear() self.clearNotification() g_eventBus.removeListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited) g_playerEvents.onAvatarBecomePlayer -= self.__onAvatarBecomePlayer g_connectionManager.onDisconnected -= self.__onDisconnected def setNotificators(self): battle = self.__eventsCache.getCompanyBattles() self.clearNotification() if battle.isValid(): destroyingTimeLeft = battle.getDestroyingTimeLeft() if destroyingTimeLeft is not None: if destroyingTimeLeft <= 0: self.__onCompanyFinished() else: self.addNotificators(AcyclicNotifier(battle.getDestroyingTimeLeft, self.__onCompanyFinished)) if battle.isCreationTimeCorrect(): self.__onCompanyStarted() else: self.addNotificators(AcyclicNotifier(battle.getCreationTimeLeft, self.__onCompanyStarted)) self.startNotification() else: self.__onCompanyFinished() return def __onLobbyInited(self, *args): self.__isLobbyLoaded = True self.__handlePostponed() def __onAvatarBecomePlayer(self): self.__isLobbyLoaded = False def __onDisconnected(self): self.__isLobbyLoaded = False def __onCompanyStarted(self): if self.__isLobbyLoaded: self.onCompanyStateChanged(True) else: self.__delayedCompanyState.append(True) def __onCompanyFinished(self): if self.__isLobbyLoaded: self.onCompanyStateChanged(False) else: self.__delayedCompanyState.append(False) def __handlePostponed(self): for companyState in self.__delayedCompanyState: self.onCompanyStateChanged(companyState) self.__delayedCompanyState = []
class _EventsCache(object): USER_QUESTS = (EVENT_TYPE.BATTLE_QUEST, EVENT_TYPE.TOKEN_QUEST, EVENT_TYPE.FORT_QUEST, EVENT_TYPE.PERSONAL_QUEST, EVENT_TYPE.POTAPOV_QUEST) SYSTEM_QUESTS = (EVENT_TYPE.REF_SYSTEM_QUEST,) def __init__(self): self.__progress = QuestsProgressRequester() self.__waitForSync = False self.__invalidateCbID = None self.__cache = defaultdict(dict) self.__actionsCache = defaultdict(lambda : defaultdict(dict)) self.__questsDossierBonuses = defaultdict(set) self.__potapov = PQController(self) self.onSyncStarted = Event() self.onSyncCompleted = Event() return def init(self): self.__potapov.init() def fini(self): self.__potapov.fini() self.onSyncStarted.clear() self.onSyncCompleted.clear() self.__clearInvalidateCallback() def clear(self): quests_caches.clearNavInfo() @property def waitForSync(self): return self.__waitForSync @property def questsProgress(self): return self.__progress @property def potapov(self): return self.__potapov @async @process def update(self, diff = None, callback = None): yield self.__progress.request() isNeedToInvalidate = True isNeedToClearItemsCaches = False def _cbWrapper(*args): self.__potapov.update(diff) callback(*args) if diff is not None: isQPUpdated = 'quests' in diff isEventsDataUpdated = ('eventsData', '_r') in diff or 'eventsData' in diff isNeedToInvalidate = isQPUpdated or isEventsDataUpdated hasVehicleUnlocks = False for intCD in diff.get('stats', {}).get('unlocks', set()): if getTypeOfCompactDescr(intCD) == GUI_ITEM_TYPE.VEHICLE: hasVehicleUnlocks = True break isNeedToClearItemsCaches = 'inventory' in diff and GUI_ITEM_TYPE.VEHICLE in diff['inventory'] or hasVehicleUnlocks if isNeedToInvalidate: self.__invalidateData(_cbWrapper) return else: if isNeedToClearItemsCaches: self.__clearQuestsItemsCache() _cbWrapper(True) return def getQuests(self, filterFunc = None): filterFunc = filterFunc or (lambda a: True) def userFilterFunc(q): return not q.isHidden() and filterFunc(q) return self._getQuests(userFilterFunc) def getHiddenQuests(self, filterFunc = None): filterFunc = filterFunc or (lambda a: True) def hiddenFilterFunc(q): return q.isHidden() and filterFunc(q) return self._getQuests(hiddenFilterFunc) def getAllQuests(self, filterFunc = None, includePotapovQuests = False): return self._getQuests(filterFunc, includePotapovQuests) def getActions(self, filterFunc = None): actions = self.__getActionsData() filterFunc = filterFunc or (lambda a: True) result = {} for aData in actions: if 'id' in aData: a = self._makeAction(aData['id'], aData) if not filterFunc(a): continue result[a.getID()] = a return result def getEventBattles(self): battles = self.__getEventBattles() if len(battles): return EventBattles(battles.get('vehicleTags', set()), battles.get('vehicles', []), bool(battles.get('enabled', 0)), battles.get('arenaTypeID')) else: return None def getEvents(self, filterFunc = None): svrEvents = self.getQuests(filterFunc) svrEvents.update(self.getActions(filterFunc)) return svrEvents def getCurrentEvents(self): return self.getEvents(lambda q: q.getStartTimeLeft() <= 0 < q.getFinishTimeLeft()) def getFutureEvents(self): return self.getEvents(lambda q: q.getStartTimeLeft() > 0) def getHistoricalBattles(self, hideExpired = True, filterFunc = None): battles = self.__getHistoricalBattlesData() filterFunc = filterFunc or (lambda a: True) result = {} for bID, bData in battles.iteritems(): b = self._makeHistoricalBattle(bID, bData) if hideExpired and b.isOutOfDate(): continue if not filterFunc(b): continue result[bID] = b return result def getItemAction(self, item, isBuying = True, forCredits = False): result = [] type = ACTION_MODIFIER_TYPE.DISCOUNT if isBuying else ACTION_MODIFIER_TYPE.SELLING itemTypeID = item.itemTypeID nationID = item.nationID intCD = item.intCD values = self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(nationID, []) values += self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(15, []) for (key, value), actionID in values: if item.isPremium and key in ('creditsPrice', 'creditsPriceMultiplier') and not forCredits: continue result.append((value, actionID)) result.extend(self.__actionsCache[ACTION_SECTION_TYPE.ITEM][type].get(itemTypeID, {}).get(intCD, tuple())) return result def getRentAction(self, item, rentPackage): result = [] type = ACTION_MODIFIER_TYPE.RENT itemTypeID = item.itemTypeID nationID = item.nationID intCD = item.intCD values = self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(nationID, []) values += self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(15, []) for (key, value), actionID in values: result.append((value, actionID)) result.extend(self.__actionsCache[ACTION_SECTION_TYPE.ITEM][type].get(itemTypeID, {}).get((intCD, rentPackage), tuple())) return result def getEconomicsAction(self, name): result = self.__actionsCache[ACTION_SECTION_TYPE.ECONOMICS][ACTION_MODIFIER_TYPE.DISCOUNT].get(name, []) resultMult = self.__actionsCache[ACTION_SECTION_TYPE.ECONOMICS][ACTION_MODIFIER_TYPE.DISCOUNT].get('%sMultiplier' % name, []) return tuple(result + resultMult) def getCamouflageAction(self, vehicleIntCD): return self.__actionsCache[ACTION_SECTION_TYPE.CUSTOMIZATION][ACTION_MODIFIER_TYPE.DISCOUNT].get(vehicleIntCD, tuple()) def getEmblemsAction(self, group): return self.__actionsCache[ACTION_SECTION_TYPE.CUSTOMIZATION][ACTION_MODIFIER_TYPE.DISCOUNT].get(group, tuple()) def getQuestsDossierBonuses(self): return self.__questsDossierBonuses def getQuestsByTokenRequirement(self, token): result = [] for q in self._getQuests(includePotapovQuests=True).itervalues(): if token in map(lambda t: t.getID(), q.accountReqs.getTokens()): result.append(q) return result def getQuestsByTokenBonus(self, token): result = [] for q in self._getQuests(includePotapovQuests=True).itervalues(): for t in q.getBonuses('tokens'): if token in t.getTokens().keys(): result.append(q) break return result def _getQuests(self, filterFunc = None, includePotapovQuests = False): quests = self.__getQuestsData() quests.update(self.__getFortQuestsData()) quests.update(self.__getPersonalQuestsData()) filterFunc = filterFunc or (lambda a: True) result = {} for qID, qData in quests.iteritems(): q = self._makeQuest(qID, qData) if q.getDestroyingTimeLeft() <= 0: continue if not filterFunc(q): continue result[qID] = q if includePotapovQuests: for qID, q in self.potapov.getQuests().iteritems(): if filterFunc(q): result[qID] = q children, parents = self._makeQuestsRelations(result) for qID, q in result.iteritems(): if qID in children: q.setChildren(children[qID]) if qID in parents: q.setParents(parents[qID]) return result def _onResync(self, *args): self.__invalidateData() def _makeQuest(self, qID, qData): storage = self.__cache['quests'] if qID in storage: return storage[qID] q = storage[qID] = createQuest(qData.get('type', 0), qID, qData, self.__progress.getQuestProgress(qID), self.__progress.getTokenExpiryTime(qData.get('requiredToken'))) return q def _makeAction(self, aID, aData): storage = self.__cache['actions'] if aID in storage: return storage[aID] a = storage[aID] = Action(aID, aData) return a def _makeHistoricalBattle(self, bID, bData): storage = self.__cache['historicalBattles'] if bID in storage: return storage[bID] b = storage[bID] = HistoricalBattle(bID, bData) return b @classmethod def _makeQuestsRelations(cls, quests): makeTokens = defaultdict(list) needTokens = defaultdict(list) for qID, q in quests.iteritems(): tokens = q.getBonuses('tokens') if len(tokens): for t in tokens[0].getTokens(): makeTokens[t].append(qID) for t in q.accountReqs.getTokens(): needTokens[qID].append(t.getID()) children = defaultdict(dict) for parentID, tokensIDs in needTokens.iteritems(): for tokenID in tokensIDs: children[parentID][tokenID] = makeTokens.get(tokenID, []) parents = defaultdict(dict) for parentID, tokens in children.iteritems(): for tokenID, chn in tokens.iteritems(): for childID in chn: parents[childID][tokenID] = [parentID] return (children, parents) def __invalidateData(self, callback = lambda *args: None): self.__clearCache() self.__clearInvalidateCallback() self.__waitForSync = True self.onSyncStarted() def mergeValues(a, b): result = list(a) result.extend(b) return result for action in self.getActions().itervalues(): for modifier in action.getModifiers(): section = modifier.getSection() type = modifier.getType() itemType = modifier.getItemType() values = modifier.getValues(action) currentSection = self.__actionsCache[section][type] if itemType is not None: currentSection = currentSection.setdefault(itemType, {}) for k in values: if k in currentSection: currentSection[k] = mergeValues(currentSection[k], values[k]) else: currentSection[k] = values[k] rareAchieves = set() invalidateTimeLeft = sys.maxint for q in self.getCurrentEvents().itervalues(): dossierBonuses = q.getBonuses('dossier') if len(dossierBonuses): storage = self.__questsDossierBonuses[q.getID()] for bonus in dossierBonuses: records = bonus.getRecords() storage.update(records) rareAchieves |= set((r for r in records if r[0] == ACHIEVEMENT_BLOCK.RARE)) timeLeftInfo = q.getNearestActivityTimeLeft() if timeLeftInfo is not None: isAvailable, errorMsg = q.isAvailable() if not isAvailable: if errorMsg in ('invalid_weekday', 'invalid_time_interval'): invalidateTimeLeft = min(invalidateTimeLeft, timeLeftInfo[0]) else: intervalBeginTimeLeft, (intervalStart, intervalEnd) = timeLeftInfo invalidateTimeLeft = min(invalidateTimeLeft, intervalBeginTimeLeft + intervalEnd - intervalStart) else: invalidateTimeLeft = min(invalidateTimeLeft, q.getFinishTimeLeft()) g_rareAchievesCache.request(rareAchieves) for q in self.getFutureEvents().itervalues(): timeLeftInfo = q.getNearestActivityTimeLeft() if timeLeftInfo is None: startTime = q.getStartTimeLeft() else: startTime = timeLeftInfo[0] invalidateTimeLeft = min(invalidateTimeLeft, startTime) for hb in self.getHistoricalBattles().itervalues(): timeLeftInfo = hb.getNearestActivityTimeLeft() if timeLeftInfo is None: startTime = hb.getFinishTimeLeft() else: startTime = timeLeftInfo[0] invalidateTimeLeft = min(invalidateTimeLeft, startTime) if invalidateTimeLeft != sys.maxint: self.__loadInvalidateCallback(invalidateTimeLeft) self.__waitForSync = False self.onSyncCompleted() callback(True) from gui.shared import g_eventBus g_eventBus.handleEvent(events.LobbySimpleEvent(events.LobbySimpleEvent.EVENTS_UPDATED)) return def __clearQuestsItemsCache(self): for qID, q in self._getQuests().iteritems(): q.accountReqs.clearItemsCache() q.vehicleReqs.clearItemsCache() @classmethod def __getEventsData(cls, eventsTypeName): try: if isPlayerAccount(): if eventsTypeName in BigWorld.player().eventsData: return pickle.loads(zlib.decompress(BigWorld.player().eventsData[eventsTypeName])) return {} LOG_ERROR('Trying to get quests data from not account player', eventsTypeName, BigWorld.player()) except Exception: LOG_CURRENT_EXCEPTION() return {} def __getQuestsData(self): return self.__getEventsData(EVENT_CLIENT_DATA.QUEST) def __getFortQuestsData(self): return self.__getEventsData(EVENT_CLIENT_DATA.FORT_QUEST) def __getPersonalQuestsData(self): return self.__getEventsData(EVENT_CLIENT_DATA.PERSONAL_QUEST) def __getActionsData(self): return self.__getEventsData(EVENT_CLIENT_DATA.ACTION) def __getEventBattles(self): return self.__getEventsData(EVENT_CLIENT_DATA.INGAME_EVENTS).get('eventBattles', {}) def __getHistoricalBattlesData(self): return self.__getEventsData(EVENT_CLIENT_DATA.HISTORICAL_BATTLES) def __loadInvalidateCallback(self, duration): LOG_DEBUG('load quest window invalidation callback (secs)', duration) self.__clearInvalidateCallback() self.__invalidateCbID = BigWorld.callback(math.ceil(duration), self.__invalidateData) def __clearInvalidateCallback(self): if self.__invalidateCbID is not None: BigWorld.cancelCallback(self.__invalidateCbID) self.__invalidateCbID = None return def __clearCache(self): self.__questsDossierBonuses.clear() self.__actionsCache.clear() for storage in self.__cache.itervalues(): storage.clear()
class _CurrentVehicle(): def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.onChanged = Event() self.onChangeStarted = Event() return def init(self): g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate, 'cache.vehsLock': self.onLocksUpdate}) prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) g_hangarSpace.removeVehicle() self.selectNoVehicle() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']: isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() elif 'repair' in vehsDiff: isRepaired = self.__vehInvID in vehsDiff['repair'] if not GUI_ITEM_TYPE.TURRET in invDiff: isComponentsChanged = GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive, vehsDiff.itervalues())) > 0 (isComponentsChanged or isRepaired or isVehicleDescrChanged) and self.refreshModel() (isVehicleChanged or isRepaired) and self.onChanged() return def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: g_hangarSpace.updateVehicle(self.item) else: g_hangarSpace.removeVehicle() @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): if self.isPresent() and self.item.isAutoLoad: for shell in self.item.shells: if shell.count != shell.defaultCount: return False return True def isAutoEquipFull(self): if self.isPresent() and self.item.isAutoEquip: return self.item.eqs == self.item.eqsLayout return True def selectVehicle(self, vehInvID = 0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) return def selectNoVehicle(self): self.__selectVehicle(0) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() return ('#menu:currentVehicleStatus/' + state, stateLvl) return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL) def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show('updateCurrentVehicle', isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide('updateCurrentVehicle') def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None return def __checkPrebattleLockedVehicle(self): clientPrb = prb_control.getClientPrebattle() if clientPrb is not None: rosters = prb_control.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '') if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __repr__(self): return 'CurrentVehicle(%s)' % str(self.item)
class BaseAmmunitionPanelView(ViewImpl): _itemsCache = dependency.descriptor(IItemsCache) __slots__ = ('_ammunitionPanel', 'onSizeChanged', 'onPanelSectionSelected', 'onPanelSectionResized') def __init__(self, flags=ViewFlags.VIEW): settings = ViewSettings(R.views.lobby.tanksetup.AmmunitionPanel()) settings.flags = flags settings.model = AmmunitionPanelViewModel() super(BaseAmmunitionPanelView, self).__init__(settings) self.onSizeChanged = Event() self.onPanelSectionSelected = Event() self.onPanelSectionResized = Event() def createToolTip(self, event): if event.contentID == R.views.common.tooltip_window.backport_tooltip_content.BackportTooltipContent( ): tooltipData = getSlotTooltipData( event, g_currentVehicle.item, self.viewModel.ammunitionPanel.getSelectedSlot()) if tooltipData is not None: window = BackportTooltipWindow(tooltipData, self.getParentWindow()) window.load() return window return super(BaseAmmunitionPanelView, self).createToolTip(event) def createToolTipContent(self, event, contentID): return ShellsInfo( event.contentID, g_currentVehicle.item ) if event.contentID == R.views.lobby.tanksetup.tooltips.ShellsInfo( ) else super(BaseAmmunitionPanelView, self).createToolTipContent( event, contentID) def createContextMenuContent(self, event): if event.contentID != R.views.common.BackportContextMenu(): super(BaseAmmunitionPanelView, self).createContextMenuContent(event) contextMenuData = getHangarContextMenuData(event, self.uniqueID) return BackportContextMenuContent( contextMenuData) if contextMenuData is not None else super( BaseAmmunitionPanelView, self).createContextMenuContent(event) def setHangarSwitchAnimState(self, isComplete): self.viewModel.setIsReady(isComplete) @property def viewModel(self): return super(BaseAmmunitionPanelView, self).getViewModel() def setLastSlotAction(self, *args, **kwargs): setLastSlotAction(self.viewModel, g_currentVehicle.item, *args, **kwargs) def update(self, fullUpdate=True): if fullUpdate: clearLastSlotAction(self.viewModel) self.viewModel.setIsMaintenanceEnabled(not g_currentVehicle.isLocked()) self.viewModel.setIsDisabled(self._getIsDisabled()) self._ammunitionPanel.update(g_currentVehicle.item, fullUpdate=fullUpdate) def destroy(self): self.onSizeChanged.clear() self.onPanelSectionSelected.clear() self.onPanelSectionResized.clear() super(BaseAmmunitionPanelView, self).destroy() def _onLoading(self, *args, **kwargs): super(BaseAmmunitionPanelView, self)._onLoading(*args, **kwargs) self._ammunitionPanel = self._createAmmunitionPanel() self._ammunitionPanel.onLoading() def _onLoaded(self, *args, **kwargs): super(BaseAmmunitionPanelView, self)._onLoaded(*args, **kwargs) self.viewModel.setIsReady(True) def _initialize(self, *args, **kwargs): super(BaseAmmunitionPanelView, self)._initialize() self._addListeners() self._ammunitionPanel.initialize() self.update(fullUpdate=False) def _finalize(self): self._removeListeners() self._ammunitionPanel.finalize() super(BaseAmmunitionPanelView, self)._finalize() def _createAmmunitionPanel(self): return HangarAmmunitionPanel(self.viewModel.ammunitionPanel, g_currentVehicle.item) def _addListeners(self): self.viewModel.onViewSizeInitialized += self.__onViewSizeInitialized self.viewModel.ammunitionPanel.onSectionSelect += self._onPanelSectionSelected self.viewModel.ammunitionPanel.onSectionResized += self._onPanelSectionResized g_currentVehicle.onChangeStarted += self.__onVehicleChangeStarted g_currentVehicle.onChanged += self._currentVehicleChanged self._itemsCache.onSyncCompleted += self.__itemCacheChanged def _removeListeners(self): self.viewModel.onViewSizeInitialized -= self.__onViewSizeInitialized self.viewModel.ammunitionPanel.onSectionSelect -= self._onPanelSectionSelected self.viewModel.ammunitionPanel.onSectionResized -= self._onPanelSectionResized g_currentVehicle.onChangeStarted -= self.__onVehicleChangeStarted g_currentVehicle.onChanged -= self._currentVehicleChanged self._itemsCache.onSyncCompleted -= self.__itemCacheChanged def _onPanelSectionSelected(self, args): if not self._getIsDisabled(): clearLastSlotAction(self.viewModel) self.onPanelSectionSelected(**args) def _onPanelSectionResized(self, kwargs): self.onPanelSectionResized(**kwargs) def _currentVehicleChanged(self): self.update() def __onVehicleChangeStarted(self): self.viewModel.setIsMaintenanceEnabled(False) self.viewModel.setIsDisabled(True) def __itemCacheChanged(self, *_): self.update(fullUpdate=False) @staticmethod def _getIsDisabled(): return not g_currentVehicle.isInHangar() or g_currentVehicle.isLocked( ) or g_currentVehicle.isBroken() def __onViewSizeInitialized(self, args=None): self.onSizeChanged(args.get('width', 0), args.get('height', 0), args.get('offsetY', 0))
class ServerSettings(object): def __init__(self, serverSettings): self.onServerSettingsChange = Event() self.__serverSettings = copy.deepcopy( serverSettings) if serverSettings else {} if 'roaming' in self.__serverSettings: roamingSettings = self.__serverSettings['roaming'] self.__roamingSettings = RoamingSettings( roamingSettings[0], roamingSettings[1], [_ServerInfo(*s) for s in roamingSettings[2]]) else: self.__roamingSettings = RoamingSettings.defaults() if 'file_server' in self.__serverSettings: self.__fileServerSettings = _FileServerSettings( self.__serverSettings['file_server']) else: self.__fileServerSettings = _FileServerSettings.defaults() if 'regional_settings' in self.__serverSettings: self.__regionalSettings = makeTupleByDict( _RegionalSettings, self.__serverSettings['regional_settings']) else: self.__regionalSettings = _RegionalSettings.defaults() try: self.__eSportCurrentSeason = makeTupleByDict( _ESportCurrentSeason, self.__serverSettings) except TypeError: self.__eSportCurrentSeason = _ESportCurrentSeason.defaults() if 'clanProfile' in self.__serverSettings: self.__updateClanProfile(self.__serverSettings) else: self.__clanProfile = _ClanProfile.defaults() if 'spgRedesignFeatures' in self.__serverSettings: self.__spgRedesignFeatures = makeTupleByDict( _SpgRedesignFeatures, self.__serverSettings['spgRedesignFeatures']) else: self.__spgRedesignFeatures = _SpgRedesignFeatures.defaults() if 'strongholdSettings' in self.__serverSettings: settings = self.__serverSettings['strongholdSettings'] self.__strongholdSettings = _StrongholdSettings( settings.get('wgshHostUrl', '')) else: self.__strongholdSettings = _StrongholdSettings.defaults() if 'rankedBattles' in self.__serverSettings: self.__bwRankedBattles = makeTupleByDict( _BwRankedBattles, self.__serverSettings['rankedBattles']) else: self.__bwRankedBattles = _BwRankedBattles() if 'hallOfFame' in self.__serverSettings: self.__bwHallOfFame = makeTupleByDict( _BwHallOfFame, self.__serverSettings['hallOfFame']) else: self.__bwHallOfFame = _BwHallOfFame() if 'ranked_config' in self.__serverSettings: self.__rankedBattlesSettings = makeTupleByDict( _RankedBattlesConfig, self.__serverSettings['ranked_config']) else: self.__rankedBattlesSettings = _RankedBattlesConfig() def update(self, serverSettingsDiff): self.__serverSettings = updateDict(self.__serverSettings, serverSettingsDiff) if 'clanProfile' in serverSettingsDiff: self.__updateClanProfile(serverSettingsDiff) if 'spgRedesignFeatures' in self.__serverSettings: self.__spgRedesignFeatures = makeTupleByDict( _SpgRedesignFeatures, self.__serverSettings['spgRedesignFeatures']) if 'ranked_config' in serverSettingsDiff: self.__updateRanked(serverSettingsDiff) self.onServerSettingsChange(serverSettingsDiff) def clear(self): self.onServerSettingsChange.clear() def getSettings(self): return self.__serverSettings @property def roaming(self): return self.__roamingSettings @property def fileServer(self): return self.__fileServerSettings @property def regionals(self): return self.__regionalSettings @property def eSportCurrentSeason(self): return self.__eSportCurrentSeason @property def clanProfile(self): return self.__clanProfile @property def spgRedesignFeatures(self): return self.__spgRedesignFeatures @property def stronghold(self): return self.__strongholdSettings @property def bwRankedBattles(self): return self.__bwRankedBattles @property def bwHallOfFame(self): return self.__bwHallOfFame @property def rankedBattles(self): return self.__rankedBattlesSettings def isPotapovQuestEnabled(self): return self.isFalloutQuestEnabled() or self.isRegularQuestEnabled() def isRegularQuestEnabled(self): return self.__getGlobalSetting('isRegularQuestEnabled', True) def isFalloutQuestEnabled(self): return self.__getGlobalSetting('isFalloutQuestEnabled', True) def isBuyPotapovQuestTileEnabled(self): return self.__getGlobalSetting('isBuyPotapovQuestTileEnabled', False) def isBuyPotapovQuestSlotEnabled(self): return self.__getGlobalSetting('isBuyPotapovQuestSlotEnabled', False) def isStrongholdsEnabled(self): return self.__getGlobalSetting('strongholdSettings', {}).get('isStrongholdsEnabled', False) def isGoldFishEnabled(self): return self.__getGlobalSetting('isGoldFishEnabled', False) def isTutorialEnabled(self): return self.__getGlobalSetting( 'isTutorialEnabled', IS_TUTORIAL_ENABLED) and not self.isBootcampEnabled() def isSandboxEnabled(self): return self.__getGlobalSetting('isSandboxEnabled', False) def isBootcampEnabled(self): return self.__getGlobalSetting('isBootcampEnabled', False) def isEpicRandomEnabled(self): return self.__getGlobalSetting('isEpicRandomEnabled', False) def isEpicRandomAchievementsEnabled(self): return self.__getGlobalSetting('isEpicRandomAchievementsEnabled', False) def isEpicRandomMarkOfMasteryEnabled(self): return self.__getGlobalSetting('isEpicRandomMarkOfMasteryEnabled', False) def isPromoAutoViewsEnabled(self): if self.isBootcampEnabled(): from bootcamp.Bootcamp import g_bootcamp if g_bootcamp.isRunning(): return False return True def isHofEnabled(self): return self.__getGlobalSetting('hallOfFame', {}).get('isHofEnabled', False) def getMaxSPGinSquads(self): return self.__getGlobalSetting('maxSPGinSquads', 0) def getRandomMapsForDemonstrator(self): return self.__getGlobalSetting('randomMapsForDemonstrator', {}) def isPremiumInPostBattleEnabled(self): return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True) def isVehicleComparingEnabled(self): return bool(self.__getGlobalSetting('isVehiclesCompareEnabled', True)) def isEncyclopediaEnabled(self, tokensCount): switchState = self.__getGlobalSetting('isEncyclopediaEnabled') if switchState == SWITCH_STATE.ALL: state = True elif switchState == SWITCH_STATE.NONE: state = False elif switchState == SWITCH_STATE.TOKEN: state = tokensCount > 0 else: LOG_ERROR( 'Wrong activation state for encyclopedia. Encyclopedia is considered to be disabled' ) state = False return state def isTemplateMatchmakerEnabled(self): return bool( self.__getGlobalSetting('isTemplateMatchmakerEnabled', True)) def isTankmanRestoreEnabled(self): return self.__getGlobalSetting('isTankmanRestoreEnabled', True) def isVehicleRestoreEnabled(self): return self.__getGlobalSetting('isVehicleRestoreEnabled', True) def __getGlobalSetting(self, settingsName, default=None): return self.__serverSettings.get(settingsName, default) def __updateClanProfile(self, targetSettings): cProfile = targetSettings['clanProfile'] self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False), cProfile.get('gateUrl', ''), cProfile.get('type', 'gateway')) def __updateRanked(self, targetSettings): self.__rankedBattlesSettings = self.__rankedBattlesSettings.replace( targetSettings['ranked_config'])
class ClientDamageProcessor(object): ATTACK_TIMEOUT = 3.5 def __init__(self, config, gameEnvironment): self.PREDICATES = {'teammate': self._teammatePredicate, 'type': self._typePredicate, 'ACType': self._acTypePredicate} params = config[PARAMS_FIELD] self._reward = params[REWARD_FIELD] self._eventId = params[ID_FIELD] self._progressStep = params[PROGRESS_STEP_FIELD] self.eDamage = Event() self._gameEnvironment = gameEnvironment self._linkEvents(gameEnvironment) self._avatarsDamageRemainders = dict() self._currentTarget = 0 self._targetWithAccumulatedDamage = 0 self._targetAccumulator = 0 self._createPredicates(params) def _createPredicates(self, config): self._predicates = [] predicates = config[PREDICATES_FIELD] if predicates is not None: for pId in predicates: self._predicates.append((self.PREDICATES[pId], predicates[pId])) return def _processDamage(self, avatarId, health, lastDamagerId, oldHealth, maxHealth): damage = oldHealth - health if not (lastDamagerId == BigWorld.player().id and all((predicate(avatarId, result) for predicate, result in self._predicates))) or damage <= 0: return nowTime = BigWorld.time() savedTargetDamageInfo = self._avatarsDamageRemainders.get(avatarId, (0, nowTime)) accumulatedDamage = damage + savedTargetDamageInfo[0] amount, reminder = getRewardableProgress(accumulatedDamage, maxHealth, self._progressStep) isAccumulatorTimeout = nowTime - savedTargetDamageInfo[1] > ClientDamageProcessor.ATTACK_TIMEOUT self._avatarsDamageRemainders[avatarId] = (reminder, nowTime) if not avatarId == self._currentTarget or isAccumulatorTimeout: self._currentTarget = avatarId self._targetAccumulator = 0 reward = int(amount * self._reward) if reward != 0: self._targetAccumulator += reward accumulatorResetted = self._currentTarget != self._targetWithAccumulatedDamage or isAccumulatorTimeout self._targetWithAccumulatedDamage = self._currentTarget self.eDamage(self._eventId, reward, self._targetAccumulator, accumulatorResetted) elif isAccumulatorTimeout: self._targetWithAccumulatedDamage = 0 def destroy(self): self._unlinkEvents(self._gameEnvironment) self._gameEnvironment = None self._avatarsDamageRemainders = None self.eDamage.clear() self.eDamage = None self.PREDICATES.clear() self._predicates = [] return def _linkEvents(self, gameEnvironment): gameEnvironment.eAvatarAdded += self._onAvatarAdded gameEnvironment.eAvatarRemoved += self._onAvatarRemoved def _unlinkEvents(self, gameEnvironment): gameEnvironment.eAvatarAdded -= self._onAvatarAdded gameEnvironment.eAvatarRemoved -= self._onAvatarRemoved def _onAvatarAdded(self, avatar): avatar.eHealthChanged += self._processDamage def _onAvatarRemoved(self, avatar, isLeaveWorld): if isLeaveWorld: avatar.eHealthChanged -= self._processDamage def _teammatePredicate(self, victimEntityID, needRes): entity = BigWorld.entities.get(victimEntityID, None) if not entity: LOG_WARNING('ECO: _teammatePredicate: entity not found') return False else: player = BigWorld.player() return needRes == (player.teamIndex == entity.teamIndex) def _typePredicate(self, entityId, neededType): result = None entity = BigWorld.entities.get(entityId) if EntityHelpers.isTeamObject(entity): result = 'GroundObject' elif EntityHelpers.isPlayerAvatar(entity): result = 'Player' elif EntityHelpers.isAvatarBot(entity): clientArena = self._gameEnvironment.service('ClientArena') info = clientArena.getAvatarInfo(entityId) isDefender = info.get('defendSector') if bool(isDefender): result = 'Defender' elif bool(info.get('isBomber')): result = 'Bomber' else: result = 'Player' return result == neededType def _acTypePredicate(self, entityId, validTypes): clientArena = self._gameEnvironment.service('ClientArena') objectData = clientArena.allObjectsData[entityId] if 'ACType' not in objectData: return False try: typeName = GROUND_OBJECT_TYPE.getName(objectData['ACType']) except ValueError: return False validTypes = validTypes.split('|') return typeName in validTypes
class ContainerManager(ContainerManagerMeta, IContainerManager): """ The container manager manages overlapping of views and their life time based on their type and scope. Performs loading of views through the specified loader. 1. Overlapping of views UI consists of several layers. Each layer has its own Z index. It allows to control overlapping of views (views of the top level layer overlap views of underlying layers). The set of default layers depends on entry (application) type (lobby and battle have their own configuration). Each view can belong to one layer and it is defined by view's type. With each layer associated one view container that is managed by the container manager. There are two types of layers (view containers): - DefaultContainer - only one top level view can be placed in the container (layer) and if a new view is placed to it the previous one is destroyed; - PopUpContainer - several views can exist at the same time in one layer. Also any top level view can include a subview that is placed into a sub-container. If a top level view can include a sub-view, the sub-container is created after the top level view is loaded and initialized. When sub-view is loaded, it is placed into the top level view's sub-container. The sub-container is destroyed when the top level view is destroyed. 2. Views life time The 'view scope' concept is introduced to simplify views lifetime management. View lifetime is defined by its scope and is controlled by the container manager through the scope controller. View scope defines when the view should be destroyed: if the parent view (parent scope) is destroyed, the subview is destroyed too. For details please see ScopeController description. """ def __init__(self, loader, *containers): super(ContainerManager, self).__init__() self.onViewAddedToContainer = Event() self.__globalContainer = _GlobalViewContainer(weakref.proxy(self)) for container in containers: raise isinstance(container, ViewContainer) or AssertionError self.__globalContainer.addChildContainer(container) self.__loader = loader self.__loader.onViewLoaded += self.__onViewLoaded self.__scopeController = GlobalScopeController() self.__scopeController.create() self.__viewCache = _ViewCollection() self.__chainMng = _ChainManager(weakref.proxy(self)) def _dispose(self): self.__viewCache.destroy() self.__chainMng.destroy() if self.__loader is not None: self.__loader.onViewLoaded -= self.__onViewLoaded self.__loader = None for viewType in _CONTAINERS_DESTROY_ORDER: container = self.__globalContainer.findContainer(viewType) if container is not None: LOG_DEBUG('Destroy container {} ({})'.format( viewType, container)) container.destroy() self.__globalContainer.destroy() self.onViewAddedToContainer.clear() self.__scopeController.destroy() self.__scopeController = None super(ContainerManager, self)._dispose() return def destroyViews(self, alias, name=None): def compareByAlias(view): return view.key.alias == alias def compareByAliasAndName(view): viewKey = view.key return viewKey.alias == alias and viewKey.name == name if name is None: comparator = compareByAlias else: comparator = compareByAliasAndName views = self.__scopeController.findViews(comparator) views.extend(self.__viewCache.findViews(comparator)) for view in views: if not view.isDisposed(): LOG_DEBUG('The view {} will be destroyed...'.format(view)) view.destroy() viewKey = ViewKey(alias, name) chain = self.__chainMng.getChainByViewKey(viewKey) if chain is not None: chain.removeViewByViewKey(viewKey) return def loadChain(self, chainItems): """ Loads the given views (chain items) one after the other. :param chainItems: list of ChainItem items. """ chain = _LoadingChain(chainItems) if self.__chainMng.addChain(chain): chain.run() else: LOG_WARNING( 'Could not add a new chain. Loading of chain [{}] is canceled.' .format(chainItems)) chain.destroy() def load(self, loadParams, *args, **kwargs): """ Loads a view with the given alias and puts it to the appropriate container (layer). :param loadParams: instance of ViewLoadParams :param args: args to be passed to view's constructor. :param kwargs: kwargs to be passed to view's constructor. :return: instance of view (loading or loaded). None if no view is loaded. """ viewKey = loadParams.viewKey viewLoadingItem = self.__loader.getViewLoadingItem(viewKey) if viewLoadingItem is not None: LOG_DEBUG('View with key {} is already loading. item=[{}]'.format( viewKey, viewLoadingItem)) view = viewLoadingItem.pyEntity if loadParams.loadMode == ViewLoadMode.DEFAULT: loadingViewLoadMode = viewLoadingItem.loadParams.loadMode if loadingViewLoadMode == ViewLoadMode.PRELOAD: viewLoadingItem.loadParams = loadParams self.__addLoadingView(view) elif loadParams.loadMode == ViewLoadMode.PRELOAD: pass else: LOG_WARNING( 'Unsupported load mode {}. View loading will be skipped.'. format(loadParams)) view = None else: view = self.__globalContainer.findView(viewKey) if view is None: view = self.__viewCache.getView(viewKey) if view is None: chain = self.__chainMng.getChainByViewKey(viewKey) if chain is not None: LOG_WARNING( 'View with loadParams={} is in the loading chain {}. The request will be skipped.' .format(loadParams, chain)) else: LOG_DEBUG( 'Load view with loadParams={}. Loader=[{}]'.format( loadParams, self.__loader)) if loadParams.loadMode == ViewLoadMode.DEFAULT: view = self.__loader.loadView( loadParams, *args, **kwargs) self.__addLoadingView(view) elif loadParams.loadMode == ViewLoadMode.PRELOAD: view = self.__loader.loadView( loadParams, *args, **kwargs) else: LOG_WARNING( 'Unsupported load mode {}. View loading will be skipped.' .format(loadParams)) elif loadParams.loadMode == ViewLoadMode.PRELOAD: LOG_DEBUG( 'View with key {} ({}) is already pre-loaded.'.format( viewKey, view)) elif loadParams.loadMode == ViewLoadMode.DEFAULT: LOG_DEBUG( 'Load view with loadParams={} from the cache. Cache=[{}]' .format(loadParams, self.__viewCache)) self.__viewCache.removeView(viewKey) self.__showAndInitializeView(view) view.validate(*args, **kwargs) else: LOG_WARNING( 'Unsupported load mode {}. View loading will be skipped.' .format(loadParams)) view = None else: LOG_DEBUG('View with key {} ({}) is already loaded.'.format( viewKey, view)) viewType = view.settings.type viewContainer = self.__globalContainer.findContainer(viewType) viewContainer.addView(view) view.validate(*args, **kwargs) return view def getContainer(self, viewType): """ Returns container by the given type or None if there is no such container. :param viewType: viewType: View type. @see ViewTypes. """ return self.__globalContainer.findContainer(viewType) def isModalViewsIsExists(self): """ Returns True if a modal view exists, otherwise returns False. """ for viewType in _POPUPS_CONTAINERS: container = self.__globalContainer.findContainer(viewType) if container is not None and container.getViewCount(isModal=True): return True return False def getView(self, viewType, criteria=None): """ Gets view by the given type and criteria if it is defined. :param viewType: type of view. @see ViewTypes. :param criteria: criteria to find view in container. :return: instance of view. """ container = self.__globalContainer.findContainer(viewType) if container is not None: return container.getView(criteria=criteria) else: LOG_WARNING('Could not found container {}.'.format(viewType)) return def isViewAvailable(self, viewType, criteria=None): """ If you want to get some view from some container, it`s may be unsafely operation. For example, I want to get a Hangar from a Lobby view. it`s a bad situation and method "getView" detects this state. Then, if you just want to detect an existing View, use isViewAvailable method. :param viewType: type of view. @see ViewTypes. :param criteria: criteria to find view in container. """ container = self.__globalContainer.findContainer(viewType) if container is not None: return container.getView(criteria=criteria) is not None else: return False def showContainers(self, *viewTypes): """ Shows containers for given view types. :param viewTypes: View types """ self.as_showContainersS(viewTypes) def hideContainers(self, *viewTypes): """ Hides containers for given view types. :param viewTypes: View types """ self.as_hideContainersS(viewTypes) def isContainerShown(self, viewType): """ Returns True if a container with the given view type is shown, otherwise returns False. :param viewType: View types """ return self.as_isContainerShownS(viewType) def clear(self): """ Clears pop-ups containers. """ for viewType in _POPUPS_CONTAINERS: container = self.__globalContainer.findContainer(viewType) if container is not None: container.clear() return def closePopUps(self): """ Closes all popUps: widows and dialogs. """ self.as_closePopUpsS() def registerViewContainer(self, viewType, uniqueName): self.as_registerContainerS(viewType, uniqueName) LOG_DEBUG( 'A new container [type={}, name={}] has been registered.'.format( viewType, uniqueName)) def unregisterViewContainer(self, viewType): self.as_unregisterContainerS(viewType) LOG_DEBUG( 'The container [type={}] has been unregistered.'.format(viewType)) def __addLoadingView(self, pyView): viewType = pyView.settings.type viewContainer = self.__globalContainer.findContainer(viewType) if viewContainer is not None: viewContainer.addLoadingView(pyView) else: LOG_WARNING( 'Loading of view {} is requested but the container {} is still not exist!' .format(pyView, viewType)) self.__scopeController.addLoadingView(pyView, False) return def __showAndInitializeView(self, pyView): viewType = pyView.settings.type if viewType is None: LOG_ERROR( 'Type of view is not defined. View {} will be destroyed.', pyView) pyView.destroy() return False else: status = False container = self.__globalContainer.findContainer(viewType) if container is not None: if ViewTypes.DEFAULT == viewType: self.closePopUps() if container.addView(pyView): self.__scopeController.addView(pyView, False) self.as_showS(pyView.uniqueName, 0, 0) pyView.create() self.onViewAddedToContainer(container, pyView) status = True else: LOG_ERROR( '{} view cannot be added to container {} and will be destroyed.' .format(pyView, container)) pyView.destroy() else: LOG_ERROR( 'Type {} of view {} is not supported or container has not been properly created' .format(viewType, pyView)) pyView.destroy() return status def __addViewToCache(self, pyView): view = self.__viewCache.getView(pyView.key) if view is not None: LOG_UNEXPECTED( 'The view with key {} is already in the cache.'.format( pyView.key), pyView, view) if view != pyView: view.destroy() if self.__viewCache.addView(pyView): LOG_DEBUG('View {} has been added to the cache {}'.format( pyView, self.__viewCache)) else: LOG_DEBUG('Cannot add view {} in the cache {}'.format( pyView, self.__viewCache)) elif self.__viewCache.addView(pyView): LOG_DEBUG('View {} has been added to the cache {}'.format( pyView, self.__viewCache)) else: LOG_DEBUG('Cannot add view {} in the cache {}'.format( pyView, self.__viewCache)) return def __onViewLoaded(self, pyView, loadParams): loadMode = loadParams.loadMode if loadMode == ViewLoadMode.DEFAULT: if self.__scopeController.isViewLoading(pyView=pyView): self.__showAndInitializeView(pyView) else: LOG_DEBUG( '{} view loading is cancelled because its scope has been destroyed.' .format(pyView)) pyView.destroy() elif loadMode == ViewLoadMode.PRELOAD: self.__addViewToCache(pyView) else: LOG_WARNING( 'Unsupported load mode {}. View {} will be destroyed.'.format( loadMode, pyView)) pyView.destroy()
class StateManager: def __init__(self): self._stateId = LOADING self._stateName = STATE_MAP[self._stateId] self._stateMachine = None self._goBackSignalID = ON_GO_BACK self._awaitLoadPlaneResources = False self._createEvents() self._createStateMachine() self._initStateMachine() self._interManager = IntermissionStateManager( self, self._onIntermissionActivityChanged, self.eOpenInter, self.eCloseInter, self.eCloseInterForce) self._initStatesEffectController() self.___endDeathStateCallback = None return def _initStatesEffectController(self): from HUDStatesEffectsSettings import EFFECTS_MAP from EffectManager import g_instance self._statesEffectsCtrl = HUDStatesEffectsController( EFFECTS_MAP, g_instance) @property def state(self): return self._stateName def _createEvents(self): self.eStateChanged = Event() self.eToggleHUDVisibility = Event() self.eOpenInter = Event() self.eCloseInter = Event() self.eCloseInterForce = Event() def _createStateMachine(self): stateMapReverse = dict(((v, k) for k, v in STATE_MAP.iteritems())) def stateSetter(stateID, *args): self._onStateChanged(stateID) def stateGetter(): return stateMapReverse.get(self._stateName, None) self._stateMachine = ExternalBitStateMachine(stateSetter, stateGetter, None) return def _initStateMachine(self): self._stateMachine.addState(LOADING, None, None) self._stateMachine.addState(INTRO, None, None) self._stateMachine.addState(BATTLE_DEFAULT, None, None) self._stateMachine.addState(BATTLE_STATS, None, None) self._stateMachine.addState(OUTRO, None, None) self._stateMachine.addState(OUTRO_TAB, None, None) self._stateMachine.addState(RESPAWN_STATE, None, None) self._stateMachine.addState(DEATH_STATE, None, None) self._stateMachine.addState(DEATH_TAB_STATE, None, None) self._stateMachine.addState(LOADING_TAB, None, None) self._stateMachine.addState(INTRO_TAB, None, None) self._stateMachine.addState(RESPAWN_TAB, None, None) self._stateMachine.addState(RESPAWN_DISABLED_STATE, None, None) self._stateMachine.addState(RESPAWN_DISABLED_TAB_STATE, None, None) self._stateMachine.addState(PROMO_STATE, None, None) self._stateMachine.addTransition(LOADING, LOADING_TAB, TAB_DOWN) self._stateMachine.addTransition(LOADING_TAB, LOADING, TAB_UP) self._stateMachine.addTransition(LOADING | LOADING_TAB, BATTLE_DEFAULT, LOADING_FINISHED) self._stateMachine.addTransition( LOADING | LOADING_TAB, INTRO, HAS_CONTROL, lambda *args, **kwargs: self._showStartHint()) self._stateMachine.addTransition(DEATH_STATE, DEATH_TAB_STATE, TAB_DOWN) self._stateMachine.addTransition(DEATH_TAB_STATE, DEATH_STATE, TAB_UP) self._stateMachine.addTransition(INTRO, INTRO_TAB, TAB_DOWN) self._stateMachine.addTransition(INTRO_TAB, INTRO, TAB_UP) self._stateMachine.addTransition( INTRO | LOADING, PRE_BATTLE, INTRO_FINISHED, lambda *args, **kwargs: self._showStartHint()) self._stateMachine.addTransition( LOADING_TAB, PRE_BATTLE_TAB, INTRO_FINISHED, lambda *args, **kwargs: self._showStartHint()) self._stateMachine.addTransition(INTRO_TAB, PRE_BATTLE_TAB, INTRO_FINISHED) self._stateMachine.addTransition( INTRO | INTRO_TAB | LOADING | LOADING_TAB, BATTLE_DEFAULT, ON_PRE_BATTLE_FINISH, lambda *args, **kwargs: self._showStartHint()) self._stateMachine.addTransition( PRE_BATTLE, BATTLE_DEFAULT, ON_PRE_BATTLE_FINISH, lambda *args, **kwargs: self._goToBattle()) self._stateMachine.addTransition( PRE_BATTLE_TAB, BATTLE_STATS, ON_PRE_BATTLE_FINISH, lambda *args, **kwargs: self._goToBattle()) self._stateMachine.addTransition(PRE_BATTLE, PRE_BATTLE_TAB, TAB_DOWN) self._stateMachine.addTransition(PRE_BATTLE_TAB, PRE_BATTLE, TAB_UP) self._stateMachine.addTransition(RESPAWN_STATE, RESPAWN_TAB, TAB_DOWN) self._stateMachine.addTransition(RESPAWN_TAB, RESPAWN_STATE, TAB_UP) self._stateMachine.addTransition( RESPAWN_STATE | SPECTATOR_STATE | SPECTATOR_TACTICAL_STATE, BATTLE_DEFAULT, ON_END_RESPAWN, lambda *args, **kwargs: self._onRespawn()) self._stateMachine.addTransition( RESPAWN_TAB | SPECTATOR_TAB_STATE | SPECTATOR_TAB_TACTICAL_STATE, BATTLE_STATS, ON_END_RESPAWN) self._stateMachine.addTransition(RESPAWN_DISABLED_STATE, RESPAWN_DISABLED_TAB_STATE, TAB_DOWN) self._stateMachine.addTransition(RESPAWN_DISABLED_TAB_STATE, RESPAWN_DISABLED_STATE, TAB_UP) self._stateMachine.addTransition( SPECTATOR_READY_STATES, SPECTATOR_STATE, ON_GO_TO_SPECTATOR, lambda *args, **kwargs: self._onSetSpectatorType(SPECTATOR_TYPE. CINEMATIC)) self._stateMachine.addTransition( SPECTATOR_READY_STATES, SPECTATOR_TACTICAL_STATE, ON_GO_TO_TACTICAL_SPECTATOR, lambda *args, **kwargs: self. _onSetSpectatorType(SPECTATOR_TYPE.TACTICAL)) self._stateMachine.addTransition( ALL_SPECTATOR_STATES, RESPAWN_STATE, ON_GO_BACK, lambda *args, ** kwargs: self._onSetSpectatorType(SPECTATOR_TYPE.NONE)) self._stateMachine.addTransition( ALL_SPECTATOR_STATES, RESPAWN_DISABLED_STATE, ON_GO_BACK_NO_RESPAWN, lambda *args, **kwargs: self. _onSetSpectatorType(SPECTATOR_TYPE.NONE)) self._stateMachine.addTransition(SPECTATOR_STATE, SPECTATOR_TAB_STATE, TAB_DOWN) self._stateMachine.addTransition(SPECTATOR_TAB_STATE, SPECTATOR_STATE, TAB_UP) self._stateMachine.addTransition(SPECTATOR_TACTICAL_STATE, SPECTATOR_TAB_TACTICAL_STATE, TAB_DOWN) self._stateMachine.addTransition(SPECTATOR_TAB_TACTICAL_STATE, SPECTATOR_TACTICAL_STATE, TAB_UP) self._stateMachine.addTransition( BATTLE_DEFAULT | BATTLE_STATS, DEATH_STATE, ON_DEATH, lambda *args, **kwargs: self._onDeath()) self._stateMachine.addTransition(DEATH_STATE | DEATH_TAB_STATE, RESPAWN_STATE, ON_WAITE_RESPAWN) self._stateMachine.addTransition( LOADING | LOADING_TAB, RESPAWN_STATE, ON_WAITE_RESPAWN, lambda *args, **kwargs: self._connectToSpectator()) self._stateMachine.addTransition( DEATH_STATE | DEATH_TAB_STATE, RESPAWN_DISABLED_STATE, ON_WAITE_DISABLED_RESPAWN, lambda *args, **kwargs: self._onRespawnDisabled()) self._stateMachine.addTransition( LOADING | LOADING_TAB, RESPAWN_DISABLED_STATE, ON_WAITE_DISABLED_RESPAWN, lambda *args, **kwargs: self._connectToSpectator()) self._stateMachine.addTransition(BATTLE_DEFAULT, BATTLE_STATS, TAB_DOWN) self._stateMachine.addTransition(BATTLE_STATS, BATTLE_DEFAULT, TAB_UP) self._stateMachine.addTransition( BATTLE_DEFAULT | BATTLE_STATS | RESPAWN_STATES | ALL_SPECTATOR_STATES | DEATH_STATE | DEATH_TAB_STATE, OUTRO, ON_OUTRO) self._stateMachine.addTransition(OUTRO, OUTRO_TAB, TAB_DOWN) self._stateMachine.addTransition(OUTRO_TAB, OUTRO, TAB_UP) self._stateMachine.addTransition(PROMO_STATE, BATTLE_DEFAULT, TOGGLE_PROMO) self._stateMachine.addTransition(ANY_STATE, PROMO_STATE, TOGGLE_PROMO) return def initSignals(self, features): self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._gameEnvironment = features.require(Feature.GAME_ENVIRONMENT) self._respawnModel = features.require(Feature.GAME_MODEL).respawn self._camera = features.require(Feature.CAMERA) self._clientArena = features.require(Feature.CLIENT_ARENA) inputProcessor = features.require(Feature.INPUT).commandProcessor sm = self._stateMachine inputProcessor.addListeners(InputMapping.CMD_VISIBILITY_HUD, None, None, self._onHUDVisibilityCommand) inputProcessor.addListeners( InputMapping.CMD_NEXT_VEHICLE_WHEN_DEAD, lambda: self._playerAvatar.switchObservee()) inputProcessor.addListeners(InputMapping.CMD_INTERMISSION_MENU, self._onIntermissionPress) inputProcessor.addListeners(InputMapping.CMD_SHOW_TEAMS, lambda: self._onTabPressed(True), lambda: self._onTabPressed(False)) inputProcessor.addListeners(InputMapping.CMD_HELP, lambda: self._onHelpPressed(True), lambda: self._onHelpPressed(False)) inputProcessor.addListeners( InputMapping.CMD_GO_TO_SPECTATOR, lambda: self._onGoToSpectatorCommand(ON_GO_TO_SPECTATOR)) inputProcessor.addListeners( InputMapping.CMD_GO_TO_TACTICAL_SPECTATOR, lambda: self._onGoToSpectatorCommand(ON_GO_TO_TACTICAL_SPECTATOR)) inputProcessor.addListeners(InputMapping.CMD_SKIP_DEATH, self._skipDeath) inputProcessor.addListeners(InputMapping.CMD_SKIP_OUTRO, self._skipOutro) self._gameEnvironment.eIntroFinished += self._onIntroFinish self._gameEnvironment.eLoadingFinished += self._eLoadingFinished self._gameEnvironment.ePreBattleFinished += self._ePreBattleFinished self._gameEnvironment.eLoadingDeathFinished += self._eLoadingDeathFinished self._gameEnvironment.eAllIntreClosed += self._eAllIntreClosed self._gameEnvironment.eTogglePromoHUD += self.onPromoHUDToggle self._playerAvatar.onStateChanged += self._onPlayerStateChanged self._playerAvatar.eTacticalRespawnEnd += self._onTacticalRespawnEnd self._playerAvatar.eUpdateSpectator += self._onObserveeChanged self._playerAvatar.ePlaneModelLoaded += self._onPlaneModelLoaded self._clientArena.onBeforePlaneChanged += self._onBeforePlayerPlaneChanged self._addPredicates(inputProcessor) self._addAdditionalManager(features) return def _onStateChanged(self, newStateId): self._interManager.validateState(newStateId) self._stateId = newStateId self._stateName = STATE_MAP[newStateId] self.eStateChanged(self._stateName) self._updateDenyCursorHide() self.checkMouseState() self._updateAdditionalManager() self._statesEffectsCtrl.onHUDStateChanged(newStateId) def _updateAdditionalManager(self): self._respManager.changeState(self._stateId) def _addAdditionalManager(self, features): self._respManager = RespawnSilentCheckManager( features, RESPAWN_SILENT_CHECK_STATES) self._respManager.eRestDelay += self._onRespDelay def _onRespDelay(self): self._onGoToSpectatorCommand(ON_GO_TO_SPECTATOR) def _updateDenyCursorHide(self): self._gameEnvironment.eOnDenyCursorHideChanged( self._cursorVisibility()) def _cursorVisibility(self): return self._interManager.isActive or self._stateId & MOUSE_VISIBILITY_STATES != 0 def _onSetSpectatorType(self, sType, *args, **kwargs): self._playerAvatar.activateTacticalSpectator(sType) self._camera.onTacticalSpectator( self._playerAvatar.spectatorTypeWithTacticalMode) def _onObserveeChanged(self, newObserveeID): LOG_DEBUG('_onObserveeChanged', newObserveeID) if BigWorld.player().isObserverToBattleTransition: return if newObserveeID == 0: self._stateMachine.signal(self._goBackSignalID) def _onObserveeLost(self): if self.isRespawnAvailable(): self._stateMachine.signal(self._goBackSignalID) else: self._stateMachine.signal(ON_GO_TO_SPECTATOR) def _onIntermissionActivityChanged(self, active): self._updateDenyCursorHide() def _onRespawnDisabled(self, *args, **kwargs): self._goBackSignalID = ON_GO_BACK_NO_RESPAWN def _onHUDVisibilityCommand(self, *args, **kwargs): LOG_DEBUG('HUD visibility command received') self.eToggleHUDVisibility() def _onIntermissionPress(self): chat = self._gameEnvironment.service('Chat') gamePlayHints = self._gameEnvironment.service('GamePlayHints') LOG_DEBUG('STATES TEST : _onIntermissionPress ', self._stateId) if gamePlayHints.hintVisible: HUDExecutionManager.call(GameplayHintsSource.onDisableStartHint) elif chat.chatVisible: chat.hideChat() elif self._stateId & SPECTATOR_STATES: self._stateMachine.signal(self._goBackSignalID) else: self._stateMachine.signal(TAB_UP) self._interManager.onIntermissionPress(self._stateId) def _onHelpPressed(self, pressed): LOG_DEBUG('STATES TEST : _onHelpPressed ', self._stateId) self._interManager.onHelpPress(pressed, self._stateId) def _onTabPressed(self, pressed): LOG_DEBUG('STATES TEST : _onTabPressed ', self._stateId) if not self._interManager.isActive: if pressed: self._stateMachine.signal(TAB_DOWN) else: self._stateMachine.signal(TAB_UP) def _onBeforePlayerPlaneChanged(self, avatarID): if BigWorld.player().id == avatarID: self._awaitLoadPlaneResources = True def _onPlaneModelLoaded(self): if self._awaitLoadPlaneResources and BigWorld.player( ).state & EntityStates.GAME: self._stateMachine.signal(ON_END_RESPAWN) self._awaitLoadPlaneResources = False def _goToBattle(self, *args, **kwargs): """Reset camera for player to avoid some issues related to reconnect """ self._camera.reset() self._requestShootingHint() def _onRespawn(self, *args, **kwargs): """Reset camera for player to avoid some issues related to reconnect """ self._requestShootingHint() def _onDeath(self, *args, **kwargs): """Close start hint if it was visible when player died """ gamePlayHints = self._gameEnvironment.service('GamePlayHints') gamePlayHints.setHintVisibility(False) def _showStartHint(self, *args, **kwargs): """Reset camera for player to avoid some issues related to reconnect """ gamePlayHints = self._gameEnvironment.service('GamePlayHints') if self._playerAvatar.startHintAvailable and not gamePlayHints.hintVisible: HUDExecutionManager.call(GameplayHintsSource.onShowHint, HINTS_TYPE.START) def _connectToSpectator(self, *args, **kwargs): self._playerAvatar.skipDeadFallState() self._camera.switchToSpectator() def _onGoToSpectatorCommand(self, signalID): if self._stateId & ALL_SPECTATOR_STATES: self._stateMachine.signal(self._goBackSignalID) else: if self._playerAvatar.observeeID == 0: self._playerAvatar.switchObservee() return self._stateMachine.signal(signalID) def _requestShootingHint(self): if self._playerAvatar.shootingHintAvailable and not self._playerAvatar.startHintAvailable: HUDExecutionManager.call(GameplayHintsSource.onShowHint, HINTS_TYPE.SHOOTING) def isRespawnAvailable(self): return self._respawnModel.respawnAmount.get() != 0 def goToCinemaSpectatorPredicate(self): res = self._stateId & CINEMA_SPECTATOR_READY_STATES return res def goToTacticalSpectatorPredicate(self): res = self._stateId & TACTICAL_SPECTATOR_READY_STATES return res def isChatAvailable(self): res = not self._stateId & SPECTATOR_STATES return res def _addPredicates(self, processor): processor.addPredicate(InputMapping.CMD_GO_TO_SPECTATOR, self.goToCinemaSpectatorPredicate) processor.addPredicate(InputMapping.CMD_GO_TO_TACTICAL_SPECTATOR, self.goToTacticalSpectatorPredicate) processor.addPredicate(InputMapping.CMD_GO_BACK, self.isRespawnAvailable) processor.addPredicate(InputMapping.CMD_CHAT, self.isChatAvailable) def _skipOutro(self): if self._stateName == STATE_MAP[OUTRO]: self._playerAvatar.exitGame() def _skipDeath(self): if self._stateName == STATE_MAP[ DEATH_STATE] or self._stateName == STATE_MAP[DEATH_TAB_STATE]: LOG_DEBUG(' STATES TEST : _skipDeath ') signalID = ON_WAITE_RESPAWN if self.isRespawnAvailable( ) else ON_WAITE_DISABLED_RESPAWN BigWorld.callback(0, lambda: self._stateMachine.signal(signalID)) def _eAllIntreClosed(self): LOG_DEBUG('STATES TEST : onAllIntreClosed ') self._interManager.onAllIntermissionClosed() self.checkMouseState() def checkMouseState(self): Cursor.forceShowCursor(self._cursorVisibility()) if self._stateId == BATTLE_DEFAULT and not self._interManager.isActive: self._playerAvatar.setFlyMouseInputAllowed(True) else: self._playerAvatar.setFlyMouseInputAllowed(False) def _onIntroFinish(self): LOG_DEBUG('STATES TEST : _onIntroFinish ') self._stateMachine.signal(INTRO_FINISHED) def _eLoadingFinished(self): LOG_DEBUG('STATES TEST : eLoadingFinished ') self._stateMachine.signal(HAS_CONTROL) def _ePreBattleFinished(self): LOG_DEBUG('STATES TEST : _ePreBattleFinished ') self._stateMachine.signal(ON_PRE_BATTLE_FINISH) def _eLoadingDeathFinished(self): LOG_DEBUG(' STATES TEST : _eLoadingDeathFinished ') self._endDeathState() def _onPlayerStateChanged(self, oldState, state): LOG_DEBUG(' STATES TEST : currentState : ', EntityStates.getStateName(state)) if state & (EntityStates.DESTROYED | EntityStates.DESTROYED_FALL): if oldState & EntityStates.GAME_CONTROLLED: LOG_DEBUG(' STATES TEST : ', 'DEAD') self._stateMachine.signal(ON_DEATH) self.___endDeathStateCallback = BigWorld.callback( 10, self._endDeathState) if state & EntityStates.GAME: LOG_DEBUG('STATES TEST : ', 'START GAME AFTER RESPAWN') if not self._awaitLoadPlaneResources: self._stateMachine.signal(ON_END_RESPAWN) if state & EntityStates.OUTRO: LOG_DEBUG(' STATES TEST : ', ' OUTRO ') self._stateMachine.signal(ON_OUTRO) def _onTacticalRespawnEnd(self, *args, **kwargs): LOG_DEBUG(' STATES TEST : _onTacticalRespawnEnd') def _endDeathState(self): if self._stateName == STATE_MAP[ DEATH_STATE] or self._stateName == STATE_MAP[ DEATH_TAB_STATE] or self._stateName == STATE_MAP[LOADING]: signalID = ON_WAITE_RESPAWN if self.isRespawnAvailable( ) else ON_WAITE_DISABLED_RESPAWN self._stateMachine.signal(signalID) def onPromoHUDToggle(self): self._stateMachine.signal(TOGGLE_PROMO) def dispose(self): if self.___endDeathStateCallback: BigWorld.cancelCallback(self.___endDeathStateCallback) self.___endDeathStateCallback = None self._statesEffectsCtrl.destroy() self._statesEffectsCtrl = None self._interManager.dispose() self._interManager = None self._respManager.eRestDelay -= self._onRespDelay self._respManager = None self._gameEnvironment.eIntroFinished -= self._onIntroFinish self._gameEnvironment.eLoadingFinished -= self._eLoadingFinished self._gameEnvironment.ePreBattleFinished -= self._ePreBattleFinished self._gameEnvironment.eLoadingDeathFinished -= self._eLoadingDeathFinished self._gameEnvironment.eAllIntreClosed -= self._eAllIntreClosed self._gameEnvironment.eTogglePromoHUD -= self.onPromoHUDToggle self._playerAvatar.onStateChanged -= self._onPlayerStateChanged self._playerAvatar.eTacticalRespawnEnd -= self._onTacticalRespawnEnd self._playerAvatar.eUpdateSpectator -= self._onObserveeChanged self._playerAvatar.ePlaneModelLoaded -= self._onPlaneModelLoaded self._clientArena.onBeforePlaneChanged -= self._onBeforePlayerPlaneChanged self._playerAvatar = None self._gameEnvironment = None self._respawnModel = None self._camera = None self.eStateChanged.clear() self._stateMachine.destroy() return
class ServerSettings(object): def __init__(self, serverSettings): self.onServerSettingsChange = Event() self.__serverSettings = serverSettings if serverSettings else {} if "roaming" in self.__serverSettings: roamingSettings = self.__serverSettings["roaming"] self.__roamingSettings = RoamingSettings( roamingSettings[0], roamingSettings[1], [_ServerInfo(*s) for s in roamingSettings[2]] ) else: self.__roamingSettings = RoamingSettings.defaults() if "file_server" in self.__serverSettings: self.__fileServerSettings = _FileServerSettings(self.__serverSettings["file_server"]) else: self.__fileServerSettings = _FileServerSettings.defaults() if "regional_settings" in self.__serverSettings: self.__regionalSettings = makeTupleByDict(_RegionalSettings, self.__serverSettings["regional_settings"]) else: self.__regionalSettings = _RegionalSettings.defaults() try: self.__eSportCurrentSeason = makeTupleByDict(_ESportCurrentSeason, self.__serverSettings) except TypeError: self.__eSportCurrentSeason = _ESportCurrentSeason.defaults() self.__updateClanProfile(self.__serverSettings) def update(self, serverSettingsDiff): self.__serverSettings.update(serverSettingsDiff) self.__updateClanProfile(serverSettingsDiff) self.onServerSettingsChange(serverSettingsDiff) def clear(self): self.onServerSettingsChange.clear() def getSettings(self): return self.__serverSettings @property def roaming(self): return self.__roamingSettings @property def fileServer(self): return self.__fileServerSettings @property def regionals(self): return self.__regionalSettings @property def eSportCurrentSeason(self): return self.__eSportCurrentSeason @property def clanProfile(self): return self.__clanProfile def isPotapovQuestEnabled(self): return self.__getGlobalSetting("isPotapovQuestEnabled", False) def isFortBattlesEnabled(self): return not self.__getGlobalSetting("isFortBattlesDisabled", True) def isClubsEnabled(self): return self.__getGlobalSetting("isClubsEnabled", False) def isGoldFishEnabled(self): return self.__getGlobalSetting("isGoldFishEnabled", False) def isTutorialEnabled(self): return self.__getGlobalSetting("isTutorialEnabled", IS_TUTORIAL_ENABLED) def isSandboxEnabled(self): return self.__getGlobalSetting("isSandboxEnabled", False) def isPromoAutoViewsEnabled(self): return True def getForbiddenFortDefenseHours(self): return self.__getGlobalSetting("forbiddenFortDefenseHours", tuple()) def getForbiddenSortieHours(self): return self.__getGlobalSetting("forbiddenSortieHours", tuple()) def getForbiddenSortiePeripheryIDs(self): return self.__getGlobalSetting("forbiddenSortiePeripheryIDs", tuple()) def getForbiddenRatedBattles(self): return self.__getGlobalSetting("forbiddenRatedBattles", {}) def isPremiumInPostBattleEnabled(self): return self.__getGlobalSetting("isPremiumInPostBattleEnabled", True) def __getGlobalSetting(self, settingsName, default=None): return self.__serverSettings.get(settingsName, default) def __updateClanProfile(self, targetSettings): if "clanProfile" in targetSettings: cProfile = targetSettings["clanProfile"] self.__clanProfile = _ClanProfile( cProfile.get("isEnabled", False), cProfile.get("gateUrl", ""), cProfile.get("type", "gateway") ) else: self.__clanProfile = _ClanProfile.defaults()
class ItemsCache(IItemsCache): def __init__(self): super(ItemsCache, self).__init__() goodies = GoodiesRequester() self.__items = ItemsRequester.ItemsRequester(InventoryRequester(), StatsRequester(), DossierRequester(), goodies, ShopRequester(goodies), RecycleBinRequester(), VehicleRotationRequester(), RankedRequester(), BattleRoyaleRequester(), BadgesRequester(), EpicMetaGameRequester(), TokensRequester(), dependency.instance(IFestivityFactory).getRequester(), BlueprintsRequester(), SessionStatsRequester(), AnonymizerRequester(), GiftSystemRequester()) self.__compatVehiclesCache = CompatVehiclesCache() self.__waitForSync = False self.__syncFailed = False self.onSyncStarted = Event() self.onSyncCompleted = Event() self.onSyncFailed = Event() def init(self): g_playerEvents.onInventoryResync += self.__pe_onInventoryResync g_playerEvents.onDossiersResync += self.__pe_onDossiersResync g_playerEvents.onStatsResync += self.__pe_onStatsResync g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected def fini(self): self.__items.fini() self.__compatVehiclesCache.clear() self.onSyncStarted.clear() self.onSyncCompleted.clear() self.onSyncFailed.clear() g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected g_playerEvents.onStatsResync -= self.__pe_onStatsResync g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync @property def waitForSync(self): return self.__waitForSync @property def items(self): return self.__items @property def compatVehiclesCache(self): return self.__compatVehiclesCache @async def update(self, updateReason, diff=None, notify=True, callback=None): if diff is None or self.__syncFailed: self.__invalidateFullData(updateReason, notify, callback) else: self.__invalidateData(updateReason, diff, notify, callback) return def clear(self): LOG_DEBUG('Clearing items cache.') self.__compatVehiclesCache.clear() return self.items.clear() def request(self, callback): raise SoftException('This method should not be reached in this context') def onDisconnected(self): self.items.onDisconnected() def _onResync(self, reason): if not self.__waitForSync: self.__invalidateFullData(reason) def _onCenterIsLongDisconnected(self, isLongDisconnected): self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected) def __invalidateData(self, updateReason, diff, notify=True, callback=lambda *args: None): self.__waitForSync = True wasSyncFailed = self.__syncFailed self.__syncFailed = False self.onSyncStarted() if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed: invalidItems = self.__items.invalidateCache(diff) else: invalidItems = {} def cbWrapper(*args): self.__waitForSync = False if not self.isSynced(): self.__syncFailed = True self.onSyncFailed(updateReason) else: self.__compatVehiclesCache.invalidateData(self, invalidItems) if notify: self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def __invalidateFullData(self, updateReason, notify=True, callback=lambda *args: None): self.__waitForSync = True wasSyncFailed = self.__syncFailed self.__syncFailed = False self.onSyncStarted() def cbWrapper(*args): self.__waitForSync = False if not self.isSynced(): self.__syncFailed = True self.onSyncFailed(updateReason) else: if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed: invalidItems = self.__items.invalidateCache() else: invalidItems = {} self.__compatVehiclesCache.invalidateFullData(self) if notify: self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def isSynced(self): return self.items.isSynced() def __pe_onStatsResync(self, *args): self._onResync(CACHE_SYNC_REASON.STATS_RESYNC) def __pe_onInventoryResync(self, *args): self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC) def __pe_onDossiersResync(self, *args): self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
class _QuestsCache(object): def __init__(self): self.__progress = QuestsProgress() self.__waitForSync = False self.__invalidateCbID = None self.onSyncStarted = Event() self.onSyncCompleted = Event() return def init(self): pass def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() self.__clearInvalidateCallback() @property def waitForSync(self): return self.__waitForSync @property def progress(self): return self.__progress @async def update(self, callback = None): self.__invalidateData(callback) @classmethod def makeQuestsGroups(cls, quests): tasks = [] groups = defaultdict(lambda : []) for qID, q in quests.iteritems(): if q.getGroupID() is None: tasks.append(q) elif q.isStrategic(): tasks.append(q) groups[q.getGroupID()].insert(0, q) else: groups[q.getGroupID()].append(q) return (tasks, groups) def getQuests(self, filterFunc = None): quests = self.__getQuestsData() filterFunc = filterFunc or (lambda a: True) result = {} for qID, qData in quests.iteritems(): q = Quest(qID, qData, self.__progress.getQuestProgress(qID)) if q.getDestroyingTimeLeft() <= 0: continue if not filterFunc(q): continue result[qID] = q _, groups = self.makeQuestsGroups(result) for q in result.itervalues(): if q.isSubtask() or q.isStrategic(): q.setGroup(groups[q.getGroupID()]) return result def getCurrentQuests(self): return self.getQuests(lambda q: q.getStartTimeLeft() <= 0 and q.getFinishTimeLeft() > 0) def getFutureQuests(self): return self.getQuests(lambda q: q.getStartTimeLeft() > 0) def _onResync(self, *args): self.__invalidateData() @classmethod def __getQuestGroupID(cls, qData): return qData.get('groupID') or None @classmethod def __getQuestSeqID(cls, qData): return qData.get('seqID', -1) def __invalidateData(self, callback = lambda *args: None): def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted() callback(*args) self.__clearInvalidateCallback() self.__waitForSync = True self.onSyncStarted() self.__progress.request()(cbWrapper) minFinishTimeLeft = sys.maxint for q in self.getCurrentQuests().itervalues(): minFinishTimeLeft = min(minFinishTimeLeft, q.getFinishTimeLeft()) for q in self.getFutureQuests().itervalues(): minFinishTimeLeft = min(minFinishTimeLeft, q.getStartTimeLeft()) if minFinishTimeLeft != sys.maxint: self.__loadInvalidateCallback(minFinishTimeLeft) from gui.shared import g_eventBus g_eventBus.handleEvent(events.LobbySimpleEvent(events.LobbySimpleEvent.QUESTS_UPDATED)) def __getQuestsData(self): try: if isPlayerAccount(): if 'questsClientData' in BigWorld.player().eventsData: return pickle.loads(zlib.decompress(BigWorld.player().eventsData['questsClientData'])) return {} LOG_ERROR('Trying to get quests data from not account player', BigWorld.player()) except Exception: LOG_CURRENT_EXCEPTION() return {} def __loadInvalidateCallback(self, duration): LOG_DEBUG('load quest window invalidation callback (secs)', duration) self.__clearInvalidateCallback() self.__invalidateCbID = BigWorld.callback(math.ceil(duration), self.__invalidateData) def __clearInvalidateCallback(self): if self.__invalidateCbID is not None: BigWorld.cancelCallback(self.__invalidateCbID) self.__invalidateCbID = None return
class CustomizationCamera(object): def __init__(self): self.__cfg = getHangarSpaceConfig() self.__camSens = self.__cfg['cam_sens'] self.__pitchConstraints = self.__cfg['cam_pitch_constr'] self.__distConstraints = self.__cfg['cam_dist_constr'] self.__yawCameraFilter = HangarCameraYawFilter( math.radians(self.__cfg['cam_yaw_constr'][0]), math.radians(self.__cfg['cam_yaw_constr'][1]), self.__camSens) self.__cam = None self.__prevCam = None self.__prevVerticalFov = None self.__nativeVerticalFov = None self.__currentVerticalFov = None self.__isActive = False self.__scrollEvent = Event() return def init(self): self.__cam = BigWorld.CursorCamera() self.__cam.pivotMaxDist = 0 self.__cam.pivotMinDist = 0 self.__cam.turningHalfLife = self.__cam.maxDistHalfLife = self.__cfg[ 'cam_fluency'] self.__cam.movementHalfLife = 0.0 self.__cam.pivotPosition = Math.Vector3() self.__cam.source = Math.Matrix() self.__cam.target = Math.Matrix() self.__cam.wg_applyParams() def destroy(self): self.deactivate() self.__cam = None self.__cfg = None self.__camSens = None self.__pitchConstraints = None self.__distConstraints = None self.__yawCameraFilter = None self.__scrollEvent.clear() return def activate(self, targetPos, cameraParams): if self.__isActive: return self.__prevCam = BigWorld.camera() self.__prevVerticalFov = BigWorld.projection().fov self.__cam.spaceID = self.__prevCam.spaceID self.__yawCameraFilter = HangarCameraYawFilter( math.radians(cameraParams.yawConstraints[0]), math.radians(cameraParams.yawConstraints[1]), self.__camSens) self.__pitchConstraints = cameraParams.pitchConstraints self.__distConstraints = cameraParams.distanceConstraints pivotY, pivotMaxDist, initYaw, initPitch = self.__calculateCursorCameraParams( targetPos, cameraParams) self.__cam.target.setTranslate(targetPos) self.__cam.pivotPosition = Math.Vector3(0.0, pivotY, 0.0) self.__cam.pivotMaxDist = pivotMaxDist sourceMat = Math.Matrix() sourceMat.setRotateYPR(Math.Vector3(initYaw, initPitch, 0.0)) self.__cam.source = sourceMat self.__cam.wg_applyParams() BigWorld.camera(self.__cam) horizontalFov = math.radians(cameraParams.fov) self.__setHorizontalFov(horizontalFov) self.__currentVerticalFov = self.__nativeVerticalFov = BigWorld.projection( ).fov FovExtended.instance().onSetFovSettingEvent += self.__onSetFovSetting FovExtended.instance().onRefreshFovEvent += self.__onRefreshFov self.__isActive = True def deactivate(self): if not self.__isActive: return else: self.__isActive = False FovExtended.instance( ).onSetFovSettingEvent -= self.__onSetFovSetting FovExtended.instance().onRefreshFovEvent -= self.__onRefreshFov if self.__prevCam is not None: if self.__prevCam.spaceID != BigWorld.camera().spaceID: return BigWorld.camera(self.__prevCam) self.__prevCam = None self.__restorePreviousFov() return def addScrollListener(self, listener): self.__scrollEvent += listener def removeScrollListener(self, listener): self.__scrollEvent -= listener def handleMouseEvent(self, dx, dy, dz): if self.__isActive: self.__processMouseEvent(dx, dy, dz) def __processMouseEvent(self, dx, dy, dz): sourceMat = Math.Matrix(self.__cam.source) yaw = sourceMat.yaw pitch = sourceMat.pitch dist = self.__cam.pivotMaxDist currentMatrix = Math.Matrix(self.__cam.invViewMatrix) currentYaw = currentMatrix.yaw yaw = self.__yawCameraFilter.getNextYaw(currentYaw, yaw, dx) prevDist = dist pitch -= dy * self.__camSens dist -= dz * self.__camSens pitch = mathUtils.clamp(math.radians(self.__pitchConstraints[0]), math.radians(self.__pitchConstraints[1]), pitch) dist = mathUtils.clamp(self.__distConstraints[0], self.__distConstraints[1], dist) mat = Math.Matrix() mat.setRotateYPR(Math.Vector3(yaw, pitch, 0.0)) self.__cam.source = mat self.__cam.pivotMaxDist = dist deltaDist = math.fabs(dist - prevDist) if dz != 0 and deltaDist > 0.01: self.__scrollEvent() @staticmethod def __calculateCursorCameraParams(targetPos, cameraParams): initMatrix = Math.Matrix(cameraParams.initMatrix) initDirection = initMatrix.applyToAxis(2) startPoint = initMatrix.translation xPlanePoint = startPoint + initMatrix.applyToAxis(0) zPlanePoint = startPoint + initDirection camHorizontalPlane = Math.Plane() camHorizontalPlane.init(startPoint, xPlanePoint, zPlanePoint) intersectedPoint = camHorizontalPlane.intersectRay( targetPos, Math.Vector3(0.0, 1.0, 0.0)) correctedCamDirection = intersectedPoint - startPoint pivotVec = intersectedPoint - targetPos pivotY = pivotVec.y yawCorrection = correctedCamDirection.yaw - initDirection.yaw yawCorrectionMatrix = Math.Matrix() yawCorrectionMatrix.setRotateYPR(Math.Vector3(yawCorrection, 0.0, 0.0)) initMatrix.postMultiply(yawCorrectionMatrix) return (pivotY, correctedCamDirection.length, initMatrix.yaw, -initMatrix.pitch) @staticmethod def __setHorizontalFov(horizontalFov): FovExtended.instance().setFovByAbsoluteValue(horizontalFov) def __onSetFovSetting(self): self.__prevVerticalFov = BigWorld.projection().fov BigWorld.projection().fov = self.__currentVerticalFov def __onRefreshFov(self): self.__currentVerticalFov = BigWorld.projection().fov def __restorePreviousFov(self): if self.__prevVerticalFov is None: return else: if math.fabs(self.__currentVerticalFov - self.__nativeVerticalFov) > 1e-06: FovExtended.instance().resetFov() else: BigWorld.projection().fov = self.__prevVerticalFov self.__prevVerticalFov = None self.__currentVerticalFov = None self.__nativeVerticalFov = None return
class CustomizationItemCMHandler(AbstractContextMenuHandler): itemsCache = dependency.descriptor(IItemsCache) service = dependency.descriptor(ICustomizationService) def __init__(self, cmProxy, ctx=None): self._intCD = 0 super(CustomizationItemCMHandler, self).__init__( cmProxy, ctx, { CustomizationOptions.BUY: 'buyItem', CustomizationOptions.SELL: 'sellItem', CustomizationOptions.REMOVE_FROM_TANK: 'removeItemFromTank' }) self.onSelected = Event(self._eManager) self._item = self.itemsCache.items.getItemByCD(self._intCD) self._c11nView = self.app.containerManager.getContainer( ViewTypes.LOBBY_SUB).getView() def fini(self): self.onSelected.clear() self.onSelected = None super(CustomizationItemCMHandler, self).fini() return def buyItem(self): self.onSelected(CustomizationOptions.BUY, self._intCD) def sellItem(self): self.onSelected(CustomizationOptions.SELL, self._intCD) def removeItemFromTank(self): self.onSelected(CustomizationOptions.REMOVE_FROM_TANK, self._intCD) def _generateOptions(self, ctx=None): item = self.itemsCache.items.getItemByCD(self._intCD) buyPriceVO = getItemPricesVO(item.getBuyPrice()) sellPriceVO = getItemPricesVO(item.getSellPrice()) inventoryCount = self._c11nView.getItemInventoryCount(item) availableForSale = inventoryCount > 0 and item.getSellPrice( ) != ITEM_PRICE_EMPTY and not item.isRentable and not item.isHidden style = self._c11nView.getModifiedStyle() removeFromTankEnabled = style.intCD == item.intCD if style is not None else False for outfit in (self._c11nView.getModifiedOutfit(season) for season in SeasonType.COMMON_SEASONS): if outfit.has(item): removeFromTankEnabled = True break accountMoney = self.itemsCache.items.stats.money availableForPurchase = not item.isHidden and not item.getBuyPrice( ) == ITEM_PRICE_EMPTY and item.getBuyPrice().price <= accountMoney showAlert = len(sellPriceVO[0]) > 1 tooltipVO = None if showAlert: tooltipVO = packActionTooltipData( ACTION_TOOLTIPS_TYPE.ITEM, str(item.intCD), False, item.sellPrices.getSum().price, item.sellPrices.getSum().defPrice) price = sellPriceVO[0]['price'] sellPriceVO[0] = {} sellPriceVO[0]['price'] = price return [ self._makeItem( CustomizationOptions.BUY, MENU.cst_item_ctx_menu(CustomizationOptions.BUY), { 'data': { 'price': first(buyPriceVO) } if availableForPurchase else None, 'enabled': availableForPurchase }, None, 'CurrencyContextMenuItem'), self._makeSeparator(), self._makeItem( CustomizationOptions.SELL, MENU.cst_item_ctx_menu(CustomizationOptions.SELL), { 'data': { 'price': first(sellPriceVO) } if availableForSale else None, 'enabled': availableForSale, 'showAlert': showAlert, 'tooltipVO': tooltipVO }, None, 'CurrencyContextMenuItem'), self._makeSeparator(), self._makeItem( CustomizationOptions.REMOVE_FROM_TANK, MENU.cst_item_ctx_menu(CustomizationOptions.REMOVE_FROM_TANK), {'enabled': removeFromTankEnabled}) ] def _initFlashValues(self, ctx): self._intCD = ctx.itemID
class _ItemsCache(object): def __init__(self): self.__items = ItemsRequester() self.__waitForSync = False self.onSyncStarted = Event() self.onSyncCompleted = Event() def init(self): g_playerEvents.onInventoryResync += self.__pe_onInventoryResync g_playerEvents.onDossiersResync += self.__pe_onDossiersResync g_playerEvents.onStatsResync += self.__pe_onStatsResync g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected g_playerEvents.onStatsResync -= self.__pe_onStatsResync g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync @property def waitForSync(self): return self.__waitForSync @property def items(self): return self.__items @async def update(self, updateReason, diff=None, callback=None): if diff is None: self.__invalidateFullData(updateReason, callback) else: self.__invalidateData(updateReason, diff, callback) def clear(self): LOG_DEBUG('Clearing items cache.') return self.items.clear() def _onResync(self, reason): if not self.__waitForSync: self.__invalidateFullData(reason) def _onCenterIsLongDisconnected(self, isLongDisconnected): self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected) def __invalidateData(self, updateReason, diff, callback=lambda *args: None): self.__waitForSync = True self.onSyncStarted() if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC: invalidItems = self.__items.invalidateCache(diff) else: invalidItems = {} def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def __invalidateFullData(self, updateReason, callback=lambda *args: None): self.__waitForSync = True self.onSyncStarted() def cbWrapper(*args): self.__waitForSync = False if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC: invalidItems = self.__items.invalidateCache() else: invalidItems = {} self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def isSynced(self): return self.items.isSynced() def __pe_onStatsResync(self, *args): self._onResync(CACHE_SYNC_REASON.STATS_RESYNC) def __pe_onInventoryResync(self, *args): self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC) def __pe_onDossiersResync(self, *args): self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
class ServerSettings(object): def __init__(self, serverSettings): self.onServerSettingsChange = Event() self.set(serverSettings) def set(self, serverSettings): self.__serverSettings = copy.deepcopy( serverSettings) if serverSettings else {} if 'roaming' in self.__serverSettings: roamingSettings = self.__serverSettings['roaming'] self.__roamingSettings = RoamingSettings( roamingSettings[0], roamingSettings[1], [_ServerInfo(*s) for s in roamingSettings[2]]) else: self.__roamingSettings = RoamingSettings.defaults() if 'file_server' in self.__serverSettings: self.__fileServerSettings = _FileServerSettings( self.__serverSettings['file_server']) else: self.__fileServerSettings = _FileServerSettings.defaults() if 'regional_settings' in self.__serverSettings: self.__regionalSettings = makeTupleByDict( _RegionalSettings, self.__serverSettings['regional_settings']) else: self.__regionalSettings = _RegionalSettings.defaults() try: self.__eSportCurrentSeason = makeTupleByDict( _ESportCurrentSeason, self.__serverSettings) except TypeError: self.__eSportCurrentSeason = _ESportCurrentSeason.defaults() if 'wgcg' in self.__serverSettings: self.__updateWgcg(self.__serverSettings) else: self.__wgcg = _Wgcg.defaults() if 'clanProfile' in self.__serverSettings: self.__updateClanProfile(self.__serverSettings) else: self.__clanProfile = _ClanProfile.defaults() if 'spgRedesignFeatures' in self.__serverSettings: self.__spgRedesignFeatures = makeTupleByDict( _SpgRedesignFeatures, self.__serverSettings['spgRedesignFeatures']) else: self.__spgRedesignFeatures = _SpgRedesignFeatures.defaults() if 'strongholdSettings' in self.__serverSettings: settings = self.__serverSettings['strongholdSettings'] self.__strongholdSettings = _StrongholdSettings( settings.get('wgshHostUrl', '')) else: self.__strongholdSettings = _StrongholdSettings.defaults() if 'frontlineSettings' in self.__serverSettings: settings = self.__serverSettings['frontlineSettings'] self.__frontlineSettings = _FrontlineSettings( settings.get('flHostUrl', '')) else: self.__frontlineSettings = _FrontlineSettings.defaults() if 'rankedBattles' in self.__serverSettings: self.__bwRankedBattles = makeTupleByDict( _BwRankedBattles, self.__serverSettings['rankedBattles']) else: self.__bwRankedBattles = _BwRankedBattles.defaults() if 'hallOfFame' in self.__serverSettings: self.__bwHallOfFame = makeTupleByDict( _BwHallOfFame, self.__serverSettings['hallOfFame']) else: self.__bwHallOfFame = _BwHallOfFame.defaults() if 'ranked_config' in self.__serverSettings: self.__rankedBattlesSettings = makeTupleByDict( _RankedBattlesConfig, self.__serverSettings['ranked_config']) else: self.__rankedBattlesSettings = _RankedBattlesConfig.defaults() if 'wgm_offline_emergency_config' in self.__serverSettings: self.__wgmOfflineEmergencyConfig = makeTupleByDict( _WGMoneyOfflineEmergencyConfig, self.__serverSettings['wgm_offline_emergency_config']) else: self.__wgmOfflineEmergencyConfig = _WGMoneyOfflineEmergencyConfig.defaults( ) if 'epic_config' in self.__serverSettings: LOG_DEBUG('epic_config', self.__serverSettings['epic_config']) self.__epicMetaGameSettings = makeTupleByDict( _EpicMetaGameConfig, self.__serverSettings['epic_config']['epicMetaGame']) self.__epicGameSettings = makeTupleByDict( _EpicGameConfig, self.__serverSettings['epic_config']) else: self.__epicMetaGameSettings = _EpicMetaGameConfig() self.__epicGameSettings = _EpicGameConfig() if 'telecom_config' in self.__serverSettings: self.__telecomConfig = _TelecomConfig( self.__serverSettings['telecom_config']) else: self.__telecomConfig = _TelecomConfig.defaults() self.onServerSettingsChange(serverSettings) def update(self, serverSettingsDiff): self.__serverSettings = updateDict(self.__serverSettings, serverSettingsDiff) if 'clanProfile' in serverSettingsDiff: self.__updateClanProfile(serverSettingsDiff) if 'spgRedesignFeatures' in self.__serverSettings: self.__spgRedesignFeatures = makeTupleByDict( _SpgRedesignFeatures, self.__serverSettings['spgRedesignFeatures']) if 'ranked_config' in serverSettingsDiff: self.__updateRanked(serverSettingsDiff) if 'hallOfFame' in serverSettingsDiff: self.__bwHallOfFame = makeTupleByDict( _BwHallOfFame, serverSettingsDiff['hallOfFame']) if 'wgcg' in serverSettingsDiff: self.__updateWgcg(serverSettingsDiff) if 'wgm_offline_emergency_config' in serverSettingsDiff: self.__wgmOfflineEmergencyConfig = makeTupleByDict( _WGMoneyOfflineEmergencyConfig, serverSettingsDiff['wgm_offline_emergency_config']) if 'epic_config' in serverSettingsDiff: self.__updateEpic(serverSettingsDiff) if 'telecom_config' in serverSettingsDiff: self.__telecomConfig = _TelecomConfig( self.__serverSettings['telecom_config']) self.onServerSettingsChange(serverSettingsDiff) def clear(self): self.onServerSettingsChange.clear() def getSettings(self): return self.__serverSettings @property def roaming(self): return self.__roamingSettings @property def fileServer(self): return self.__fileServerSettings @property def regionals(self): return self.__regionalSettings @property def eSportCurrentSeason(self): return self.__eSportCurrentSeason @property def clanProfile(self): return self.__clanProfile @property def wgcg(self): return self.__wgcg @property def spgRedesignFeatures(self): return self.__spgRedesignFeatures @property def stronghold(self): return self.__strongholdSettings @property def frontline(self): return self.__frontlineSettings @property def bwRankedBattles(self): return self.__bwRankedBattles @property def bwHallOfFame(self): return self.__bwHallOfFame @property def rankedBattles(self): return self.__rankedBattlesSettings @property def wgmOfflineEmergency(self): return self.__wgmOfflineEmergencyConfig @property def epicMetaGame(self): return self.__epicMetaGameSettings @property def epicBattles(self): return self.__epicGameSettings @property def telecomConfig(self): return self.__telecomConfig def isEpicBattleEnabled(self): return self.epicBattles.enabled > 0 def isPersonalMissionsEnabled(self): return self.isRegularQuestEnabled() def isRegularQuestEnabled(self): return self.__getGlobalSetting('isRegularQuestEnabled', True) def isStrongholdsEnabled(self): return self.__getGlobalSetting('strongholdSettings', {}).get('isStrongholdsEnabled', False) def isLeaguesEnabled(self): return self.__getGlobalSetting('strongholdSettings', {}).get('isLeaguesEnabled', False) def isElenEnabled(self): return self.__getGlobalSetting('elenSettings', {}).get('isElenEnabled', True) def elenUpdateInterval(self): return self.__getGlobalSetting('elenSettings', {}).get('elenUpdateInterval', 60) def isGoldFishEnabled(self): return self.__getGlobalSetting('isGoldFishEnabled', False) def isTutorialEnabled(self): return self.__getGlobalSetting('isTutorialEnabled', IS_TUTORIAL_ENABLED) def isSandboxEnabled(self): return self.__getGlobalSetting('isSandboxEnabled', False) def isBootcampEnabled(self): return self.__getGlobalSetting('isBootcampEnabled', False) def isEpicRandomEnabled(self): return self.__getGlobalSetting('isEpicRandomEnabled', False) def isEpicRandomAchievementsEnabled(self): return self.__getGlobalSetting('isEpicRandomAchievementsEnabled', False) def isEpicRandomMarkOfMasteryEnabled(self): return self.__getGlobalSetting('isEpicRandomMarkOfMasteryEnabled', False) def isEpicRandomMarksOnGunEnabled(self): return self.__getGlobalSetting('isEpicRandomMarksOnGunEnabled', False) def isPromoAutoViewsEnabled(self): if self.isBootcampEnabled(): from bootcamp.Bootcamp import g_bootcamp if g_bootcamp.isRunning(): return False return True def isHofEnabled(self): return self.__getGlobalSetting('hallOfFame', {}).get('isHofEnabled', False) def getMaxSPGinSquads(self): return self.__getGlobalSetting('maxSPGinSquads', 0) def getRandomMapsForDemonstrator(self): return self.__getGlobalSetting('randomMapsForDemonstrator', {}) def isPremiumInPostBattleEnabled(self): return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True) def isVehicleComparingEnabled(self): return bool(self.__getGlobalSetting('isVehiclesCompareEnabled', True)) def isEncyclopediaEnabled(self, tokensCount): switchState = self.__getGlobalSetting('isEncyclopediaEnabled') if switchState == SWITCH_STATE.ALL: state = True elif switchState == SWITCH_STATE.NONE: state = False elif switchState == SWITCH_STATE.TOKEN: state = tokensCount > 0 else: LOG_ERROR( 'Wrong activation state for encyclopedia. Encyclopedia is considered to be disabled' ) state = False return state def isTankmanRestoreEnabled(self): return self.__getGlobalSetting('isTankmanRestoreEnabled', True) def isVehicleRestoreEnabled(self): return self.__getGlobalSetting('isVehicleRestoreEnabled', True) def isCustomizationEnabled(self): return self.__getGlobalSetting('isCustomizationEnabled', True) def getHeroVehicles(self): return self.__getGlobalSetting('hero_vehicles', {}) def __getGlobalSetting(self, settingsName, default=None): return self.__serverSettings.get(settingsName, default) def __updateClanProfile(self, targetSettings): cProfile = targetSettings['clanProfile'] self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False)) def __updateWgcg(self, targetSettings): cProfile = targetSettings['wgcg'] self.__wgcg = _Wgcg(cProfile.get('isEnabled', False), cProfile.get('gateUrl', ''), cProfile.get('type', 'gateway'), cProfile.get('loginOnStart', False)) def __updateRanked(self, targetSettings): self.__rankedBattlesSettings = self.__rankedBattlesSettings.replace( targetSettings['ranked_config']) def __updateEpic(self, targetSettings): self.__epicMetaGameSettings = self.__epicMetaGameSettings.replace( targetSettings['epic_config']) self.__epicGameSettings = self.__epicGameSettings.replace( targetSettings['epic_config'])
class DetailedEngineState(assembly_utility.Component): rpm = property(lambda self: self._rpm) gearNum = property(lambda self: self._gearNum) gearUp = property(lambda self: self._gearUp) mode = property(lambda self: self._mode) starting = property(lambda self: self.__starting) physicLoad = property(lambda self: self._physicLoad) relativeSpeed = property(lambda self: self._relativeSpeed) engineLoad = property(lambda self: self._engineLoad) roughnessValue = property(lambda self: self._roughnessValue) relativeRPM = property(lambda self: self._reativelRPM) _STOPPED = 0 _IDLE = 1 _MEDIUM = 2 _HIGH = 3 def __init__(self): self._rpm = 0.0 self._reativelRPM = 0.0 self._gearNum = 0 self._mode = DetailedEngineState._STOPPED self.__starting = False self._gearUp = False self._physicLoad = 0.0 self._relativeSpeed = 0.0 self._maxClimbAngle = math.radians(20.0) self._engineLoad = self._STOPPED self._vehicle = None self._gearUpCbk = None self.__startEngineCbk = None self.__prevArenaPeriod = BigWorld.player().arena.period self.onEngineStart = Event() if self.__prevArenaPeriod == ARENA_PERIOD.BATTLE or self.__prevArenaPeriod == ARENA_PERIOD.PREBATTLE: self.__startEngineCbk = BigWorld.callback(0.1, self.__startEngineFunc) BigWorld.player().arena.onPeriodChange += self.__arenaPeriodChanged return def destroy(self): BigWorld.player().arena.onPeriodChange -= self.__arenaPeriodChanged if self.__startEngineCbk is not None: BigWorld.cancelCallback(self.__startEngineCbk) self._vehicle = None self._gearUpCbk = None self.onEngineStart.clear() self.onEngineStart = None return def __arenaPeriodChanged(self, *args): period = BigWorld.player().arena.period if period != self.__prevArenaPeriod and period == ARENA_PERIOD.PREBATTLE: self._mode = DetailedEngineState._STOPPED self.__prevArenaPeriod = period maxTime = BigWorld.player().arena.periodEndTime - BigWorld.serverTime() maxTime = maxTime * 0.7 if maxTime > 0.0 else 1.0 time = uniform(0.0, maxTime) self.__startEngineCbk = BigWorld.callback(time, self.__startEngineFunc) elif period == ARENA_PERIOD.BATTLE: if self.__startEngineCbk is None and self._mode == DetailedEngineState._STOPPED: self.onEngineStart() self.__starting = False return def __startEngineFunc(self): self.__startEngineCbk = None self.__starting = True self._mode = DetailedEngineState._IDLE self.onEngineStart() return def setMode(self, mode): if mode > DetailedEngineState._STOPPED: if self._mode == DetailedEngineState._STOPPED: self.__starting = True else: self.__starting = False else: self.__starting = False self._mode = mode def start(self, vehicle): self._vehicle = vehicle self._maxClimbAngle = math.acos(self._vehicle.typeDescriptor.physics['minPlaneNormalY']) def refresh(self, delta): vehicleTypeDescriptor = self._vehicle.typeDescriptor vehicleSpeed = self._vehicle.speedInfo.value[0] if vehicleSpeed > 0.0: self._relativeSpeed = vehicleSpeed / vehicleTypeDescriptor.physics['speedLimits'][0] else: self._relativeSpeed = vehicleSpeed / vehicleTypeDescriptor.physics['speedLimits'][1] def setGearUpCallback(self, gearUpCbk): self._gearUpCbk = gearUpCbk def delGearUpCallback(self): self._gearUpCbk = None return
class _CurrentVehicle(): def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.__historicalBattle = None self.onChanged = Event() self.onChangeStarted = Event() return def init(self): g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate, 'cache.vehsLock': self.onLocksUpdate}) game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged game_control.g_instance.rentals.onRentChangeNotify += self.onRentChange prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged game_control.g_instance.rentals.onRentChangeNotify -= self.onRentChange g_hangarSpace.removeVehicle() self.selectNoVehicle() def onIgrTypeChanged(self, *args): if self.isPremiumIGR(): self.onChanged() self.refreshModel() def onRentChange(self, vehicles): if self.isPresent(): if self.item.intCD in vehicles: self.onChanged() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']: isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() else: isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff['repair'] isCustomizationChanged = 'igrCustomizationLayout' in vehsDiff and self.__vehInvID in vehsDiff['igrCustomizationLayout'] isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive or (self.__vehInvID, '_r') in hive, vehsDiff.itervalues())) > 0 if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged: self.refreshModel() if isVehicleChanged or isRepaired: self.onChanged() return def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: if self.__historicalBattle is not None: historical = g_tankActiveCamouflage['historical'] if self.__historicalBattle.canParticipateWith(self.item.intCD) and self.item.intCD not in historical: historical[self.item.intCD] = self.__historicalBattle.getArenaType().vehicleCamouflageKind if self.item.intCD not in g_tankActiveCamouflage: availableKinds = [] currKind = 0 for id, startTime, days in self.item.descriptor.camouflages: if id is not None: availableKinds.append(currKind) currKind += 1 if len(availableKinds) > 0: g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds) g_hangarSpace.updateVehicle(self.item, self.__historicalBattle) else: g_hangarSpace.removeVehicle() return @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isDisabledInRent(self): return self.isPresent() and self.item.rentalIsOver and self.item.isRented def isDisabledInPremIGR(self): return self.isPresent() and self.item.isDisabledInPremIGR def isPremiumIGR(self): return self.isPresent() and self.item.isPremiumIGR def isInPrebattle(self): return self.isPresent() and self.item.isInPrebattle def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): if self.isPresent() and self.item.isAutoLoad: for shell in self.item.shells: if shell.count != shell.defaultCount: return False return True def isAutoEquipFull(self): if self.isPresent() and self.item.isAutoEquip: for i, e in enumerate(self.item.eqsLayout): if e != self.item.eqs[i]: return False return True def selectVehicle(self, vehInvID = 0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) return def selectNoVehicle(self): self.__selectVehicle(0) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() if state == Vehicle.VEHICLE_STATE.IN_PREMIUM_IGR_ONLY: localization = '#menu:vehicle/igrRentLeft/%s' rentLeftStr = getRentLeftTimeStr(localization, self.item.rentLeftTime) icon = TextManager.getIcon(TextIcons.PREMIUM_IGR_BIG) if self.item.isRented: message = i18n.makeString('#menu:currentVehicleStatus/' + state, icon=icon, time=rentLeftStr) else: message = i18n.makeString('#menu:tankCarousel/vehicleStates/inPremiumIgrOnly', icon=icon) return (state, message, stateLvl) return (state, '#menu:currentVehicleStatus/' + state, stateLvl) return ('notpresent', MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL) def setHistoricalBattle(self, historicalBattle): g_tankActiveCamouflage['historical'] = {} self.__historicalBattle = historicalBattle self.refreshModel() self.onChanged() def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show('updateCurrentVehicle', isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide('updateCurrentVehicle') def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None return def __checkPrebattleLockedVehicle(self): clientPrb = prb_control.getClientPrebattle() if clientPrb is not None: rosters = prb_control.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '') if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __repr__(self): return 'CurrentVehicle(%s)' % str(self.item)
class _ClanCache(object): def __init__(self): self.__waitForSync = False self.__fortProvider = ClientFortProvider() self.__clanMembersLen = None self.__clanMotto = '' self.__clanDescription = '' self.onSyncStarted = Event() self.onSyncCompleted = Event() return def init(self): pass def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() def onAccountShowGUI(self): self.__startFortProvider() def onAvatarBecomePlayer(self): self.__stopFortProvider() def onDisconnected(self): self.__stopFortProvider() @property def waitForSync(self): return self.__waitForSync @async def update(self, diff = None, callback = None): self.__invalidateData(diff, callback) def clear(self): pass @storage_getter('users') def usersStorage(self): return None @property def fortProvider(self): return self.__fortProvider @property def clanDBID(self): from gui.shared import g_itemsCache return g_itemsCache.items.stats.clanDBID @property def isInClan(self): """ @return: is current player in clan """ return self.clanDBID is not None and self.clanDBID != 0 @property def clanMembers(self): members = set() if self.isInClan: members = set(self.usersStorage.getClanMembersIterator(False)) return members @property def clanInfo(self): from gui.shared import g_itemsCache info = g_itemsCache.items.stats.clanInfo if info and len(info) > 1: return info else: return (None, None, -1, 0, 0) @property def clanName(self): return passCensor(html.escape(self.clanInfo[0])) @property def clanAbbrev(self): return self.clanInfo[1] @property def clanMotto(self): return self.__clanMotto @property def clanDescription(self): return self.__clanDescription @property def clanTag(self): result = self.clanAbbrev if result: return '[%s]' % result return result @property def clanCommanderName(self): for member in self.clanMembers: if member.getClanRole() == CLAN_MEMBER_FLAGS.LEADER: return member.getName() return None @property def clanRole(self): user = self.usersStorage.getUser(getAccountDatabaseID()) if user: role = user.getClanRole() else: role = 0 return role @property def isClanLeader(self): return self.clanRole == CLAN_MEMBER_FLAGS.LEADER @async @process def getClanEmblemID(self, callback): clanEmblem = None if self.isInClan: tID = 'clanInfo' + BigWorld.player().name clanEmblem = yield self.getClanEmblemTextureID(self.clanDBID, False, tID) callback(clanEmblem) return @async def getFileFromServer(self, clanId, fileType, callback): if not BigWorld.player().serverSettings['file_server'].has_key(fileType): LOG_ERROR("Invalid server's file type: %s" % fileType) self._valueResponse(0, (None, None), callback) return None else: clan_emblems = BigWorld.player().serverSettings['file_server'][fileType] BigWorld.player().customFilesCache.get(clan_emblems['url_template'] % clanId, lambda url, file: self._valueResponse(0, (url, file), callback), True) return None @async @process def getClanEmblemTextureID(self, clanDBID, isBig, textureID, callback): import imghdr if clanDBID is not None and clanDBID != 0: _, clanEmblemFile = yield self.getFileFromServer(clanDBID, 'clan_emblems_small' if not isBig else 'clan_emblems_big') if clanEmblemFile and imghdr.what(None, clanEmblemFile) is not None: BigWorld.wg_addTempScaleformTexture(textureID, clanEmblemFile) callback(textureID) return callback(None) return def getClanRoleUserString(self): position = self.clanInfo[3] return getClanRoleString(position) def onClanInfoReceived(self, clanDBID, clanName, clanAbbrev, clanMotto, clanDescription): self.__clanMotto = passCensor(html.escape(clanMotto)) self.__clanDescription = passCensor(html.escape(clanDescription)) def _valueResponse(self, resID, value, callback): if resID < 0: LOG_ERROR('[class %s] There is error while getting data from cache: %s[%d]' % (self.__class__.__name__, code2str(resID), resID)) return callback(value) callback(value) def _onResync(self): if not self.__waitForSync: self.__invalidateData() def __invalidateData(self, diff = None, callback = lambda *args: None): if diff is not None: if 'stats' in diff and 'clanInfo' in diff['stats']: self.__fortProvider.resetState() callback(True) return def __startFortProvider(self): self.__clanMembersLen = len(self.clanMembers) g_messengerEvents.users.onClanMembersListChanged += self.__me_onClanMembersListChanged self.__fortProvider.start(self) def __stopFortProvider(self): self.__clanMembersLen = None g_messengerEvents.users.onClanMembersListChanged -= self.__me_onClanMembersListChanged self.__fortProvider.stop() return def __me_onClanMembersListChanged(self): clanMembersLen = len(self.clanMembers) if self.__clanMembersLen is not None and clanMembersLen != self.__clanMembersLen: self.__clanMembersLen = clanMembersLen self.__fortProvider.resetState() self.__fortProvider.notify('onClanMembersListChanged') return
class _ItemsCache(object): def __init__(self): self.__items = ItemsRequester() self.__waitForSync = False self.onSyncStarted = Event() self.onSyncCompleted = Event() def init(self): g_playerEvents.onInventoryResync += self.__pe_onInventoryResync g_playerEvents.onDossiersResync += self.__pe_onDossiersResync g_playerEvents.onStatsResync += self.__pe_onStatsResync g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected g_playerEvents.onStatsResync -= self.__pe_onStatsResync g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync @property def waitForSync(self): return self.__waitForSync @property def items(self): return self.__items @async def update(self, updateReason, diff = None, callback = None): if diff is None: self.__invalidateFullData(updateReason, callback) else: self.__invalidateData(updateReason, diff, callback) def clear(self): LOG_DEBUG('Clearing items cache.') return self.items.clear() def _onResync(self, reason): if not self.__waitForSync: self.__invalidateFullData(reason) def _onCenterIsLongDisconnected(self, isLongDisconnected): self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected) def __invalidateData(self, updateReason, diff, callback = lambda *args: None): self.__waitForSync = True self.onSyncStarted() if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC: invalidItems = self.__items.invalidateCache(diff) else: invalidItems = {} def cbWrapper(*args): self.__waitForSync = False self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def __invalidateFullData(self, updateReason, callback = lambda *args: None): self.__waitForSync = True self.onSyncStarted() def cbWrapper(*args): self.__waitForSync = False if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC: invalidItems = self.__items.invalidateCache() else: invalidItems = {} self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def isSynced(self): return self.items.isSynced() def __pe_onStatsResync(self, *args): self._onResync(CACHE_SYNC_REASON.STATS_RESYNC) def __pe_onInventoryResync(self, *args): self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC) def __pe_onDossiersResync(self, *args): self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
class ContainerManager(ContainerManagerMeta): __DESTROY_ORDER = (ViewTypes.DEFAULT, ViewTypes.LOBBY_SUB, ViewTypes.WINDOW, ViewTypes.BROWSER, ViewTypes.TOP_WINDOW, ViewTypes.WAITING, ViewTypes.CURSOR, ViewTypes.SERVICE_LAYOUT) __CONTAINERS_TO_CLEAR = (ViewTypes.WINDOW, ViewTypes.BROWSER, ViewTypes.TOP_WINDOW) def __init__(self, loader): super(ContainerManager, self).__init__() self.onViewAddedToContainer = Event() proxy = weakref.proxy(self) self.__containers = {ViewTypes.DEFAULT: _DefaultContainer(proxy), ViewTypes.CURSOR: _DefaultContainer(proxy), ViewTypes.WAITING: _DefaultContainer(proxy), ViewTypes.WINDOW: _PopUpContainer(proxy), ViewTypes.BROWSER: _PopUpContainer(proxy), ViewTypes.TOP_WINDOW: _PopUpContainer(proxy), ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)} self._loadingViews = dict() self.__loader = loader self.__loader.onViewLoaded += self.__loader_onViewLoaded self.__scopeController = GlobalScopeController() self.__scopeController.create() def load(self, alias, name = None, *args, **kwargs): if name is None: name = alias isViewExists = self.as_getViewS(name) if not isViewExists and (alias, name) not in self._loadingViews: pyEntity = self.__loader.loadView(alias, name, *args, **kwargs) self.__scopeController.addLoadingView(pyEntity, False) curType = pyEntity.settings.type if self.canCancelPreviousLoading(curType): result = [] for kev, val in self._loadingViews.iteritems(): if val.settings.type == pyEntity.settings.type: result.append(val) if len(result) > 0: self.__cancelLoadingForPyEntities(result) self._loadingViews[alias, name] = pyEntity return def __cancelLoadingForPyEntities(self, pyEntities): for curEntity in pyEntities: self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName)) self.__loader.cancelLoadingByName(curEntity.uniqueName) curEntity.destroy() def canCancelPreviousLoading(self, containerType): container = self.getContainer(containerType) if container is not None: return container.canCancelPreviousLoading() else: return False return def addContainer(self, containerType, name, container = None): result = True if containerType not in self.__containers: if container is None: self.__containers[containerType] = _DefaultContainer(weakref.proxy(self)) self.as_registerContainerS(containerType, name) elif isinstance(container, IViewContainer): self.__containers[containerType] = container self.as_registerContainerS(containerType, name) else: LOG_ERROR('Container must be implemented IViewContainer', container) result = False else: LOG_ERROR('Container already registered', containerType) result = False return result def removeContainer(self, viewType): self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType()) result = True if viewType in self.__containers: container = self.__containers[viewType] container.destroy() self.as_unregisterContainerS(viewType) del self.__containers[viewType] else: result = False return result def getContainer(self, viewType): if viewType in self.__containers: return self.__containers[viewType] else: return None def isModalViewsIsExists(self): if self.getContainer(ViewTypes.TOP_WINDOW).getViewCount(isModal=True) > 0: return True elif self.getContainer(ViewTypes.BROWSER).getViewCount(isModal=True) > 0: return True else: return self.getContainer(ViewTypes.WINDOW).getViewCount(isModal=True) > 0 def getView(self, viewType, criteria = None): view = None container = self.getContainer(viewType) if container is not None: view = container.getView(criteria=criteria) else: raise Exception('Container for %s view is None!' % viewType) return view def isViewAvailable(self, viewType, criteria = None): container = self.getContainer(viewType) if container is not None: return container.getView(criteria=criteria) is not None else: return False return def closePopUps(self): self.as_closePopUpsS() def clear(self): for c in self.__CONTAINERS_TO_CLEAR: self.getContainer(c).clear() def _dispose(self): if self.__loader is not None: self.__loader.onViewLoaded -= self.__loader_onViewLoaded self.__loader = None for viewType in self.__DESTROY_ORDER: if viewType in self.__containers: container = self.__containers.pop(viewType) LOG_DEBUG('CONTAINER: ' + str(container) + '/' + viewType) container.destroy() if len(self.__containers): LOG_ERROR('No all containers are destructed.') self.__containers.clear() self.onViewAddedToContainer.clear() self.__scopeController.destroy() self.__scopeController = None self._loadingViews.clear() self._loadingViews = None super(ContainerManager, self)._dispose() return def __loader_onViewLoaded(self, pyView): viewType = pyView.settings.type if viewType is None: LOG_ERROR('Type of view is not defined', pyView.settings) viewKey = (pyView.alias, pyView.uniqueName) if viewKey in self._loadingViews: self._loadingViews.pop(viewKey) if viewType in self.__containers: if ViewTypes.DEFAULT == viewType: self.closePopUps() if self.__scopeController.isViewLoading(pyView): container = self.__containers[viewType] if container.add(pyView): self.__scopeController.addView(pyView, False) self.as_showS(pyView.uniqueName, 0, 0) pyView.create() subContainerType = pyView.getSubContainerType() if subContainerType is not None: self.addContainer(subContainerType, pyView.uniqueName) LOG_DEBUG('View added to container', pyView) self.onViewAddedToContainer(container, pyView) else: LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView)) self.as_hideS(pyView.uniqueName) pyView.destroy() else: LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView)) return
class AvatarInputHandler(CallbackDelayer, ComponentSystem): bootcampCtrl = dependency.descriptor(IBootcampController) ctrl = property(lambda self: self.__curCtrl) ctrls = property(lambda self: self.__ctrls) isSPG = property(lambda self: self.__isSPG) isATSPG = property(lambda self: self.__isATSPG) isFlashBangAllowed = property(lambda self: self.__ctrls['video'] != self.__curCtrl) isDetached = property(lambda self: self.__isDetached) isGuiVisible = property(lambda self: self.__isGUIVisible) isStarted = property(lambda self: self.__isStarted) isObserverFPV = property(lambda self: BigWorld.player().isObserver() and BigWorld.player().isObserverFPV) remoteCameraSender = property(lambda self: self.__remoteCameraSender) __ctrlModeName = aih_global_binding.bindRW(_BINDING_ID.CTRL_MODE_NAME) __aimOffset = aih_global_binding.bindRW(_BINDING_ID.AIM_OFFSET) _DYNAMIC_CAMERAS_ENABLED_KEY = 'global/dynamicCameraEnabled' settingsCore = dependency.descriptor(ISettingsCore) @staticmethod def enableDynamicCamera(enable, useHorizontalStabilizer=True): for dynamicCameraClass in _DYNAMIC_CAMERAS: dynamicCameraClass.enableDynamicCamera(enable) SniperAimingSystem.setStabilizerSettings(useHorizontalStabilizer, True) @staticmethod def isCameraDynamic(): for dynamicCameraClass in _DYNAMIC_CAMERAS: if not dynamicCameraClass.isCameraDynamic(): return False return True @staticmethod def isSniperStabilized(): return SniperAimingSystem.getStabilizerSettings() @property def ctrlModeName(self): return self.__ctrlModeName siegeModeControl = ComponentDescriptor() siegeModeSoundNotifications = ComponentDescriptor() steadyVehicleMatrixCalculator = ComponentDescriptor() def __init__(self): CallbackDelayer.__init__(self) ComponentSystem.__init__(self) self.__alwaysShowAimKey = None self.__showMarkersKey = None sec = self._readCfg() self.onCameraChanged = Event() self.onPostmortemVehicleChanged = Event() self.onPostmortemKillerVisionEnter = Event() self.onPostmortemKillerVisionExit = Event() self.__isArenaStarted = False self.__isStarted = False self.__targeting = _Targeting() self.__vertScreenshotCamera = _VertScreenshotCamera() self.__ctrls = dict() self.__killerVehicleID = None self.__isAutorotation = True self.__prevModeAutorotation = None self.__isSPG = False self.__isATSPG = False self.__setupCtrls(sec) self.__curCtrl = self.__ctrls[_CTRLS_FIRST] self.__ctrlModeName = _CTRLS_FIRST self.__isDetached = False self.__waitObserverCallback = None self.__observerVehicle = None self.__observerIsSwitching = False self.__commands = [] self.__remoteCameraSender = None self.__isGUIVisible = False return def __constructComponents(self): player = BigWorld.player() if player.vehicleTypeDescriptor.hasSiegeMode: if not self.siegeModeControl: self.siegeModeControl = SiegeModeControl() self.__commands.append(self.siegeModeControl) self.siegeModeControl.onSiegeStateChanged += lambda *args: self.steadyVehicleMatrixCalculator.relinkSources() self.siegeModeSoundNotifications = SiegeModeSoundNotifications() self.siegeModeControl.onSiegeStateChanged += self.siegeModeSoundNotifications.onSiegeStateChanged self.siegeModeControl.onRequestFail += self.__onRequestFail self.siegeModeControl.onSiegeStateChanged += SiegeModeCameraShaker.shake if self.bootcampCtrl.isInBootcamp() and constants.HAS_DEV_RESOURCES: self.__commands.append(BootcampModeControl()) def prerequisites(self): out = [] for ctrl in self.__ctrls.itervalues(): out += ctrl.prerequisites() return out def handleKeyEvent(self, event): import game isDown, key, mods, isRepeat = game.convertKeyEvent(event) if isRepeat: return False elif self.__isStarted and self.__isDetached: if self.__curCtrl.alwaysReceiveKeyEvents() and not self.isObserverFPV or CommandMapping.g_instance.isFired(CommandMapping.CMD_CM_LOCK_TARGET, key): self.__curCtrl.handleKeyEvent(isDown, key, mods, event) return BigWorld.player().handleKey(isDown, key, mods) elif not self.__isStarted or self.__isDetached: return False for command in self.__commands: if command.handleKeyEvent(isDown, key, mods, event): return True if isDown and BigWorld.isKeyDown(Keys.KEY_CAPSLOCK): if self.__alwaysShowAimKey is not None and key == self.__alwaysShowAimKey: gui_event_dispatcher.toggleCrosshairVisibility() return True if self.__showMarkersKey is not None and key == self.__showMarkersKey and not self.__isGUIVisible: gui_event_dispatcher.toggleMarkers2DVisibility() return True if key == Keys.KEY_F5 and constants.HAS_DEV_RESOURCES: self.__vertScreenshotCamera.enable(not self.__vertScreenshotCamera.isEnabled) return True if key == Keys.KEY_SPACE and isDown and BigWorld.player().isObserver(): BigWorld.player().cell.switchObserverFPV(not BigWorld.player().isObserverFPV) return True else: return True if not self.isObserverFPV and self.__curCtrl.handleKeyEvent(isDown, key, mods, event) else BigWorld.player().handleKey(isDown, key, mods) def handleMouseEvent(self, dx, dy, dz): return False if not self.__isStarted or self.__isDetached else self.__curCtrl.handleMouseEvent(dx, dy, dz) def setForcedGuiControlMode(self, flags): result = False detached = flags & GUI_CTRL_MODE_FLAG.CURSOR_ATTACHED > 0 if detached ^ self.__isDetached: self.__isDetached = detached self.__targeting.detach(self.__isDetached) if detached: g_appLoader.attachCursor(settings.APP_NAME_SPACE.SF_BATTLE, flags=flags) result = True if flags & GUI_CTRL_MODE_FLAG.AIMING_ENABLED > 0: self.setAimingMode(False, AIMING_MODE.USER_DISABLED) else: g_appLoader.detachCursor(settings.APP_NAME_SPACE.SF_BATTLE) result = True self.__curCtrl.setForcedGuiControlMode(detached) elif detached: g_appLoader.syncCursor(settings.APP_NAME_SPACE.SF_BATTLE, flags=flags) return result def updateShootingStatus(self, canShoot): return None if self.__isDetached else self.__curCtrl.updateShootingStatus(canShoot) def getDesiredShotPoint(self, ignoreAimingMode=False): return None if self.__isDetached else self.__curCtrl.getDesiredShotPoint(ignoreAimingMode) def getMarkerPoint(self): point = None if self.__ctrlModeName in (_CTRL_MODE.ARCADE, _CTRL_MODE.STRATEGIC, _CTRL_MODE.ARTY): AimingSystems.shootInSkyPoint.has_been_called = False point = self.getDesiredShotPoint(ignoreAimingMode=True) if AimingSystems.shootInSkyPoint.has_been_called: point = None return point def showGunMarker(self, isShown): self.__curCtrl.setGunMarkerFlag(isShown, _GUN_MARKER_FLAG.CLIENT_MODE_ENABLED) def showGunMarker2(self, isShown): if not BattleReplay.isPlaying(): self.__curCtrl.setGunMarkerFlag(isShown, _GUN_MARKER_FLAG.SERVER_MODE_ENABLED) if gun_marker_ctrl.useDefaultGunMarkers(): self.__curCtrl.setGunMarkerFlag(not isShown, _GUN_MARKER_FLAG.CLIENT_MODE_ENABLED) replayCtrl = BattleReplay.g_replayCtrl replayCtrl.setUseServerAim(isShown) def updateGunMarker(self, pos, direction, size, relaxTime, collData): self.__curCtrl.updateGunMarker(_GUN_MARKER_TYPE.CLIENT, pos, direction, size, relaxTime, collData) def updateGunMarker2(self, pos, direction, size, relaxTime, collData): self.__curCtrl.updateGunMarker(_GUN_MARKER_TYPE.SERVER, pos, direction, size, relaxTime, collData) def setAimingMode(self, enable, mode): self.__curCtrl.setAimingMode(enable, mode) def getAimingMode(self, mode): return self.__curCtrl.getAimingMode(mode) def setAutorotation(self, bValue): if not self.__curCtrl.enableSwitchAutorotationMode(): return elif not BigWorld.player().isOnArena: return else: if self.__isAutorotation != bValue: self.__isAutorotation = bValue BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation) self.__prevModeAutorotation = None return def getAutorotation(self): return self.__isAutorotation def switchAutorotation(self): self.setAutorotation(not self.__isAutorotation) def activatePostmortem(self, isRespawn): if self.siegeModeSoundNotifications is not None: self.siegeModeSoundNotifications = None BigWorld.player().autoAim(None) for ctlMode in self.__ctrls.itervalues(): ctlMode.resetAimingMode() try: params = self.__curCtrl.postmortemCamParams except Exception: params = None onPostmortemActivation = getattr(self.__curCtrl, 'onPostmortemActivation', None) if onPostmortemActivation is not None: onPostmortemActivation(_CTRL_MODE.POSTMORTEM, postmortemParams=params, bPostmortemDelay=True, respawn=isRespawn) else: self.onControlModeChanged(_CTRL_MODE.POSTMORTEM, postmortemParams=params, bPostmortemDelay=True, respawn=isRespawn) return def deactivatePostmortem(self): self.onControlModeChanged('arcade') arcadeMode = self.__ctrls['arcade'] arcadeMode.camera.setToVehicleDirection() self.__identifySPG() self.__constructComponents() def setKillerVehicleID(self, killerVehicleID): self.__killerVehicleID = killerVehicleID def getKillerVehicleID(self): return self.__killerVehicleID def start(self): g_guiResetters.add(self.__onRecreateDevice) self.steadyVehicleMatrixCalculator = SteadyVehicleMatrixCalculator() self.__identifySPG() self.__constructComponents() for control in self.__ctrls.itervalues(): control.create() avatar = BigWorld.player() if not self.__curCtrl.isManualBind(): avatar.positionControl.bindToVehicle(True) self.__curCtrl.enable() tmp = self.__curCtrl.getPreferredAutorotationMode() if tmp is not None: self.__isAutorotation = tmp self.__prevModeAutorotation = True else: self.__isAutorotation = True self.__prevModeAutorotation = None avatar.enableOwnVehicleAutorotation(self.__isAutorotation) self.__targeting.enable(True) self.__isStarted = True self.__isGUIVisible = True self.__killerVehicleID = None arena = avatar.arena arena.onPeriodChange += self.__onArenaStarted self.settingsCore.onSettingsChanged += self.__onSettingsChanged avatar.consistentMatrices.onVehicleMatrixBindingChanged += self.__onVehicleChanged self.__onArenaStarted(arena.period) if not avatar.isObserver() and arena.hasObservers: self.__remoteCameraSender = RemoteCameraSender(self) self.onCameraChanged('arcade') return def stop(self): self.__isStarted = False import SoundGroups SoundGroups.g_instance.changePlayMode(0) aih_global_binding.clear() for control in self.__ctrls.itervalues(): control.destroy() replayCtrl = BattleReplay.g_replayCtrl if replayCtrl.isRecording: replayCtrl.setPlayerVehicleID(0) if self.__remoteCameraSender is not None: self.__remoteCameraSender.destroy() self.__remoteCameraSender = None self.onCameraChanged.clear() self.onCameraChanged = None self.onPostmortemVehicleChanged.clear() self.onPostmortemVehicleChanged = None self.onPostmortemKillerVisionEnter.clear() self.onPostmortemKillerVisionEnter = None self.onPostmortemKillerVisionExit.clear() self.onPostmortemKillerVisionExit = None self.__targeting.enable(False) self.__killerVehicleID = None if self.__onRecreateDevice in g_guiResetters: g_guiResetters.remove(self.__onRecreateDevice) BigWorld.player().arena.onPeriodChange -= self.__onArenaStarted self.settingsCore.onSettingsChanged -= self.__onSettingsChanged BigWorld.player().consistentMatrices.onVehicleMatrixBindingChanged -= self.__onVehicleChanged ComponentSystem.destroy(self) CallbackDelayer.destroy(self) return def __onVehicleChanged(self, isStatic): self.steadyVehicleMatrixCalculator.relinkSources() self.__identifySPG() if self.__waitObserverCallback is not None and self.__observerVehicle is not None: player = BigWorld.player() ownVehicle = BigWorld.entity(player.playerVehicleID) vehicle = player.getVehicleAttached() if vehicle != ownVehicle: self.__waitObserverCallback() self.__observerIsSwitching = False self.__observerVehicle = None return def setObservedVehicle(self, vehicleID): for control in self.__ctrls.itervalues(): control.setObservedVehicle(vehicleID) def onControlModeChanged(self, eMode, **args): if self.steadyVehicleMatrixCalculator is not None: self.steadyVehicleMatrixCalculator.relinkSources() if not self.__isArenaStarted and eMode != _CTRL_MODE.POSTMORTEM: return else: player = BigWorld.player() isObserverMode = 'observer' in player.vehicleTypeDescriptor.type.tags if player is not None else True if self.__waitObserverCallback is not None: self.__waitObserverCallback = None if isObserverMode and eMode == _CTRL_MODE.POSTMORTEM: if self.__observerVehicle is not None and not self.__observerIsSwitching: self.__waitObserverCallback = partial(self.onControlModeChanged, eMode, **args) self.__observerIsSwitching = True player.positionControl.followCamera(False) player.positionControl.bindToVehicle(True, self.__observerVehicle) return if isObserverMode and self.__ctrlModeName == _CTRL_MODE.POSTMORTEM: player = BigWorld.player() self.__observerVehicle = player.vehicle.id if player.vehicle else None self.__observerIsSwitching = False replayCtrl = BattleReplay.g_replayCtrl if replayCtrl.isRecording: replayCtrl.setControlMode(eMode) self.__curCtrl.disable() prevCtrl = self.__curCtrl self.__curCtrl = self.__ctrls[eMode] self.__ctrlModeName = eMode if player is not None: if not prevCtrl.isManualBind() and self.__curCtrl.isManualBind(): if isObserverMode: player.positionControl.bindToVehicle(False, -1) else: player.positionControl.bindToVehicle(False) elif prevCtrl.isManualBind() and not self.__curCtrl.isManualBind(): if isObserverMode: player.positionControl.followCamera(False) player.positionControl.bindToVehicle(True, self.__observerVehicle) else: player.positionControl.bindToVehicle(True) elif not prevCtrl.isManualBind() and not self.__curCtrl.isManualBind(): if isObserverMode and not self.isObserverFPV: player.positionControl.bindToVehicle(True) newAutoRotationMode = self.__curCtrl.getPreferredAutorotationMode() if newAutoRotationMode is not None: if prevCtrl.getPreferredAutorotationMode() is None: self.__prevModeAutorotation = self.__isAutorotation if self.__isAutorotation != newAutoRotationMode: self.__isAutorotation = newAutoRotationMode BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation) elif prevCtrl.getPreferredAutorotationMode() is not None: if self.__prevModeAutorotation is None: self.__prevModeAutorotation = True if self.__isAutorotation != self.__prevModeAutorotation: self.__isAutorotation = self.__prevModeAutorotation BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation) self.__prevModeAutorotation = None if not isObserverMode and self.__ctrlModeName in (_CTRL_MODE.ARCADE, _CTRL_MODE.SNIPER): lockEnabled = prevCtrl.getAimingMode(AIMING_MODE.TARGET_LOCK) self.__curCtrl.setAimingMode(lockEnabled, AIMING_MODE.TARGET_LOCK) self.__targeting.onRecreateDevice() self.__curCtrl.setGUIVisible(self.__isGUIVisible) if isObserverMode: args.update(vehicleID=self.__observerVehicle) self.__curCtrl.enable(**args) else: self.__curCtrl.enable(**args) isReplayPlaying = replayCtrl.isPlaying vehicleID = None vehicle = player.getVehicleAttached() if isObserverMode: vehicleID = self.__observerVehicle elif vehicle is not None and isReplayPlaying: vehicleID = vehicle.id self.onCameraChanged(eMode, vehicleID) if not isReplayPlaying: self.__curCtrl.handleMouseEvent(0.0, 0.0, 0.0) return def onVehicleControlModeChanged(self, eMode): LOG_DEBUG('onVehicleControlModeChanged: ', eMode, self.isObserverFPV) if not self.isObserverFPV: self.onControlModeChanged(_CTRL_MODE.POSTMORTEM) return else: if eMode is None: eMode = _CTRL_MODES[BigWorld.player().observerFPVControlMode] targetPos = self.getDesiredShotPoint() or Math.Vector3(0, 0, 0) LOG_DEBUG('onVehicleControlModeChanged: ', eMode, targetPos) self.onControlModeChanged(eMode, preferredPos=targetPos, aimingMode=0, saveZoom=False, saveDist=True, equipmentID=None, curVehicleID=BigWorld.player().getVehicleAttached()) return def getTargeting(self): return self.__targeting def setGUIVisible(self, isVisible): self.__isGUIVisible = isVisible self.__curCtrl.setGUIVisible(isVisible) def selectPlayer(self, vehId): self.__curCtrl.selectPlayer(vehId) def onMinimapClicked(self, worldPos): self.__curCtrl.onMinimapClicked(worldPos) def onVehicleShaken(self, vehicle, impulsePosition, impulseDir, caliber, shakeReason): if shakeReason == _ShakeReason.OWN_SHOT_DELAYED: shakeFuncBound = functools.partial(self.onVehicleShaken, vehicle, impulsePosition, impulseDir, caliber, _ShakeReason.OWN_SHOT) delayTime = self.__dynamicCameraSettings.settings['ownShotImpulseDelay'] self.delayCallback(delayTime, shakeFuncBound) return else: camera = getattr(self.ctrl, 'camera', None) if camera is None: return impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber) vehicleSensitivity = 0.0 avatarVehicle = BigWorld.player().getVehicleAttached() if avatarVehicle is None or not avatarVehicle.isAlive(): return avatarVehicleTypeDesc = getattr(avatarVehicle, 'typeDescriptor', None) if avatarVehicleTypeDesc is not None: avatarVehWeightTons = avatarVehicleTypeDesc.physics['weight'] / 1000.0 vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehWeightTons) vehicleSensitivity *= avatarVehicleTypeDesc.hull.swinging.sensitivityToImpulse impulseReason = None isDistant = False if shakeReason == _ShakeReason.OWN_SHOT: if vehicle is avatarVehicle: impulseReason = cameras.ImpulseReason.MY_SHOT isDistant = False else: impulseReason = cameras.ImpulseReason.OTHER_SHOT isDistant = True elif vehicle is avatarVehicle: if shakeReason == _ShakeReason.HIT or shakeReason == _ShakeReason.HIT_NO_DAMAGE: impulseValue *= 1.0 if shakeReason == _ShakeReason.HIT else self.__dynamicCameraSettings.settings['zeroDamageHitSensitivity'] impulseReason = cameras.ImpulseReason.ME_HIT isDistant = False else: impulseReason = cameras.ImpulseReason.SPLASH isDistant = True impulseDir, impulseValue = self.__adjustImpulse(impulseDir, impulseValue, camera, impulsePosition, vehicleSensitivity, impulseReason) if isDistant: camera.applyDistantImpulse(impulsePosition, impulseValue, impulseReason) else: camera.applyImpulse(impulsePosition, impulseDir * impulseValue, impulseReason) return def onVehicleCollision(self, vehicle, impactVelocity): if impactVelocity < self.__dynamicCameraSettings.settings['minCollisionSpeed']: return else: camera = getattr(self.ctrl, 'camera', None) if camera is None: return avatarVehicle = BigWorld.player().getVehicleAttached() if avatarVehicle is None or not avatarVehicle.isAlive(): return if vehicle is avatarVehicle: impulse = Math.Vector3(0, impactVelocity * self.__dynamicCameraSettings.settings['collisionSpeedToImpulseRatio'], 0) camera.applyImpulse(vehicle.position, impulse, cameras.ImpulseReason.COLLISION) return def onVehicleDeath(self, vehicle, exploded): if not exploded: return else: camera = getattr(self.ctrl, 'camera', None) if camera is None: return avatarVehicle = BigWorld.player().getVehicleAttached() if avatarVehicle is None or avatarVehicle is vehicle: return caliber = vehicle.typeDescriptor.shot.shell.caliber impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber) avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0 vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons) vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, vehicle.position, vehicleSensitivity, cameras.ImpulseReason.VEHICLE_EXPLOSION) camera.applyDistantImpulse(vehicle.position, impulseValue, cameras.ImpulseReason.VEHICLE_EXPLOSION) return def onExplosionImpulse(self, position, impulseValue): camera = getattr(self.ctrl, 'camera', None) if camera is None: return else: avatarVehicle = BigWorld.player().getVehicleAttached() if avatarVehicle is None: return avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0 vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons) vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, position, vehicleSensitivity, cameras.ImpulseReason.HE_EXPLOSION) camera.applyDistantImpulse(position, impulseValue, cameras.ImpulseReason.HE_EXPLOSION) return def onProjectileHit(self, position, caliber, isOwnShot): if not isOwnShot: return else: camera = getattr(self.ctrl, 'camera', None) if camera is None: return impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber) vehicleSensitivity = 1.0 avatarVehicle = BigWorld.player().getVehicleAttached() if avatarVehicle is not None: avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0 vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons) vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, position, vehicleSensitivity, cameras.ImpulseReason.VEHICLE_EXPLOSION) camera.applyDistantImpulse(position, impulseValue, cameras.ImpulseReason.PROJECTILE_HIT) return def onSpecificImpulse(self, position, impulse, specificCtrl=None): if specificCtrl is None: camera = getattr(self.ctrl, 'camera', None) else: camera = self.ctrls[specificCtrl].camera if camera is None: return else: camera.applyImpulse(position, impulse, cameras.ImpulseReason.MY_SHOT) return def __adjustImpulse(self, impulseDir, impulseValue, camera, impulsePosition, vehicleSensitivity, impulseReason): if impulseReason in camera.getReasonsAffectCameraDirectly(): dirToCamera = camera.camera.position - impulsePosition dirToCamera.normalise() impulseDir = dirToCamera else: impulseValue *= vehicleSensitivity return (impulseDir, impulseValue) def __identifySPG(self): veh = BigWorld.entity(BigWorld.player().playerVehicleID) if veh is None: return else: vehTypeDesc = veh.typeDescriptor.type self.__isSPG = 'SPG' in vehTypeDesc.tags self.__isATSPG = 'AT-SPG' in vehTypeDesc.tags return def reloadDynamicSettings(self): if not constants.HAS_DEV_RESOURCES: return ResMgr.purge(INPUT_HANDLER_CFG) sec = ResMgr.openSection(INPUT_HANDLER_CFG) self.__dynamicCameraSettings = DynamicCameraSettings(sec['dynamicCameraCommon']) try: self.__ctrls['sniper'].camera.aimingSystem.reloadConfig(sec['sniperMode']['camera']) except Exception: pass def _readCfg(self): sec = ResMgr.openSection(INPUT_HANDLER_CFG) if sec is None: LOG_ERROR('can not open <%s>.' % INPUT_HANDLER_CFG) return else: self.__checkSections(sec) keySec = sec['keys'] if keySec is not None: self.__showMarkersKey = getattr(Keys, keySec.readString('showMarkersKey', ''), None) self.__alwaysShowAimKey = getattr(Keys, keySec.readString('alwaysShowAimKey', ''), None) self.__dynamicCameraSettings = DynamicCameraSettings(sec['dynamicCameraCommon']) return sec def __setupCtrls(self, section): modules = (control_modes, MapCaseMode, RespawnDeathMode, epic_battle_death_mode) bonusType = BigWorld.player().arenaBonusType bonusTypeCtrlsMap = _OVERWRITE_CTRLS_DESC_MAP.get(bonusType, {}) for name, desc in _CTRLS_DESC_MAP.items(): if bonusTypeCtrlsMap.has_key(name): desc = bonusTypeCtrlsMap.get(name) try: if desc[2] != _CTRL_TYPE.DEVELOPMENT or desc[2] == _CTRL_TYPE.DEVELOPMENT and constants.HAS_DEV_RESOURCES: if name not in self.__ctrls: for module in modules: classType = getattr(module, desc[0], None) if classType is None: pass self.__ctrls[name] = classType(section[desc[1]] if desc[1] else None, self) break except Exception: LOG_DEBUG('Error while setting ctrls', name, desc, constants.HAS_DEV_RESOURCES) LOG_CURRENT_EXCEPTION() return def __checkSections(self, section): for _, desc in _CTRLS_DESC_MAP.items(): if desc[1] is None or desc[2] == _CTRL_TYPE.OPTIONAL or desc[2] == _CTRL_TYPE.DEVELOPMENT and not constants.HAS_DEV_RESOURCES: continue if not section.has_key(desc[1]): LOG_ERROR('Invalid section <%s> in <%s>.' % (desc[1], INPUT_HANDLER_CFG)) return def __onArenaStarted(self, period, *args): self.__isArenaStarted = period == ARENA_PERIOD.BATTLE self.__curCtrl.setGunMarkerFlag(self.__isArenaStarted, _GUN_MARKER_FLAG.CONTROL_ENABLED) self.showGunMarker2(gun_marker_ctrl.useServerGunMarker()) self.showGunMarker(gun_marker_ctrl.useClientGunMarker()) def __onRecreateDevice(self): self.__curCtrl.onRecreateDevice() self.__targeting.onRecreateDevice() def __onSettingsChanged(self, diff): if 'dynamicCamera' in diff or 'horStabilizationSnp' in diff: dynamicCamera = self.settingsCore.getSetting('dynamicCamera') horStabilizationSnp = self.settingsCore.getSetting('horStabilizationSnp') self.enableDynamicCamera(dynamicCamera, horStabilizationSnp) def __onRequestFail(self): player = BigWorld.player() if player is not None: player.showVehicleError('cantSwitchEngineDestroyed') return
class CompanyBattleController(Notifiable): def __init__(self, eventsCache): self.__eventsCache = weakref.proxy(eventsCache) self.onCompanyStateChanged = Event() super(CompanyBattleController, self).__init__() self.__isLobbyLoaded = False self.__delayedCompanyState = [] def start(self): g_eventBus.addListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited) g_playerEvents.onAvatarBecomePlayer += self.__onAvatarBecomePlayer g_connectionManager.onDisconnected += self.__onDisconnected self.setNotificators() def stop(self): self.onCompanyStateChanged.clear() self.clearNotification() g_eventBus.removeListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited) g_playerEvents.onAvatarBecomePlayer -= self.__onAvatarBecomePlayer g_connectionManager.onDisconnected -= self.__onDisconnected def setNotificators(self): battle = self.__eventsCache.getCompanyBattles() self.clearNotification() if battle.isValid(): destroyingTimeLeft = battle.getDestroyingTimeLeft() if destroyingTimeLeft is not None: if destroyingTimeLeft <= 0: self.__onCompanyFinished() else: self.addNotificators( AcyclicNotifier(battle.getDestroyingTimeLeft, self.__onCompanyFinished)) if battle.isCreationTimeCorrect(): self.__onCompanyStarted() else: self.addNotificators( AcyclicNotifier(battle.getCreationTimeLeft, self.__onCompanyStarted)) self.startNotification() else: self.__onCompanyFinished() return def __onLobbyInited(self, *args): self.__isLobbyLoaded = True self.__handlePostponed() def __onAvatarBecomePlayer(self): self.__isLobbyLoaded = False def __onDisconnected(self): self.__isLobbyLoaded = False def __onCompanyStarted(self): if self.__isLobbyLoaded: self.onCompanyStateChanged(True) else: self.__delayedCompanyState.append(True) def __onCompanyFinished(self): if self.__isLobbyLoaded: self.onCompanyStateChanged(False) else: self.__delayedCompanyState.append(False) def __handlePostponed(self): for companyState in self.__delayedCompanyState: self.onCompanyStateChanged(companyState) self.__delayedCompanyState = []
class ContainerManager(ContainerManagerMeta): """ Class of container manager. """ def __init__(self, loader, *containers): super(ContainerManager, self).__init__() self.onViewAddedToContainer = Event() proxy = weakref.proxy(self) self.__containers = {} for container in containers: raise isinstance(container, AbstractViewContainer) or AssertionError self.__containers[container.getViewType()] = container(proxy) self._loadingViews = dict() self.__loader = loader self.__loader.onViewLoaded += self.__loader_onViewLoaded self.__scopeController = GlobalScopeController() self.__scopeController.create() def load(self, alias, name=None, *args, **kwargs): """ Loads view to container. :param alias: :param name: :param args: :param kwargs: :return: """ if name is None: name = alias isViewExists = self.as_getViewS(name) if not isViewExists and (alias, name) not in self._loadingViews: pyEntity = self.__loader.loadView(alias, name, *args, **kwargs) self.__scopeController.addLoadingView(pyEntity, False) curType = pyEntity.settings.type if self.canCancelPreviousLoading(curType): result = [] for kev, val in self._loadingViews.iteritems(): if val.settings.type == pyEntity.settings.type: result.append(val) if result: self.__cancelLoadingForPyEntities(result) self._loadingViews[alias, name] = pyEntity return def canCancelPreviousLoading(self, containerType): container = self.getContainer(containerType) if container is not None: return container.canCancelPreviousLoading() else: return False return def addContainer(self, viewType, name, container=None): result = True if viewType not in self.__containers: if container is None: self.__containers[viewType] = DefaultContainer( viewType, weakref.proxy(self)) self.as_registerContainerS(viewType, name) elif isinstance(container, AbstractViewContainer): self.__containers[viewType] = container self.as_registerContainerS(viewType, name) else: LOG_ERROR('Container must be implemented IViewContainer', container) result = False else: LOG_ERROR('Container already registered', viewType) result = False return result def removeContainer(self, viewType): self.__scopeController.removeSubScopeController( ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType()) result = True if viewType in self.__containers: container = self.__containers[viewType] container.destroy() self.as_unregisterContainerS(viewType) del self.__containers[viewType] else: result = False return result def getContainer(self, viewType): if viewType in self.__containers: return self.__containers[viewType] else: return None def isModalViewsIsExists(self): for viewType in _POPUPS_CONTAINERS: container = self.getContainer(viewType) if container is not None and container.getViewCount(isModal=True): return True return False def getView(self, viewType, criteria=None): container = self.getContainer(viewType) if container is not None: view = container.getView(criteria=criteria) else: raise Exception('Container for %s view is None!' % viewType) return view def isViewAvailable(self, viewType, criteria=None): container = self.getContainer(viewType) if container is not None: return container.getView(criteria=criteria) is not None else: return False return def showContainers(self, *viewTypes): self.as_showContainersS(viewTypes) def hideContainers(self, *viewTypes): self.as_hideContainersS(viewTypes) def isContainerShown(self, viewType): return self.as_isContainerShownS(viewType) def closePopUps(self): self.as_closePopUpsS() def clear(self): for viewType in _POPUPS_CONTAINERS: container = self.getContainer(viewType) if container is not None: container.clear() return def removeLoadingView(self, alias, uniqueName): self._loadingViews.pop((alias, uniqueName), None) return def _dispose(self): if self.__loader is not None: self.__loader.onViewLoaded -= self.__loader_onViewLoaded self.__loader = None for viewType in _CONTAINERS_DESTROY_ORDER: if viewType in self.__containers: container = self.__containers.pop(viewType) LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType)) container.destroy() if len(self.__containers): LOG_ERROR('No all containers are destructed.') self.__containers.clear() self.onViewAddedToContainer.clear() self.__scopeController.destroy() self.__scopeController = None self._loadingViews.clear() self._loadingViews = None super(ContainerManager, self)._dispose() return def __cancelLoadingForPyEntities(self, pyEntities): for curEntity in pyEntities: self._loadingViews.pop( (curEntity.settings.alias, curEntity.uniqueName)) self.__loader.cancelLoadingByName(curEntity.uniqueName) curEntity.destroy() def __loader_onViewLoaded(self, pyView): viewType = pyView.settings.type if viewType is None: LOG_ERROR('Type of view is not defined', pyView.settings) viewKey = (pyView.alias, pyView.uniqueName) if viewKey in self._loadingViews: self._loadingViews.pop(viewKey) if viewType in self.__containers: if ViewTypes.DEFAULT == viewType: self.closePopUps() if self.__scopeController.isViewLoading(pyView): container = self.__containers[viewType] if container.add(pyView): self.__scopeController.addView(pyView, False) self.as_showS(pyView.uniqueName, 0, 0) pyView.create() subContainerType = pyView.getSubContainerType() if subContainerType is not None: self.addContainer(subContainerType, pyView.uniqueName) LOG_DEBUG('View added to container', pyView) self.onViewAddedToContainer(container, pyView) else: LOG_DEBUG( '"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView)) self.as_hideS(pyView.uniqueName) pyView.destroy() else: LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView)) return
class ContainerManager(ContainerManagerMeta): """ Class of container manager. """ def __init__(self, loader, *containers): super(ContainerManager, self).__init__() self.onViewAddedToContainer = Event() proxy = weakref.proxy(self) self.__containers = {} for container in containers: raise isinstance(container, AbstractViewContainer) or AssertionError self.__containers[container.getViewType()] = container(proxy) self._loadingViews = dict() self.__loader = loader self.__loader.onViewLoaded += self.__loader_onViewLoaded self.__scopeController = GlobalScopeController() self.__scopeController.create() def load(self, alias, name = None, *args, **kwargs): """ Loads view to container. :param alias: :param name: :param args: :param kwargs: :return: """ if name is None: name = alias isViewExists = self.as_getViewS(name) if not isViewExists and (alias, name) not in self._loadingViews: pyEntity = self.__loader.loadView(alias, name, *args, **kwargs) self.__scopeController.addLoadingView(pyEntity, False) curType = pyEntity.settings.type if self.canCancelPreviousLoading(curType): result = [] for kev, val in self._loadingViews.iteritems(): if val.settings.type == pyEntity.settings.type: result.append(val) if result: self.__cancelLoadingForPyEntities(result) self._loadingViews[alias, name] = pyEntity return def canCancelPreviousLoading(self, containerType): container = self.getContainer(containerType) if container is not None: return container.canCancelPreviousLoading() else: return False return def addContainer(self, viewType, name, container = None): result = True if viewType not in self.__containers: if container is None: self.__containers[viewType] = DefaultContainer(viewType, weakref.proxy(self)) self.as_registerContainerS(viewType, name) elif isinstance(container, AbstractViewContainer): self.__containers[viewType] = container self.as_registerContainerS(viewType, name) else: LOG_ERROR('Container must be implemented IViewContainer', container) result = False else: LOG_ERROR('Container already registered', viewType) result = False return result def removeContainer(self, viewType): self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType()) result = True if viewType in self.__containers: container = self.__containers[viewType] container.destroy() self.as_unregisterContainerS(viewType) del self.__containers[viewType] else: result = False return result def getContainer(self, viewType): if viewType in self.__containers: return self.__containers[viewType] else: return None def isModalViewsIsExists(self): for viewType in _POPUPS_CONTAINERS: container = self.getContainer(viewType) if container is not None and container.getViewCount(isModal=True): return True return False def getView(self, viewType, criteria = None): container = self.getContainer(viewType) if container is not None: view = container.getView(criteria=criteria) else: raise Exception('Container for %s view is None!' % viewType) return view def isViewAvailable(self, viewType, criteria = None): container = self.getContainer(viewType) if container is not None: return container.getView(criteria=criteria) is not None else: return False return def showContainers(self, *viewTypes): self.as_showContainersS(viewTypes) def hideContainers(self, *viewTypes): self.as_hideContainersS(viewTypes) def isContainerShown(self, viewType): return self.as_isContainerShownS(viewType) def closePopUps(self): self.as_closePopUpsS() def clear(self): for viewType in _POPUPS_CONTAINERS: container = self.getContainer(viewType) if container is not None: container.clear() return def removeLoadingView(self, alias, uniqueName): self._loadingViews.pop((alias, uniqueName), None) return def _dispose(self): if self.__loader is not None: self.__loader.onViewLoaded -= self.__loader_onViewLoaded self.__loader = None for viewType in _CONTAINERS_DESTROY_ORDER: if viewType in self.__containers: container = self.__containers.pop(viewType) LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType)) container.destroy() if len(self.__containers): LOG_ERROR('No all containers are destructed.') self.__containers.clear() self.onViewAddedToContainer.clear() self.__scopeController.destroy() self.__scopeController = None self._loadingViews.clear() self._loadingViews = None super(ContainerManager, self)._dispose() return def __cancelLoadingForPyEntities(self, pyEntities): for curEntity in pyEntities: self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName)) self.__loader.cancelLoadingByName(curEntity.uniqueName) curEntity.destroy() def __loader_onViewLoaded(self, pyView): viewType = pyView.settings.type if viewType is None: LOG_ERROR('Type of view is not defined', pyView.settings) viewKey = (pyView.alias, pyView.uniqueName) if viewKey in self._loadingViews: self._loadingViews.pop(viewKey) if viewType in self.__containers: if ViewTypes.DEFAULT == viewType: self.closePopUps() if self.__scopeController.isViewLoading(pyView): container = self.__containers[viewType] if container.add(pyView): self.__scopeController.addView(pyView, False) self.as_showS(pyView.uniqueName, 0, 0) pyView.create() subContainerType = pyView.getSubContainerType() if subContainerType is not None: self.addContainer(subContainerType, pyView.uniqueName) LOG_DEBUG('View added to container', pyView) self.onViewAddedToContainer(container, pyView) else: LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView)) self.as_hideS(pyView.uniqueName) pyView.destroy() else: LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView)) return
class ItemsCache(IItemsCache): def __init__(self): super(ItemsCache, self).__init__() goodies = GoodiesRequester() self.__items = ItemsRequester.ItemsRequester( InventoryRequester(), StatsRequester(), DossierRequester(), goodies, ShopRequester(goodies), RecycleBinRequester(), VehicleRotationRequester(), RankedRequester(), BadgesRequester()) self.__waitForSync = False self.__syncFailed = False self.onSyncStarted = Event() self.onSyncCompleted = Event() self.onSyncFailed = Event() def init(self): g_playerEvents.onInventoryResync += self.__pe_onInventoryResync g_playerEvents.onDossiersResync += self.__pe_onDossiersResync g_playerEvents.onStatsResync += self.__pe_onStatsResync g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() self.onSyncFailed.clear() g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected g_playerEvents.onStatsResync -= self.__pe_onStatsResync g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync @property def waitForSync(self): return self.__waitForSync @property def items(self): return self.__items @async def update(self, updateReason, diff=None, callback=None): if diff is None or self.__syncFailed: self.__invalidateFullData(updateReason, callback) else: self.__invalidateData(updateReason, diff, callback) return def clear(self): LOG_DEBUG('Clearing items cache.') return self.items.clear() def _onResync(self, reason): if not self.__waitForSync: self.__invalidateFullData(reason) def _onCenterIsLongDisconnected(self, isLongDisconnected): self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected) def __invalidateData(self, updateReason, diff, callback=lambda *args: None): self.__waitForSync = True wasSyncFailed = self.__syncFailed self.__syncFailed = False self.onSyncStarted() if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed: invalidItems = self.__items.invalidateCache(diff) else: invalidItems = {} def cbWrapper(*args): self.__waitForSync = False if not self.isSynced(): self.__syncFailed = True self.onSyncFailed(updateReason) else: self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def __invalidateFullData(self, updateReason, callback=lambda *args: None): self.__waitForSync = True wasSyncFailed = self.__syncFailed self.__syncFailed = False self.onSyncStarted() def cbWrapper(*args): self.__waitForSync = False if not self.isSynced(): self.__syncFailed = True self.onSyncFailed(updateReason) else: if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed: invalidItems = self.__items.invalidateCache() else: invalidItems = {} self.onSyncCompleted(updateReason, invalidItems) callback(*args) self.__items.request()(cbWrapper) def isSynced(self): return self.items.isSynced() def __pe_onStatsResync(self, *args): self._onResync(CACHE_SYNC_REASON.STATS_RESYNC) def __pe_onInventoryResync(self, *args): self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC) def __pe_onDossiersResync(self, *args): self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
class _CurrentVehicle: def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.onChanged = Event() self.onChangeStarted = Event() return def init(self): g_clientUpdateManager.addCallbacks({"inventory": self.onInventoryUpdate, "cache.vehsLock": self.onLocksUpdate}) game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged game_control.g_instance.rentals.onRentChangeNotify += self.onRentChange game_control.getFalloutCtrl().onSettingsChanged += self.__onFalloutChanged prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged game_control.g_instance.rentals.onRentChangeNotify -= self.onRentChange game_control.getFalloutCtrl().onSettingsChanged -= self.__onFalloutChanged _getHangarSpace().removeVehicle() self.selectNoVehicle() def onIgrTypeChanged(self, *args): if self.isPremiumIGR(): self.onChanged() self.refreshModel() def onRentChange(self, vehicles): if self.isPresent(): if self.item.intCD in vehicles: self.onChanged() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if "compDescr" in vehsDiff and self.__vehInvID in vehsDiff["compDescr"]: isVehicleSold = vehsDiff["compDescr"][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() else: isRepaired = "repair" in vehsDiff and self.__vehInvID in vehsDiff["repair"] isCustomizationChanged = ( "igrCustomizationLayout" in vehsDiff and self.__vehInvID in vehsDiff["igrCustomizationLayout"] ) isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = ( len( filter( lambda hive: self.__vehInvID in hive or (self.__vehInvID, "_r") in hive, vehsDiff.itervalues() ) ) > 0 ) if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged: self.refreshModel() if isVehicleChanged or isRepaired: self.onChanged() return def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: if self.item.intCD not in g_tankActiveCamouflage: availableKinds = [] currKind = 0 for id, startTime, days in self.item.descriptor.camouflages: if id is not None: availableKinds.append(currKind) currKind += 1 if len(availableKinds) > 0: g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds) _getHangarSpace().updateVehicle(self.item) else: _getHangarSpace().removeVehicle() return @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isGroupReady(self): return self.isPresent() and self.item.isGroupReady()[0] def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isDisabledInRent(self): return self.isPresent() and self.item.rentalIsOver def isDisabledInPremIGR(self): return self.isPresent() and self.item.isDisabledInPremIGR def isPremiumIGR(self): return self.isPresent() and self.item.isPremiumIGR def isInPrebattle(self): return self.isPresent() and self.item.isInPrebattle def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isOnlyForEventBattles(self): return self.item.isOnlyForEventBattles def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle() def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): return not self.isPresent() or self.item.isAutoLoadFull() def isAutoEquipFull(self): return not self.isPresent() or self.item.isAutoEquipFull() def isFalloutOnly(self): return self.isPresent() and self.item.isFalloutOnly() def selectVehicle(self, vehInvID=0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) return def selectNoVehicle(self): self.__selectVehicle(0) def getDossier(self): return g_itemsCache.items.getVehicleDossier(self.item.intCD) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() if state == Vehicle.VEHICLE_STATE.IN_PREMIUM_IGR_ONLY: rentLeftStr = getTimeLeftStr("#menu:vehicle/igrRentLeft/%s", self.item.rentInfo.timeLeft) icon = icons.premiumIgrBig() if self.item.isRented: message = i18n.makeString("#menu:currentVehicleStatus/" + state, icon=icon, time=rentLeftStr) else: message = i18n.makeString("#menu:tankCarousel/vehicleStates/inPremiumIgrOnly", icon=icon) return (state, message, stateLvl) return (state, "#menu:currentVehicleStatus/" + state, stateLvl) return ( Vehicle.VEHICLE_STATE.NOT_PRESENT, MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL, ) def getViewState(self): return createState4CurrentVehicle(self) def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show("updateCurrentVehicle", isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide("updateCurrentVehicle") def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None return def __checkPrebattleLockedVehicle(self): clientPrb = prb_getters.getClientPrebattle() if clientPrb is not None: rosters = prb_getters.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get("vehCompDescr", "") if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __onFalloutChanged(self): if self.isPresent() and (self.item.isOnlyForEventBattles or self.item.isFalloutAvailable): self.onChanged() def __repr__(self): return "CurrentVehicle(%s)" % str(self.item)
class AnonymizerController(IAnonymizerController): __lobbyContext = dependency.descriptor(ILobbyContext) __itemsCache = dependency.descriptor(IItemsCache) __slots__ = ('__isEnabled', '__isRestricted', '__isAnonymized', '__isInBattle', '__uploader') def __init__(self): self.onStateChanged = Event() self.__isEnabled = False self.__isRestricted = False self.__isAnonymized = False self.__isInBattle = False self.__uploader = ContactsUploader() def onConnected(self): self.__uploader.init() def onDisconnected(self): self.__uploader.fini() self.__clear() def onLobbyInited(self, _): self.__isInBattle = False self.__addListeners() self.__update() def onAvatarBecomePlayer(self): self.__removeListeners() self.__isInBattle = True def onAccountBecomeNonPlayer(self): if self.__uploader.isProcessing: _logger.info('contacts uploader stopping because of onAccountBecomeNonPlayer.') self.__uploader.stop() @property def isInBattle(self): return self.__isInBattle @property def isEnabled(self): return self.__isEnabled @property def isRestricted(self): return self.__isRestricted @property def isAnonymized(self): return self.__isEnabled and self.__isAnonymized def setAnonymized(self, value): if self.isEnabled and not self.isRestricted: if value != self.__isAnonymized: self.__isAnonymized = value BigWorld.player().anonymizer.setAnonymized(self.__isAnonymized, self.__onSetAnonymizedResponse) else: self.__pushChangeUnavailableMessage() def __addListeners(self): g_clientUpdateManager.addCallbacks({'cache.SPA': self.__onCacheSPAChanged, 'anonymizer.enabled': self.__onAnonymizedStateChanged, 'anonymizer.contactsFeedback': self.__onContactsFeedback}) self.__lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingsChanged def __removeListeners(self): self.__lobbyContext.getServerSettings().onServerSettingsChange -= self.__onServerSettingsChanged g_clientUpdateManager.removeObjectCallbacks(self) def __update(self): self.__isEnabled = self.__lobbyContext.getServerSettings().isAnonymizerEnabled() self.__isRestricted = self.__itemsCache.items.stats.isAnonymousRestricted self.__isAnonymized = self.__itemsCache.items.anonymizer.isPlayerAnonymized self.__processContacts() self.onStateChanged(enabled=self.isEnabled, restricted=self.isRestricted, anonymized=self.isAnonymized) def __clear(self): self.onStateChanged.clear() self.__removeListeners() self.__isEnabled = False self.__isRestricted = False self.__isAnonymized = False self.__isInBattle = False def __onServerSettingsChanged(self, *_): self.__isEnabled = self.__lobbyContext.getServerSettings().isAnonymizerEnabled() self.onStateChanged(enabled=self.isEnabled) def __onCacheSPAChanged(self, *_): self.__isRestricted = self.__itemsCache.items.stats.isAnonymousRestricted self.onStateChanged(restricted=self.isRestricted) def __onAnonymizedStateChanged(self, *_): self.__isAnonymized = self.__itemsCache.items.anonymizer.isPlayerAnonymized self.onStateChanged(anonymized=self.isAnonymized) def __onContactsFeedback(self, *_): self.__processContacts() def __processContacts(self): contactsFeedback = self.__itemsCache.items.anonymizer.contactsFeedback if contactsFeedback: arenaUniqueID, contactsBlob = self.__itemsCache.items.anonymizer.contactsFeedback[0] if self.__uploader.isProcessing: if self.__uploader.arenaUniqueID == arenaUniqueID: _logger.info('contacts uploader continue upload arenaID %s', arenaUniqueID) return self.__uploader.stop() self.__uploader.start(arenaUniqueID, contactsBlob) elif self.__uploader.isProcessing: self.__uploader.stop() def __onSetAnonymizedResponse(self, resultID, errorCode): if errorCode: self.__onAnonymizedStateChanged() self.__pushChangeUnavailableMessage() _logger.debug('setAnonymized response: %s', (resultID, errorCode)) @staticmethod def __pushChangeUnavailableMessage(): SystemMessages.pushMessage(backport.text(_RSettingsError.changeUnavailable.message()), SystemMessages.SM_TYPE.Warning)
class _CurrentVehicle(): def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.__historicalBattle = None self.onChanged = Event() self.onChangeStarted = Event() self.__crew = {} def init(self): g_clientUpdateManager.addCallbacks({ 'inventory': self.onInventoryUpdate, 'cache.vehsLock': self.onLocksUpdate }) game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged g_hangarSpace.removeVehicle() self.selectNoVehicle() def onIgrTypeChanged(self, *args): self.refreshModel() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']: isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() else: isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff[ 'repair'] isCustomizationChanged = 'igrCustomizationsLayout' in vehsDiff and self.__vehInvID in vehsDiff[ 'igrCustomizationsLayout'] isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = len( filter( lambda hive: self.__vehInvID in hive or (self.__vehInvID, '_r') in hive, vehsDiff.itervalues())) > 0 if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged: self.refreshModel() if isVehicleChanged or isRepaired: self.onChanged() if self.isPresent(): self.__updateViewRange() def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: if self.__historicalBattle is not None: historical = g_tankActiveCamouflage['historical'] if self.__historicalBattle.canParticipateWith( self.item.intCD) and self.item.intCD not in historical: historical[self.item. intCD] = self.__historicalBattle.getArenaType( ).vehicleCamouflageKind if self.item.intCD not in g_tankActiveCamouflage: availableKinds = [] currKind = 0 for id, startTime, days in self.item.descriptor.camouflages: if id is not None: availableKinds.append(currKind) currKind += 1 if len(availableKinds) > 0: g_tankActiveCamouflage[self.item.intCD] = random.choice( availableKinds) g_hangarSpace.updateVehicle(self.item, self.__historicalBattle) else: g_hangarSpace.removeVehicle() return @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): if self.isPresent() and self.item.isAutoLoad: for shell in self.item.shells: if shell.count != shell.defaultCount: return False return True def isAutoEquipFull(self): if self.isPresent() and self.item.isAutoEquip: for i, e in enumerate(self.item.eqsLayout): if e != self.item.eqs[i]: return False return True def selectVehicle(self, vehInvID=0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles( criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) def selectNoVehicle(self): self.__selectVehicle(0) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() return ('#menu:currentVehicleStatus/' + state, stateLvl) return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL) def setHistoricalBattle(self, historicalBattle): g_tankActiveCamouflage['historical'] = {} self.__historicalBattle = historicalBattle self.refreshModel() self.onChanged() def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show('updateCurrentVehicle', isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) if self.isPresent(): self.__updateViewRange() def __updateViewRange(self): # Set Defaults xvm_conf = {} saveConfig = False # Load configuration xvm_configuration_file = os.getcwd( ) + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc' if not os.path.exists(xvm_configuration_file): SystemMessages.pushMessage("Configuration file missing (" + xvm_configuration_file + ")", type=SystemMessages.SM_TYPE.Error) return else: try: data = "" blockComment = False f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"') for line in f.read().split('\n'): line = line.strip() if line != "": # Start of block comment comment = line.find("/*") if comment != -1 and comment == 0: blockComment = True continue # End of block comment comment = line.find("*/") if comment != -1: blockComment = False continue # Block Comment if blockComment == True: continue # Start of line comment comment = line.find("//") if comment != -1 and comment == 0: continue # Remove end of line comments position = 0 for i in range(0, line.count("//")): comment = line.find("//", position + 2) if comment != -1: colon = line.find(":") startSpeach = line.find("\"", colon + 1) if startSpeach > comment: line = line[:comment].strip() endSpeach = line.find("\"", startSpeach + 1) if comment > endSpeach: line = line[:comment].strip() position += comment if line != "": data += line + '\n' f.close() xvm_conf = json.loads(data) except Exception as e: SystemMessages.pushMessage("Parsing configuration file: " + str(e), type=SystemMessages.SM_TYPE.Error) return # Code for migrating old configuration files (v1.5->v1.6) if not xvm_conf["tankrange"].has_key("spotting_limit"): xvm_conf["tankrange"]["spotting_limit"] = True saveConfig = True # Code for migrating old configuration files (v1.7->v1.8) if not xvm_conf["tankrange"].has_key("notify_changes"): xvm_conf["tankrange"]["notify_changes"] = True saveConfig = True # Get name tank_name = g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.type.name.replace(":", "-") if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Tank Name: ", tank_name) # Only update when we have a crew if not self.isCrewFull(): if xvm_conf['tankrange']['logging']: LOG_NOTE('Crew is missing.') return # Remove current circles remaining = [] oldCircles = {} for tank_data in xvm_conf["circles"]["special"]: if tank_data.keys()[0] != tank_name: remaining.append(tank_data) elif tank_data[tank_name].has_key( 'distance') and tank_data[tank_name].has_key( '$ref') and tank_data[tank_name]['$ref'].has_key( 'path'): oldCircles[tank_data[tank_name]['$ref'] ['path']] = tank_data[tank_name]['distance'] xvm_conf["circles"]["special"] = remaining # Get type if xvm_conf["tankrange"][ "ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.type.tags: f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2))) f.close() if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Ignoring " + vehicle_type + " tank.") return # Get view distance view_distance = g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.turret["circularVisionRadius"] if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Base View Range: ", view_distance) # Check for Ventilation ventilation = self.__isOptionalEquipped("improvedVentilation") if xvm_conf["tankrange"]["logging"] and ventilation: LOG_NOTE("Ventilation Found") # Check for Consumable consumable = False if self.__isConsumableEquipped("ration"): consumable = True if self.__isConsumableEquipped("chocolate"): consumable = True if self.__isConsumableEquipped("cocacola"): consumable = True if self.__isConsumableEquipped("hotCoffee"): consumable = True if xvm_conf["tankrange"]["logging"] and consumable: LOG_NOTE("Premium Consumable Found") # Update crew self.__updateCrew() # Check for Brothers In Arms brothers_in_arms = True if len(self.__crew) == 0: brothers_in_arms = False else: for name, data in self.__crew.iteritems(): if "brotherhood" not in data["skill"]: brothers_in_arms = False elif data["skill"]["brotherhood"] != 100: brothers_in_arms = False if xvm_conf["tankrange"]["logging"] and brothers_in_arms: LOG_NOTE("BIA Found") # Calculate commander bonus commander_skill = 0.0 if "commander" in self.__crew: commander_skill = self.__crew["commander"]["level"] if brothers_in_arms == True: commander_skill += 5.0 if ventilation == True: commander_skill += 5.0 if consumable == True: commander_skill += 10.0 if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Commander Skill: ", commander_skill) # Calculate other bonuses other_bonus = 1.0 for name, data in self.__crew.iteritems(): # Calculate recon skills if "commander_eagleEye" in data["skill"]: other_bonus *= 1.0 + (0.0002 * data["skill"]["commander_eagleEye"]) if xvm_conf["tankrange"]["logging"]: LOG_NOTE( "Recon Bonus: ", 1.0 + (0.0002 * data["skill"]["commander_eagleEye"])) # Calculate Situational Awareness Skill if "radioman_finder" in data["skill"]: other_bonus *= 1.0 + (0.0003 * data["skill"]["radioman_finder"]) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Situational Awareness Bonus: ", 1.0 + (0.0003 * data["skill"]["radioman_finder"])) # Check for Binoculars binoculars = self.__isOptionalEquipped("stereoscope") if xvm_conf["tankrange"]["logging"] and binoculars: LOG_NOTE("Binoculars Found") # Check for Coated Optics coated_optics = self.__isOptionalEquipped("coatedOptics") if xvm_conf["tankrange"]["logging"] and coated_optics: LOG_NOTE("Coated Optics Found") # Calculate final value view_distance = ((view_distance / 0.875) * (0.00375 * commander_skill + 0.5)) * other_bonus if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Other Bonus:", other_bonus) LOG_NOTE("Final View Range: ", view_distance) # Add binocular Circles binocular_distance = None if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars: binocular_distance = view_distance * 1.25 if xvm_conf["tankrange"]["spotting_limit"]: binocular_distance = min(445, binocular_distance) if not xvm_conf["tankrange"]["circle_binocular"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "distance": binocular_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "thickness": (binocular_distance * 0.25) - 14, "distance": binocular_distance * 0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_binocular") or float( oldCircles["tankrange.circle_binocular"] ) != binocular_distance: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_binocular"): saveConfig = True # Add standard Circles if coated_optics == True: view_distance = min(view_distance * 1.1, 500) if xvm_conf["tankrange"]["circle_view"]["enabled"]: if xvm_conf["tankrange"]["spotting_limit"]: view_distance = min(445, view_distance) if not xvm_conf["tankrange"]["circle_view"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "distance": view_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "thickness": (view_distance * 0.25) - 14, "distance": view_distance * 0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_view") or float( oldCircles["tankrange.circle_view"]) != view_distance: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_view"): saveConfig = True # Add Artillery Range artillery_range = 0 if xvm_conf["tankrange"]["circle_artillery"][ "enabled"] and "SPG" in g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.type.tags: for shell in g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.gun["shots"]: artillery_range = max( artillery_range, round(math.pow(shell["speed"], 2) / shell["gravity"])) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Calculated Firing Range:", artillery_range) if not xvm_conf["tankrange"]["circle_artillery"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "distance": artillery_range } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "thickness": (artillery_range * 0.25) - 14, "distance": artillery_range * 0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_artillery") or float( oldCircles["tankrange.circle_artillery"] ) != artillery_range: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_artillery"): saveConfig = True # Add Artillery Range shell_range = 0 if xvm_conf["tankrange"]["circle_shell"]["enabled"]: for shell in g_itemsCache.items.getVehicle( self.__vehInvID).descriptor.gun["shots"]: shell_range = max(shell_range, shell["maxDistance"]) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Calculated Shell Range:", shell_range) if shell_range < 445: if not xvm_conf["tankrange"]["circle_shell"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "distance": shell_range } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "thickness": (shell_range * 0.25) - 14, "distance": shell_range * 0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_shell") or float( oldCircles["tankrange.circle_shell"]) != shell_range: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_shell"): saveConfig = True # Write result if saveConfig: f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write( unicode( json.dumps(xvm_conf, ensure_ascii=False, indent=2, sort_keys=True))) f.close() # notify changes if saveConfig and xvm_conf["tankrange"]["notify_changes"]: msg = "{0}: View Distance: {1}m".format( g_itemsCache.items.getVehicle(self.__vehInvID).userName, round(view_distance, 1)) if binocular_distance: msg += " + Binoculars: {0}m".format( round(binocular_distance, 1)) if artillery_range: msg += " Artillery Range: {0}m".format( round(artillery_range, 1)) if shell_range > 0 and shell_range < 445: msg += " Shell Range: {0}m".format(round(shell_range, 1)) SystemMessages.pushMessage(msg, type=SystemMessages.SM_TYPE.Information) @process def __updateCrew(self): from gui.shared.utils.requesters import Requester self.__crew.clear() barracks = yield Requester('tankman').getFromInventory() for tankman in barracks: for crewman in self.item.crew: if crewman[1] is not None and crewman[ 1].invID == tankman.inventoryId: factor = tankman.descriptor.efficiencyOnVehicle( g_itemsCache.items.getVehicle( self.__vehInvID).descriptor) crew_member = { "level": tankman.descriptor.roleLevel * factor[0], "skill": {} } skills = [] for skill_name in tankman.descriptor.skills: skills.append({"name": skill_name, "level": 100}) if len(skills) != 0: skills[-1]["level"] = tankman.descriptor.lastSkillLevel for skill in skills: crew_member["skill"][skill["name"]] = skill["level"] self.__crew[tankman.descriptor.role] = crew_member def __isOptionalEquipped(self, optional_name): for item in self.item.descriptor.optionalDevices: if item is not None and optional_name in item.name: return True return False def __isConsumableEquipped(self, consumable_name): from gui.shared.utils.requesters import VehicleItemsRequester for item in self.item.eqsLayout: if item is not None and consumable_name in item.descriptor.name: return True return False def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide('updateCurrentVehicle') def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None def __checkPrebattleLockedVehicle(self): clientPrb = prb_control.getClientPrebattle() if clientPrb is not None: rosters = prb_control.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get( 'vehCompDescr', '') if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD( vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __repr__(self): return 'CurrentVehicle(%s)' % str(self.item)
class _ClanCache(object): def __init__(self): self.__waitForSync = False self.__fortProvider = None self.__clanMembersLen = None self.__clanMotto = '' self.__clanDescription = '' self.onSyncStarted = Event() self.onSyncCompleted = Event() return def init(self): self.__fortProvider = ClientFortProvider() def fini(self): self.onSyncStarted.clear() self.onSyncCompleted.clear() self.clear() def onAccountShowGUI(self): self.__startFortProvider() def onAvatarBecomePlayer(self): self.__stopFortProvider() def onDisconnected(self): self.__stopFortProvider() @property def waitForSync(self): return self.__waitForSync @async def update(self, diff=None, callback=None): self.__invalidateData(diff, callback) def clear(self): self.__fortProvider = None return @storage_getter('users') def usersStorage(self): return None @property def fortProvider(self): return self.__fortProvider @property def clanDBID(self): from gui.shared import g_itemsCache return g_itemsCache.items.stats.clanDBID @property def isInClan(self): """ @return: is current player in clan """ return self.clanDBID is not None and self.clanDBID != 0 @property def clanMembers(self): members = set() if self.isInClan: members = set(self.usersStorage.getClanMembersIterator(False)) return members @property def clanInfo(self): from gui.shared import g_itemsCache info = g_itemsCache.items.stats.clanInfo if info and len(info) > 1: return info else: return (None, None, -1, 0, 0) @property def clanName(self): return passCensor(html.escape(self.clanInfo[0])) @property def clanAbbrev(self): return self.clanInfo[1] @property def clanMotto(self): return self.__clanMotto @property def clanDescription(self): return self.__clanDescription @property def clanTag(self): result = self.clanAbbrev if result: return '[%s]' % result return result @property def clanCommanderName(self): for member in self.clanMembers: if member.getClanRole() == CLAN_MEMBER_FLAGS.LEADER: return member.getName() return None @property def clanRole(self): user = self.usersStorage.getUser(getAccountDatabaseID()) if user: role = user.getClanRole() else: role = 0 return role @property def isClanLeader(self): return self.clanRole == CLAN_MEMBER_FLAGS.LEADER @async @process def getClanEmblemID(self, callback): clanEmblem = None if self.isInClan: tID = 'clanInfo' + BigWorld.player().name clanEmblem = yield self.getClanEmblemTextureID( self.clanDBID, False, tID) callback(clanEmblem) return @async def getFileFromServer(self, clanId, fileType, callback): if not BigWorld.player().serverSettings['file_server'].has_key( fileType): LOG_ERROR("Invalid server's file type: %s" % fileType) self._valueResponse(0, (None, None), callback) return None else: clan_emblems = BigWorld.player( ).serverSettings['file_server'][fileType] BigWorld.player().customFilesCache.get( clan_emblems['url_template'] % clanId, lambda url, file: self._valueResponse(0, (url, file), callback), True) return None @async @process def getClanEmblemTextureID(self, clanDBID, isBig, textureID, callback): import imghdr if clanDBID is not None and clanDBID != 0: _, clanEmblemFile = yield self.getFileFromServer( clanDBID, 'clan_emblems_small' if not isBig else 'clan_emblems_big') if clanEmblemFile and imghdr.what(None, clanEmblemFile) is not None: BigWorld.wg_addTempScaleformTexture(textureID, clanEmblemFile) callback(textureID) return callback(None) return def getClanRoleUserString(self): position = self.clanInfo[3] return getClanRoleString(position) def onClanInfoReceived(self, clanDBID, clanName, clanAbbrev, clanMotto, clanDescription): self.__clanMotto = passCensor(html.escape(clanMotto)) self.__clanDescription = passCensor(html.escape(clanDescription)) def _valueResponse(self, resID, value, callback): if resID < 0: LOG_ERROR( '[class %s] There is error while getting data from cache: %s[%d]' % (self.__class__.__name__, code2str(resID), resID)) return callback(value) callback(value) def _onResync(self): if not self.__waitForSync: self.__invalidateData() def __invalidateData(self, diff=None, callback=lambda *args: None): if diff is not None: if 'stats' in diff and 'clanInfo' in diff['stats']: self.__fortProvider.resetState() callback(True) return def __startFortProvider(self): self.__clanMembersLen = len(self.clanMembers) g_messengerEvents.users.onClanMembersListChanged += self.__me_onClanMembersListChanged self.__fortProvider.start(self) def __stopFortProvider(self): self.__clanMembersLen = None g_messengerEvents.users.onClanMembersListChanged -= self.__me_onClanMembersListChanged self.__fortProvider.stop() return def __me_onClanMembersListChanged(self): clanMembersLen = len(self.clanMembers) if self.__clanMembersLen is not None and clanMembersLen != self.__clanMembersLen: self.__clanMembersLen = clanMembersLen self.__fortProvider.resetState() self.__fortProvider.notify('onClanMembersListChanged') return
class _CurrentVehicle(): def __init__(self): self.__vehInvID = 0 self.__changeCallbackID = None self.__historicalBattle = None self.onChanged = Event() self.onChangeStarted = Event() self.__crew = {} def init(self): g_clientUpdateManager.addCallbacks({ 'inventory': self.onInventoryUpdate, 'cache.vehsLock': self.onLocksUpdate }) game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged prbVehicle = self.__checkPrebattleLockedVehicle() storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE) self.selectVehicle(prbVehicle or storedVehInvID) def destroy(self): self.__vehInvID = 0 self.__clearChangeCallback() self.onChanged.clear() self.onChangeStarted.clear() g_clientUpdateManager.removeObjectCallbacks(self) game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged g_hangarSpace.removeVehicle() self.selectNoVehicle() def onIgrTypeChanged(self, *args): self.refreshModel() def onInventoryUpdate(self, invDiff): vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {}) isVehicleSold = False isVehicleDescrChanged = False if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']: isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None isVehicleDescrChanged = not isVehicleSold if isVehicleSold or self.__vehInvID == 0: self.selectVehicle() else: isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff['repair'] isCustomizationChanged = 'igrCustomizationsLayout' in vehsDiff and self.__vehInvID in vehsDiff['igrCustomizationsLayout'] isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive or (self.__vehInvID, '_r') in hive, vehsDiff.itervalues())) > 0 if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged: self.refreshModel() if isVehicleChanged or isRepaired: self.onChanged() if self.isPresent(): self.__updateViewRange() def onLocksUpdate(self, locksDiff): if self.__vehInvID in locksDiff: self.refreshModel() def refreshModel(self): if self.isPresent() and self.isInHangar() and self.item.modelState: if self.__historicalBattle is not None: historical = g_tankActiveCamouflage['historical'] if self.__historicalBattle.canParticipateWith(self.item.intCD) and self.item.intCD not in historical: historical[self.item.intCD] = self.__historicalBattle.getArenaType().vehicleCamouflageKind if self.item.intCD not in g_tankActiveCamouflage: availableKinds = [] currKind = 0 for id, startTime, days in self.item.descriptor.camouflages: if id is not None: availableKinds.append(currKind) currKind += 1 if len(availableKinds) > 0: g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds) g_hangarSpace.updateVehicle(self.item, self.__historicalBattle) else: g_hangarSpace.removeVehicle() return @property def invID(self): return self.__vehInvID @property def item(self): if self.__vehInvID > 0: return g_itemsCache.items.getVehicle(self.__vehInvID) else: return None def isPresent(self): return self.item is not None def isBroken(self): return self.isPresent() and self.item.isBroken def isDisabledInRoaming(self): return self.isPresent() and self.item.isDisabledInRoaming def isLocked(self): return self.isPresent() and self.item.isLocked def isClanLock(self): return self.isPresent() and self.item.clanLock > 0 def isCrewFull(self): return self.isPresent() and self.item.isCrewFull def isInBattle(self): return self.isPresent() and self.item.isInBattle def isInHangar(self): return self.isPresent() and not self.item.isInBattle def isAwaitingBattle(self): return self.isPresent() and self.item.isAwaitingBattle def isAlive(self): return self.isPresent() and self.item.isAlive def isReadyToPrebattle(self): return self.isPresent() and self.item.isReadyToPrebattle def isReadyToFight(self): return self.isPresent() and self.item.isReadyToFight def isAutoLoadFull(self): if self.isPresent() and self.item.isAutoLoad: for shell in self.item.shells: if shell.count != shell.defaultCount: return False return True def isAutoEquipFull(self): if self.isPresent() and self.item.isAutoEquip: for i, e in enumerate(self.item.eqsLayout): if e != self.item.eqs[i]: return False return True def selectVehicle(self, vehInvID = 0): vehicle = g_itemsCache.items.getVehicle(vehInvID) if vehicle is None: invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY) if len(invVehs): vehInvID = sorted(invVehs.itervalues())[0].invID else: vehInvID = 0 self.__selectVehicle(vehInvID) def selectNoVehicle(self): self.__selectVehicle(0) def getHangarMessage(self): if self.isPresent(): state, stateLvl = self.item.getState() return ('#menu:currentVehicleStatus/' + state, stateLvl) return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL) def setHistoricalBattle(self, historicalBattle): g_tankActiveCamouflage['historical'] = {} self.__historicalBattle = historicalBattle self.refreshModel() self.onChanged() def __selectVehicle(self, vehInvID): if vehInvID == self.__vehInvID: return Waiting.show('updateCurrentVehicle', isSingle=True) self.onChangeStarted() self.__vehInvID = vehInvID AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID) self.refreshModel() if not self.__changeCallbackID: self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone) if self.isPresent(): self.__updateViewRange() def __updateViewRange(self): # Set Defaults xvm_conf = {} saveConfig = False # Load configuration xvm_configuration_file = os.getcwd() + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc' if not os.path.exists(xvm_configuration_file): SystemMessages.pushMessage("Configuration file missing (" + xvm_configuration_file + ")", type=SystemMessages.SM_TYPE.Error) return else: try: data = "" blockComment = False f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"') for line in f.read().split('\n'): line = line.strip() if line != "": # Start of block comment comment = line.find("/*") if comment != -1 and comment == 0: blockComment = True continue # End of block comment comment = line.find("*/") if comment != -1: blockComment = False continue # Block Comment if blockComment == True: continue # Start of line comment comment = line.find("//") if comment != -1 and comment == 0: continue # Remove end of line comments position = 0 for i in range(0,line.count("//")): comment = line.find("//", position+2) if comment != -1: colon = line.find(":") startSpeach = line.find("\"", colon+1) if startSpeach > comment: line = line[:comment].strip() endSpeach = line.find("\"", startSpeach+1) if comment > endSpeach: line = line[:comment].strip() position += comment if line != "": data += line + '\n' f.close() xvm_conf = json.loads(data) except Exception as e: SystemMessages.pushMessage("Parsing configuration file: " + str(e), type=SystemMessages.SM_TYPE.Error) return # Code for migrating old configuration files (v1.5->v1.6) if not xvm_conf["tankrange"].has_key("spotting_limit"): xvm_conf["tankrange"]["spotting_limit"] = True saveConfig = True # Code for migrating old configuration files (v1.7->v1.8) if not xvm_conf["tankrange"].has_key("notify_changes"): xvm_conf["tankrange"]["notify_changes"] = True saveConfig = True # Get name tank_name = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.name.replace(":","-") if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Tank Name: ", tank_name) # Only update when we have a crew if not self.isCrewFull(): if xvm_conf['tankrange']['logging']: LOG_NOTE('Crew is missing.') return # Remove current circles remaining = [] oldCircles = {} for tank_data in xvm_conf["circles"]["special"]: if tank_data.keys()[0] != tank_name: remaining.append(tank_data) elif tank_data[tank_name].has_key('distance') and tank_data[tank_name].has_key('$ref') and tank_data[tank_name]['$ref'].has_key('path'): oldCircles[tank_data[tank_name]['$ref']['path']] = tank_data[tank_name]['distance'] xvm_conf["circles"]["special"] = remaining # Get type if xvm_conf["tankrange"]["ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags: f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2))) f.close() if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Ignoring " + vehicle_type + " tank.") return # Get view distance view_distance = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.turret["circularVisionRadius"] if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Base View Range: ", view_distance) # Check for Ventilation ventilation = self.__isOptionalEquipped("improvedVentilation") if xvm_conf["tankrange"]["logging"] and ventilation: LOG_NOTE("Ventilation Found") # Check for Consumable consumable = False if self.__isConsumableEquipped("ration"): consumable = True if self.__isConsumableEquipped("chocolate"): consumable = True if self.__isConsumableEquipped("cocacola"): consumable = True if self.__isConsumableEquipped("hotCoffee"): consumable = True if xvm_conf["tankrange"]["logging"] and consumable: LOG_NOTE("Premium Consumable Found") # Update crew self.__updateCrew() # Check for Brothers In Arms brothers_in_arms = True if len(self.__crew) == 0: brothers_in_arms = False else: for name, data in self.__crew.iteritems(): if "brotherhood" not in data["skill"]: brothers_in_arms = False elif data["skill"]["brotherhood"] != 100: brothers_in_arms = False if xvm_conf["tankrange"]["logging"] and brothers_in_arms: LOG_NOTE("BIA Found") # Calculate commander bonus commander_skill = 0.0 if "commander" in self.__crew: commander_skill = self.__crew["commander"]["level"] if brothers_in_arms == True: commander_skill += 5.0 if ventilation == True: commander_skill += 5.0 if consumable == True: commander_skill += 10.0 if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Commander Skill: ", commander_skill) # Calculate other bonuses other_bonus = 1.0 for name, data in self.__crew.iteritems(): # Calculate recon skills if "commander_eagleEye" in data["skill"]: other_bonus *= 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] ) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Recon Bonus: ", 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] )) # Calculate Situational Awareness Skill if "radioman_finder" in data["skill"]: other_bonus *= 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] ) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Situational Awareness Bonus: ", 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] )) # Check for Binoculars binoculars = self.__isOptionalEquipped("stereoscope") if xvm_conf["tankrange"]["logging"] and binoculars: LOG_NOTE("Binoculars Found") # Check for Coated Optics coated_optics = self.__isOptionalEquipped("coatedOptics") if xvm_conf["tankrange"]["logging"] and coated_optics: LOG_NOTE("Coated Optics Found") # Calculate final value view_distance = ((view_distance / 0.875) * (0.00375 * commander_skill + 0.5)) * other_bonus if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Other Bonus:", other_bonus) LOG_NOTE("Final View Range: ", view_distance) # Add binocular Circles binocular_distance = None if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars: binocular_distance = view_distance * 1.25 if xvm_conf["tankrange"]["spotting_limit"]: binocular_distance = min(445, binocular_distance); if not xvm_conf["tankrange"]["circle_binocular"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "distance": binocular_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "thickness": (binocular_distance*0.25)-14, "distance": binocular_distance*0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_binocular") or float(oldCircles["tankrange.circle_binocular"]) != binocular_distance: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_binocular"): saveConfig = True # Add standard Circles if coated_optics == True: view_distance = min(view_distance * 1.1, 500) if xvm_conf["tankrange"]["circle_view"]["enabled"]: if xvm_conf["tankrange"]["spotting_limit"]: view_distance = min(445, view_distance); if not xvm_conf["tankrange"]["circle_view"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "distance": view_distance } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "thickness": (view_distance*0.25)-14, "distance": view_distance*0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_view") or float(oldCircles["tankrange.circle_view"]) != view_distance: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_view"): saveConfig = True # Add Artillery Range artillery_range = 0 if xvm_conf["tankrange"]["circle_artillery"]["enabled"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags: for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]: artillery_range = max(artillery_range, round(math.pow(shell["speed"],2) / shell["gravity"])) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Calculated Firing Range:", artillery_range) if not xvm_conf["tankrange"]["circle_artillery"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "distance": artillery_range } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "thickness": (artillery_range*0.25)-14, "distance": artillery_range*0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_artillery") or float(oldCircles["tankrange.circle_artillery"]) != artillery_range: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_artillery"): saveConfig = True # Add Artillery Range shell_range = 0 if xvm_conf["tankrange"]["circle_shell"]["enabled"]: for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]: shell_range = max(shell_range, shell["maxDistance"]) if xvm_conf["tankrange"]["logging"]: LOG_NOTE("Calculated Shell Range:", shell_range) if shell_range < 445: if not xvm_conf["tankrange"]["circle_shell"]["filled"]: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "distance": shell_range } }) else: xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "thickness": (shell_range*0.25)-14, "distance": shell_range*0.5 } }) # store only when changes if not oldCircles.has_key("tankrange.circle_shell") or float(oldCircles["tankrange.circle_shell"]) != shell_range: saveConfig = True # Remove old circles elif oldCircles.has_key("tankrange.circle_shell"): saveConfig = True # Write result if saveConfig: f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"') f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2, sort_keys=True))) f.close() # notify changes if saveConfig and xvm_conf["tankrange"]["notify_changes"]: msg = "{0}: View Distance: {1}m".format(g_itemsCache.items.getVehicle(self.__vehInvID).userName, round(view_distance,1) ) if binocular_distance: msg += " + Binoculars: {0}m".format( round(binocular_distance,1) ) if artillery_range: msg += " Artillery Range: {0}m".format( round(artillery_range,1) ) if shell_range > 0 and shell_range < 445: msg += " Shell Range: {0}m".format( round(shell_range,1) ) SystemMessages.pushMessage(msg, type=SystemMessages.SM_TYPE.Information) @process def __updateCrew(self): from gui.shared.utils.requesters import Requester self.__crew.clear() barracks = yield Requester('tankman').getFromInventory() for tankman in barracks: for crewman in self.item.crew: if crewman[1] is not None and crewman[1].invID == tankman.inventoryId: factor = tankman.descriptor.efficiencyOnVehicle(g_itemsCache.items.getVehicle(self.__vehInvID).descriptor) crew_member = { "level": tankman.descriptor.roleLevel * factor[0], "skill": {} } skills = [] for skill_name in tankman.descriptor.skills: skills.append({ "name": skill_name, "level": 100 }) if len(skills) != 0: skills[-1]["level"] = tankman.descriptor.lastSkillLevel for skill in skills: crew_member["skill"][skill["name"]] = skill["level"] self.__crew[tankman.descriptor.role] = crew_member def __isOptionalEquipped(self, optional_name): for item in self.item.descriptor.optionalDevices: if item is not None and optional_name in item.name: return True return False def __isConsumableEquipped(self, consumable_name): from gui.shared.utils.requesters import VehicleItemsRequester for item in self.item.eqsLayout: if item is not None and consumable_name in item.descriptor.name: return True return False def __changeDone(self): self.__clearChangeCallback() if isPlayerAccount(): self.onChanged() Waiting.hide('updateCurrentVehicle') def __clearChangeCallback(self): if self.__changeCallbackID is not None: BigWorld.cancelCallback(self.__changeCallbackID) self.__changeCallbackID = None def __checkPrebattleLockedVehicle(self): clientPrb = prb_control.getClientPrebattle() if clientPrb is not None: rosters = prb_control.getPrebattleRosters(prebattle=clientPrb) for rId, roster in rosters.iteritems(): if BigWorld.player().id in roster: vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '') if len(vehCompDescr): vehDescr = vehicles.VehicleDescr(vehCompDescr) vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr) if vehicle is not None: return vehicle.invID return 0 def __repr__(self): return 'CurrentVehicle(%s)' % str(self.item)