def __init__(self, owner, consumables, equipment, crewSkills): AvatarControllerBase.__init__(self, owner) self.__skillConditions = SkillConditions(owner, SKILL_EVENT) self.__objects = { OBJ_GROUPS.CREW: [ CrewSkills(owner, obj, self.__skillConditions, index) for index, obj in enumerate(crewSkills) ], OBJ_GROUPS.CONSUMABLES: [ConsumableEquipmentFeaturedObject(obj) for obj in consumables], OBJ_GROUPS.EQUIPMENT: [ EquipmentFeaturedObject(obj, getCrewSkillsID(crewSkills)) for obj in equipment ], OBJ_GROUPS.CAMOUFLAGE: [ CamouflageFeatureObject(owner.camouflageBonusSchemeName, owner.isCamouflageSpecializedForCurMap) ] } self.__specializationIdToObj = {} for crewMember in self.__objects[OBJ_GROUPS.CREW]: self.__specializationIdToObj[ crewMember.specializationID] = crewMember self.eModifiersChanged = Event.Event() self.modifiers = Modifiers() readyToUseSubscriptions = ( EventSubscription(c.eReadyToUse, self._onConsumableReadyToUse) for c in self.__objects[OBJ_GROUPS.CONSUMABLES]) self._subscription = CompositeSubscription(*readyToUseSubscriptions) if IS_CELLAPP: self._subscription.extend( EventSubscription(self._owner.eDestruction, self.onOwnerDeath)) self._subscription.subscribe()
def _update(self, gameResult, winState): playerTeamIndex = self._player.teamIndex enemyTeamIndex = 1 - self._player.teamIndex logger.debug('RESULT::::: {0}'.format(gameResult)) if gameResult in GAME_RESULT_LOC_IDS: resIndex = 2 if winState == 2 else int(playerTeamIndex != winState) reason = GAME_RESULT_LOC_IDS[gameResult][resIndex] self._model.reason = reason logger.debug('Update: {0}, {1}, {2}, {3}'.format( gameResult, winState, playerTeamIndex, reason)) self._model.winnerTeamIndex = winState self._updateBattleTime() scoreGlobal = self._clientArena.gameMode.scoreGlobal self._model.allyPoints = scoreGlobal[playerTeamIndex] self._model.enemyPoints = scoreGlobal[enemyTeamIndex] self._updatePlayerTeamRate() self._updatePlayerEconomics() if not self._updateRateSubscription: self._updateRateSubscription = CompositeSubscription( EventSubscription(self._clientArena.onEconomicEvents, self._updatePlayerTeamRate), EventSubscription(self._clientArena.onEconomicPlayersPoints, self._updatePlayerTeamRate)) self._updateRateSubscription.subscribe() self._updateBestRankData()
def __init__(self, clientArena): super(ACGameModeClient, self).__init__(clientArena) self._scoreGlobal = (0, 0) self._globalCounters = {} self._sectors = {} self._currentTick = 0 self._currentTickStartedAt = self.player.arenaStartTime self._globalTime = 0 self._dynamicTime = 0 self._isReady = False self._eManager = EventManager() self.eGameModeReady = Event(self._eManager) self._rocketV2Manager = RocketV2Manager.RocketV2Manager(self) self._signalFlaresManager = SignalFlaresManager.SignalFlaresManager( self) self._waveInfoManager = WaveInfoManager(self) self._lastPlayerManager = LastPlayerManager(self) self._pendingEvents = [] self.createSectorsData() self.registerArenaUpdateEvents(self.updateEventsMap) gameActionsManager = self.clientArena.gameActionsManager self._subscription = CompositeSubscription( EventSubscription(gameActionsManager.eWaveAdded, self._onASWaveAdded), EventSubscription(gameActionsManager.eWaveRemoved, self._onASWaveRemoved), EventSubscription(gameActionsManager.eWaveStateChanged, self._onASWaveStateChanged), EventSubscription(gameActionsManager.eBomberStateChanged, self._onASBomberStateChanged)) self._subscription.subscribe()
def __init__(self, features): self._logger = BWLogging.getLogger(self.__class__.__name__) self._model = features.require( Feature.GAME_MODEL).domination.sectorsGameEffects self._clientArena = features.require(Feature.CLIENT_ARENA) self._db = features.require(Feature.DB_LOGIC) self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._gameMode = self._clientArena.gameMode self._disableBomberCallbacks = {} self._subscription = CompositeSubscription( EDSubscription(self.gameMode, AC_EVENTS.BOMBERS_LAUNCHED, self._onBombersLaunched), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_ATTACK_NOTIFIED, self._onBomberAttackNotified), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_BOMBS_DROPPED, self._onBomberBombsDropped), EDSubscription(self.gameMode, AC_EVENTS.BOMBERS_DIED, self._onBombersDied), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_IN_WAVE_DIED, self._onBomberInWaveDied), EDSubscription(self.gameMode.rocketV2Manager, AC_EVENTS.ROCKET_V2_EFFECT_STARTED, self._onRocketEffectStarted), EDSubscription(self.gameMode.rocketV2Manager, AC_EVENTS.ROCKET_V2_EFFECT_ENDED, self._onRocketEffectEnded), EventSubscription(self._clientArena.onReceiveMarkerMessage, self._onReceiveMarkerMessage)) self.gameMode.addEventHandler( AC_EVENTS.ROCKET_V2_TARGET_SECTOR_CHANGED, self._onRocketEffectSectorChanged) if self.gameMode.isReady: self._setupModel() else: self.gameMode.eGameModeReady += self._setupModel
def _subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updateAvatarPlaneTypeRank), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updatePlaneScoresData), EventSubscription( self._clientArena.onPlayerEconomicExtDataReceived, self._updatePlaneScoresData), EventSubscription(self._clientArena.onAvatarChangedPlane, self._updateAvatarPlaneTypeRank), EventSubscription(self._clientArena.onAvatarEnterWorld, self._onAvatarEnterWorld), EventSubscription(self._clientArena.onAvatarLeaveWorld, self._onAvatarLeaveWorld), EventSubscription(self._clientArena.onEconomicPlayersPoints, self._onPlayersPoints), EventSubscription(self._clientArena.onUpdatePlayerStats, self._onUpdatePlayerStats)) self._subscription.subscribe() if self._clientArena.isAllServerDataReceived(): self._onNewAvatarsInfo(None) else: self._clientArena.onNewAvatarsInfo += self._onNewAvatarsInfo return
class BattleLogSource(DataSource): """ @type _model: gui.HUD2.features.battleEvent.BattleLogModel.BattleLogModel @type _economics: clientEconomics.ClientEconomic.ClientEconomic @type _player: PlayerAvatar.PlayerAvatar """ def __init__(self, features): self._model = features.require(Feature.GAME_MODEL).battlePoints self._economics = features.require(Feature.CLIENT_ECONOMICS) self._player = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._subscription = CompositeSubscription( EventSubscription(self._player.eAchievementUnlocked, self._onAchievementUnlocked), EventSubscription(self._player.eQuestCompleted, self._onQuestCompleted), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._onPlayerPlaneTypeRankUpdated)) self._subscription.subscribe() self._economics.assignModelView(self) def dispose(self): self._subscription.unsubscribe() self._subscription = None self._economics.assignModelView(None) self._economics = None self._model = None self._player = None return def refresh(self, totalPoints, totalExp, newEvents): """ @param totalPoints: int @param newEvents: list() look ClientEconomics.onEconomicEvents() for parameters of each event """ from debug_utils import LOG_DEBUG LOG_DEBUG( 'ECOVIEW: BattleLogSource: new events {0}, bp {1}, mp {2}'.format( len(newEvents), totalPoints, totalExp)) for event in newEvents: self._model.battleEvent = event self._model.totalPoints = totalPoints self._model.totalExp = totalExp def _onQuestCompleted(self, questID): e = createQuestCompletedEventModel(questID) self._model.battleEvent = e def _onAchievementUnlocked(self, achievementID): e = createAchievementUnlockedEventModel(achievementID) self._model.battleEvent = e def _onPlayerPlaneTypeRankUpdated(self, avatarID, planeType, oldRankID, rankID, *args, **kwargs): if avatarID == self._player.id and planeType == self._player.planeType: e = createRankGainedEventModel(rankID) self._model.battleEvent = e
def _subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._gameEnvironment.eAvatarHealthChange, self._onAvatarHealthChanged), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_LAUNCHED, self._onACBombersWaveLaunched), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_DIED, self._onACBombersWaveDied), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_ATTACK_STARTED, self._onACBombersAttackStarted)) self._subscription.subscribe()
def __subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._playerAvatar.eUpdateHealth, self._onUpdateHealth), EventSubscription(self._playerAvatar.onStateChanged, self._onStateChanged), EventSubscription(self._playerAvatar.eTacticalRespawnEnd, self._fillPlaneData), EventSubscription(self._gameEnv.ePlayerGunnerChangedTurret, self._updateModelShootingDistance)) self._subscription.subscribe()
def __init__(self, features): self._model = features.require(Feature.GAME_MODEL).battlePoints self._economics = features.require(Feature.CLIENT_ECONOMICS) self._player = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._subscription = CompositeSubscription( EventSubscription(self._player.eAchievementUnlocked, self._onAchievementUnlocked), EventSubscription(self._player.eQuestCompleted, self._onQuestCompleted), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._onPlayerPlaneTypeRankUpdated)) self._subscription.subscribe() self._economics.assignModelView(self)
class GameActionsManagerProxy(object): def __init__(self): self._entity = None self._subscription = None self._eManager = EventManager() self.eWaveAdded = Event(self._eManager) self.eWaveRemoved = Event(self._eManager) self.eWaveStateChanged = Event(self._eManager) self.eBomberStateChanged = Event(self._eManager) return @property def activeASWaves(self): if self._entity: return self._entity.activeASWaves return [] def onManagerEnterWorld(self, entity): raise not self._entity or AssertionError('Attempt to override registered manager, old = {0}, new = {1}'.format(self._entity, entity)) self._entity = entity self._subscribeOn(entity) def onManagerLeaveWorld(self, entity): raise self._entity is entity or AssertionError('Attempt to unregister unknown manager: {0}, registered: {1}'.format(entity, self._entity)) self._unsubscribe() self._entity = None return def cleanup(self): self._eManager.clear() def _subscribeOn(self, entity): raise self._subscription is None or AssertionError('Attempt to override subscription') self._subscription = CompositeSubscription(EventSubscription(entity.eWaveAdded, self.eWaveAdded), EventSubscription(entity.eWaveRemoved, self.eWaveRemoved), EventSubscription(entity.eWaveStateChanged, self.eWaveStateChanged), EventSubscription(entity.eBomberStateChanged, self.eBomberStateChanged)) self._subscription.subscribe() return def _unsubscribe(self): raise self._subscription or AssertionError('Subscription is None') self._subscription.unsubscribe() self._subscription = None return
def __init__(self, features): self._model = features.require(Feature.GAME_MODEL).classTasks self._player = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) coachMgr = self._player.coachManager self._subscription = CompositeSubscription( EventSubscription(coachMgr.eObjectivesChanged, self._updateCurrentObjectives), EventSubscription(coachMgr.eObjectiveProgressChanged, self._updateObjectiveProgress), EventSubscription(coachMgr.eObjectiveProgressRawValueChanged, self._updateObjectiveRawProgressValue), EventSubscription(self._player.eTacticalRespawnEnd, self._updateCurrentObjectives)) self._subscription.subscribe() if self._clientArena.isAllServerDataReceived(): self._setupModel(None) else: self._clientArena.onNewAvatarsInfo += self._setupModel logger.debug('Plane type objectives data source initialized') return
def __init__(self, features): self._db = features.require(Feature.DB_LOGIC) self._bigWorld = features.require(Feature.BIG_WORLD) self._model = features.require(Feature.GAME_MODEL).currentPlayerInfo self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._planesConfigurationsDB = features.require( Feature.PLANES_CONFIGURATIONS_DB) self._subscription = CompositeSubscription( EventSubscription(self._playerAvatar.onStateChanged, self._onStateChanged), EventSubscription(self._playerAvatar.eTacticalRespawnEnd, self._fillPlaneData), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._onAvatarPlaneTypeRankChanged), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updatePlaneScoresData), EventSubscription( self._clientArena.onPlayerEconomicExtDataReceived, self._updatePlaneScoresData)) self._subscription.subscribe() self._fellModel()
class PlayerInfoSource(DataSource): def __init__(self, features): self._db = features.require(Feature.DB_LOGIC) self._bigWorld = features.require(Feature.BIG_WORLD) self._model = features.require(Feature.GAME_MODEL).currentPlayerInfo self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._planesConfigurationsDB = features.require( Feature.PLANES_CONFIGURATIONS_DB) self._subscription = CompositeSubscription( EventSubscription(self._playerAvatar.onStateChanged, self._onStateChanged), EventSubscription(self._playerAvatar.eTacticalRespawnEnd, self._fillPlaneData), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._onAvatarPlaneTypeRankChanged), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updatePlaneScoresData), EventSubscription( self._clientArena.onPlayerEconomicExtDataReceived, self._updatePlaneScoresData)) self._subscription.subscribe() self._fellModel() def _fellModel(self, *args, **kwargs): if self._clientArena.isAllServerDataReceived(): self._setupModel(None) else: self._clientArena.onNewAvatarsInfo += self._setupModel self._fillPlaneData() return def _fillPlaneData(self, *args, **kwargs): avatarInfo = self._clientArena.getAvatarInfo(self._playerAvatar.id) settings = avatarInfo['settings'] self._model.planeName = localizeAirplane(settings.airplane.name) self._model.planeLevel = settings.airplane.level self._model.planeGlobalID = self._playerAvatar.globalID self._model.id = self._playerAvatar.id self._model.planeType = settings.airplane.planeType self._model.teamIndex = self._playerAvatar.teamIndex if self._clientArena.isAllServerDataReceived(): self._updatePlaneTypeRank() def _setupModel(self, newInfos): avatarInfo = self._clientArena.getAvatarInfo(self._playerAvatar.id) self._model.clanName = unicode(avatarInfo.get('clanAbbrev', '')) self._model.nickName = unicode( avatarInfo.get('playerName', 'unknown name')) self._model.squadIndex = avatarInfo.get('squadID', 0) self._model.state = getLogicState(avatarInfo) self._updatePlaneTypeRank() self._updatePlayerPlaneScoresData() def _onStateChanged(self, oldState, state): avatarInfo = self._clientArena.getAvatarInfo(self._playerAvatar.id) self._model.state = getLogicState(avatarInfo) def _onAvatarPlaneTypeRankChanged(self, avatarID, *args, **kwargs): if avatarID == self._bigWorld.player().id: self._updatePlaneTypeRank() def _updatePlaneTypeRank(self): id_ = self._bigWorld.player().id avatarInfo = self._clientArena.avatarInfos[id_] settings = avatarInfo['settings'] planeType = settings.airplane.planeType self._model.rank = avatarInfo['planeTypeRank'][planeType] def _updatePlaneScoresData(self, avatarID, *args, **kwargs): """Update score data for all avatar planes. Is called when avatar rank is changed and when new battle points received from server """ if avatarID == self._bigWorld.player().id: self._updatePlayerPlaneScoresData() def _updatePlayerPlaneScoresData(self): avatarInfo = self._clientArena.avatarInfos[self._bigWorld.player().id] economics = avatarInfo['economics'] planeTypeRanks = avatarInfo['planeTypeRank'] pointsByPlanes = economics['pointsByPlanes'] if not pointsByPlanes: globalID = avatarInfo['airplaneInfo']['globalID'] planeID = self._planesConfigurationsDB.getAirplaneConfiguration( globalID).planeID pointsByPlanes = [(planeID, 0)] for planeID, battlePoints in pointsByPlanes: planeData = self._db.getAircraftData(planeID) planeType = planeData.airplane.planeType scoreItem = self._model.planeScoresData.first( lambda e: e.planeID.get() == planeID) if scoreItem: scoreItem.battlePoints = battlePoints scoreItem.rankID = planeTypeRanks[planeType] else: self._model.planeScoresData.append( planeID=planeID, planeType=planeType, planeName=localizeAirplane(planeData.airplane.name), battlePoints=battlePoints, rankID=planeTypeRanks[planeType]) def dispose(self): self._subscription.unsubscribe() self._subscription = None self._clientArena.onNewAvatarsInfo -= self._setupModel self._playerAvatar = None self._clientArena = None self._model = None return
class PlayerSource(DataSource): def __init__(self, features): self._db = features.require(Feature.DB_LOGIC) self._model = features.require(Feature.GAME_MODEL).player self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._gameEnv = features.require(Feature.GAME_ENVIRONMENT) self._input = features.require(Feature.INPUT) self._playerAvatar.eTacticalSpectator += self._reFillModel self._input.eBattleModeChange += self._onSetBattleMod self._battleMod = BATTLE_MODE.COMBAT_MODE self._log = getLogger(self) self._fellModel() def _fellModel(self): if self._clientArena.isAllServerDataReceived(): self._setupModel(None) else: self._clientArena.onNewAvatarsInfo += self._setupModel self._fillPlaneData() return def _reFillModel(self, *args, **kwargs): self._setupModel(None) self._fillPlaneData() return def __subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._playerAvatar.eUpdateHealth, self._onUpdateHealth), EventSubscription(self._playerAvatar.onStateChanged, self._onStateChanged), EventSubscription(self._playerAvatar.eTacticalRespawnEnd, self._fillPlaneData), EventSubscription(self._gameEnv.ePlayerGunnerChangedTurret, self._updateModelShootingDistance)) self._subscription.subscribe() def _onSetBattleMod(self, bState): if self._battleMod == BATTLE_MODE.GUNNER_MODE or bState == BATTLE_MODE.GUNNER_MODE: self._battleMod = bState self._updateModelShootingDistance() def _updateModelShootingDistance(self, *args, **kwargs): self._model.effectiveShootingDistance = self._getGunnerShootingDistance( ) if self._battleMod == BATTLE_MODE.GUNNER_MODE else self._getMainArmamentShootingDistance( ) self._model.shootingDistanceMax = self._getGunnerShootingDistance( ) if self._battleMod == BATTLE_MODE.GUNNER_MODE else self._getMainArmamentShootingDistanceMax( ) self._log.debug( 'new shooting distance effective: %s, new shooting distance max: %s', self._model.effectiveShootingDistance, self._model.shootingDistanceMax) def _getMainArmamentShootingDistance(self): playerGlobalID = self._playerAvatar.globalID return self._db.getShootingDistanceEffective(playerGlobalID) def _getMainArmamentShootingDistanceMax(self): playerGlobalID = self._playerAvatar.globalID return self._db.getShootingDistanceMax(playerGlobalID) def _getGunnerShootingDistance(self): gunner = self._playerAvatar.controlledGunner return gunner.shootDistance def _fillPlaneData(self, *args, **kwargs): avatarInfo = self._clientArena.getAvatarInfo(self._playerAvatar.id) playerGlobalID = self._playerAvatar.globalID settings = avatarInfo['settings'] self._updateModelShootingDistance() self._model.planeName = localizeAirplane(settings.airplane.name) self._model.planeLevel = settings.airplane.level self._model.planeGlobalID = playerGlobalID self._model.planeType = settings.airplane.planeType self._model.planeTypeName = PREBATTLE_PLANE_TYPE_NAME[ settings.airplane.planeType] self._model.planePreviewIcon = settings.airplane.previewIconPath self._model.planeId = self._playerAvatar.objTypeID self._model.planeStatus = self._getPlaneStatus() self._model.teamIndex = self._playerAvatar.teamIndex self._model.isReconnected = bool(self._playerAvatar.reconnected) def _getPlaneStatus(self): planeID = self._playerAvatar.objTypeID isPremium = self._db.isPlanePremium(planeID) isElite = planeID in self._playerAvatar.elitePlanes planeStatus = PLANE_CLASS.PREMIUM if isPremium else isElite * PLANE_CLASS.ELITE or PLANE_CLASS.REGULAR return planeStatus def _setupModel(self, newInfos): self.__subscribe() id = self._playerAvatar.id avatarInfo = self._clientArena.getAvatarInfo(id) self._model.id = id self._model.clanName = unicode(avatarInfo.get('clanAbbrev', '')) self._model.nickName = unicode( avatarInfo.get('playerName', 'unknown name')) self._model.health = int(ceil(self._playerAvatar.health)) self._model.healthMax = int(ceil(self._playerAvatar.maxHealth)) self._model.squadIndex = avatarInfo.get('squadID', 0) self._model.state = getLogicState(avatarInfo) def _onUpdateHealth(self, health, lastDamagerID, oldValue): self._model.health = int(ceil(health)) def _onStateChanged(self, oldState, state): avatarInfo = self._clientArena.getAvatarInfo(self._playerAvatar.id) self._model.state = getLogicState(avatarInfo) def dispose(self): self._clientArena.onNewAvatarsInfo -= self._setupModel self._playerAvatar.eTacticalSpectator -= self._reFillModel self._subscription.unsubscribe() self._subscription = None self._input.eBattleModeChange -= self._onSetBattleMod self._gameEnv = None self._playerAvatar = None self._clientArena = None self._model = None return
def _subscribeOn(self, entity): raise self._subscription is None or AssertionError('Attempt to override subscription') self._subscription = CompositeSubscription(EventSubscription(entity.eWaveAdded, self.eWaveAdded), EventSubscription(entity.eWaveRemoved, self.eWaveRemoved), EventSubscription(entity.eWaveStateChanged, self.eWaveStateChanged), EventSubscription(entity.eBomberStateChanged, self.eBomberStateChanged)) self._subscription.subscribe() return
class PlaneTypeObjectivesDataSource(DataSource): """Data source for PlaneTypeObjectives model """ def __init__(self, features): self._model = features.require(Feature.GAME_MODEL).classTasks self._player = features.require(Feature.PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) coachMgr = self._player.coachManager self._subscription = CompositeSubscription( EventSubscription(coachMgr.eObjectivesChanged, self._updateCurrentObjectives), EventSubscription(coachMgr.eObjectiveProgressChanged, self._updateObjectiveProgress), EventSubscription(coachMgr.eObjectiveProgressRawValueChanged, self._updateObjectiveRawProgressValue), EventSubscription(self._player.eTacticalRespawnEnd, self._updateCurrentObjectives)) self._subscription.subscribe() if self._clientArena.isAllServerDataReceived(): self._setupModel(None) else: self._clientArena.onNewAvatarsInfo += self._setupModel logger.debug('Plane type objectives data source initialized') return def _setupModel(self, newInfos): self._clientArena.onNewAvatarsInfo -= self._setupModel self._updateCurrentObjectives() def _updateCurrentObjectives(self, *args, **kwargs): """Update current plane objectives. Should be called when objectives received from server or when avatar changed plane and new objectives are active now """ self._model.classTasks.clean() coachMgr = self._player.coachManager for objective in coachMgr.getCurrentPlaneObjectives(): self._model.classTasks.append( id=objective.id, title=objective.model.client.name.locale, countDescription=objective.model.client.countDescription. locale, description=objective.model.client.description.locale, progress=objective.progressCurrent, maxProgress=objective.progressMax, value=objective.progressRawValue, requiredValue=objective.getNextProgressBound()) def _updateObjectiveProgress(self, planeType, objectiveID, progress, *args, **kwargs): """Handle objective progress update on eObjectiveProgressChanged event """ objectiveData = self._player.coachManager.getObjectiveByID(objectiveID) objectiveModel = self._model.classTasks.first( lambda e: e.id.get() == objectiveID) if objectiveModel: objectiveModel.progress = progress objectiveModel.requiredValue = objectiveData.getNextProgressBound() def _updateObjectiveRawProgressValue(self, planeType, objectiveID, progressRawValue, *args, **kwargs): """Handle objective progress update on eObjectiveProgressChanged event """ objectiveModel = self._model.classTasks.first( lambda e: e.id.get() == objectiveID) if objectiveModel: objectiveModel.value = progressRawValue def dispose(self): self._subscription.unsubscribe() self._subscription = None self._player = None self._clientArena = None self._model = None return
class SectorsGameEffectsSource(DataSource): def __init__(self, features): self._logger = BWLogging.getLogger(self.__class__.__name__) self._model = features.require( Feature.GAME_MODEL).domination.sectorsGameEffects self._clientArena = features.require(Feature.CLIENT_ARENA) self._db = features.require(Feature.DB_LOGIC) self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._gameMode = self._clientArena.gameMode self._disableBomberCallbacks = {} self._subscription = CompositeSubscription( EDSubscription(self.gameMode, AC_EVENTS.BOMBERS_LAUNCHED, self._onBombersLaunched), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_ATTACK_NOTIFIED, self._onBomberAttackNotified), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_BOMBS_DROPPED, self._onBomberBombsDropped), EDSubscription(self.gameMode, AC_EVENTS.BOMBERS_DIED, self._onBombersDied), EDSubscription(self.gameMode, AC_EVENTS.BOMBER_IN_WAVE_DIED, self._onBomberInWaveDied), EDSubscription(self.gameMode.rocketV2Manager, AC_EVENTS.ROCKET_V2_EFFECT_STARTED, self._onRocketEffectStarted), EDSubscription(self.gameMode.rocketV2Manager, AC_EVENTS.ROCKET_V2_EFFECT_ENDED, self._onRocketEffectEnded), EventSubscription(self._clientArena.onReceiveMarkerMessage, self._onReceiveMarkerMessage)) self.gameMode.addEventHandler( AC_EVENTS.ROCKET_V2_TARGET_SECTOR_CHANGED, self._onRocketEffectSectorChanged) if self.gameMode.isReady: self._setupModel() else: self.gameMode.eGameModeReady += self._setupModel def _setupModel(self, *args, **kwargs): for record in self._clientArena.gameActionsManager.activeASWaves: state = WAVE_STATE_TO_HUD_STATE[record['state']] self._processASWave(record['sectorID'], record['targetID'], record['teamIndex'], record['waveID'], record['bomberIDsStates'], record['startTime'], state) self._subscription.subscribe() @property def gameMode(self): """Game mode instance @rtype: ArenaHelpers.GameModes.AreaConquest.ACGameModeClient.ACGameModeClient """ return self._gameMode def _onBombersLaunched(self, sectorIdent, targetSectorIdent, teamIndex, waveID, bomberIDsStates, startTime, *args, **kwargs): bomberIDs = [bomber['id'] for bomber in bomberIDsStates] self._logger.debug( "onBombersLaunched: sectorID = '{0}', targetID = '{1}', teamIndex = {2}, waveID = '{3}', bomberIDs = {4}, startTime = {5}" .format(sectorIdent, targetSectorIdent, teamIndex, waveID, bomberIDs, startTime)) self._processASWave(sectorIdent, targetSectorIdent, teamIndex, waveID, bomberIDsStates, startTime, BOMBERS_WAVE_STATE.INTRO_FLIGHT) def _processASWave(self, sectorIdent, targetSectorIdent, teamIndex, waveID, bomberIDsStates, startTime, state): arenaTypeData = self._gameMode.arenaTypeData sector = arenaTypeData.sectors.sectors[sectorIdent] influenceSettings = sector.bomberDispatcher.influenceBySectors[ targetSectorIdent] splineSettings = influenceSettings.splinesByTeams[teamIndex] spline = self._db.getSpline(splineSettings.name) points = spline.getBasePoints() startPoint = self._makePos(points[0].x, points[0].z) endPoint = self._makePos(points[-1].x, points[-1].z) actionPointIndex = splineSettings.actionPointIndex globalID = arenaTypeData.gameModeSettings.airStrike.globalIDByLevel[ self._playerAvatar.battleLevel] maxSpeed = _performanceCharacteristics_db.airplanes[globalID].maxSpeed curSpeed = speedToMovement(maxSpeed) * WORLD_SCALING / 3.6 dist = points[0].distTo(points[actionPointIndex]) startDelay = 2 flyingTime = dist / curSpeed arenaTime = startTime - self._playerAvatar.arenaStartTime strikeTime = int(arenaTime + flyingTime + startDelay) self._logger.debug( 'Bombing time estimation: arenaTime = {0}, startDelay = {1}, flyingTime = {2}' .format(arenaTime, startDelay, flyingTime)) waveTeamIndex = getClientTeamIndex(teamIndex, self._playerAvatar.teamIndex) self._appendASWave(sectorIdent, targetSectorIdent, waveTeamIndex, waveID, startPoint, endPoint, strikeTime, state, bomberIDsStates) def _onBomberInWaveDied(self, sectorIdent, waveID, bomberID): bomberEffect = self._model.airStrikes.first( lambda a: a.waveID.get() == waveID) if bomberEffect: bomberIDStruct = bomberEffect.bomberIDsStates.first( lambda d: d.id.get() == bomberID) if bomberIDStruct: bomberEffect.bomberIDsStates.splice(bomberIDStruct) def _onBomberAttackNotified(self, sectorID, waveID, bomberID, waveSize, aliveBombers, *args, **kwargs): self._logger.debug( "_onBombersAttackNotified: sectorID = '{0}', waveID = '{1}', waveSize = {2}, aliveBombers = {3}" .format(sectorID, waveID, waveSize, aliveBombers)) waveModel = self._model.airStrikes.first( lambda a: a.waveID.get() == waveID) if waveModel: waveModel.strikeState = BOMBERS_WAVE_STATE.BOMBING bomberModel = waveModel.bomberIDsStates.first( lambda a: a.id.get() == bomberID) if bomberModel: bomberModel.state = BOMBERS_WAVE_STATE.BOMBING def _onBomberBombsDropped(self, sectorID, waveID, bomberID, waveSize, aliveBombers, *args, **kwargs): arenaTypeData = self._gameMode.arenaTypeData delay = arenaTypeData.gameModeSettings.airStrike.markersDelayByLevel[ self._playerAvatar.battleLevel] model = self._model.airStrikes.first( lambda a: a.waveID.get() == waveID) self._disableBomberCallbacks[bomberID] = BigWorld.callback( delay, lambda: self.disableBomber(model, bomberID)) def disableBomber(self, model, bomberID): def checkIfReadyToSplice(list): for item in list: if item.state.get() is not BOMBERS_WAVE_STATE.OUTRO_FLIGHT: return False return True def checkIfSomebodyIsBombing(list): for item in list: if item.state.get() is BOMBERS_WAVE_STATE.BOMBING: return True return False if model: bomberModel = model.bomberIDsStates.first( lambda a: a.id.get() == bomberID) if bomberModel: bomberModel.state = BOMBERS_WAVE_STATE.OUTRO_FLIGHT if checkIfReadyToSplice(model.bomberIDsStates): model.strikeState = BOMBERS_WAVE_STATE.OUTRO_FLIGHT waveID = model.waveID.get() if self._model.airStrikes.first( lambda a: a.waveID.get() == waveID): self._model.airStrikes.splice(model) elif checkIfSomebodyIsBombing(model.bomberIDsStates): model.strikeState = BOMBERS_WAVE_STATE.BOMBING else: model.strikeState = BOMBERS_WAVE_STATE.INTRO_FLIGHT def _onBombersDied(self, waveID, *args, **kwargs): self._logger.debug("onBombersDied: waveID = '{0}'".format(waveID)) model = self._model.airStrikes.first( lambda a: a.waveID.get() == waveID) if model: for bomber in model.bomberIDsStates: bomber.state = BOMBERS_WAVE_STATE.OUTRO_FLIGHT model.strikeState = BOMBERS_WAVE_STATE.OUTRO_FLIGHT self._model.airStrikes.splice(model) def _onRocketEffectStarted(self, id, sectorIdent, targetSectorIdent, startPosition, endPosition, teamIndex, flyingTime): startTime = BigWorld.serverTime() - BigWorld.player().arenaStartTime startSectorPosition = self._getPosBySectorId(sectorIdent) endSectorPosition = self._getPosBySectorId(targetSectorIdent) self._model.rockets.append( id=id, sectorID=sectorIdent, targetSectorID=targetSectorIdent, startPoint=self._makePos(startSectorPosition.x, startSectorPosition.z), endPoint=self._makePos(endSectorPosition.x, endSectorPosition.z), teamIndex=teamIndex, flyingTime=flyingTime, startTime=startTime) def _onRocketEffectSectorChanged(self, id, newTargetSectorIdent): startSectorPosition = self._getPosBySectorId(id) endSectorPosition = self._getPosBySectorId(newTargetSectorIdent) for rocketEffect in self._model.rockets: if rocketEffect.sectorID.get() == id: rocketEffect.startPoint = self._makePos( startSectorPosition.x, startSectorPosition.z) rocketEffect.endPoint = self._makePos(endSectorPosition.x, endSectorPosition.z) rocketEffect.targetSectorID = newTargetSectorIdent break def _onReceiveMarkerMessage(self, senderID, posX, posZ, messageStringID, fromQueue): self._model.selectedPoint = self._makePos(posX, posZ) def _onRocketEffectEnded(self, id): model = self._model.rockets.first(lambda a: a.id.get() == id) if model: self._model.rockets.splice(model) def _makePos(self, x, y): return {'x': x, 'y': y} def _getPosBySectorId(self, sectorId): sectorData = self._getSectorByID(sectorId) return sectorData.entity.position def _checkSectorInSectors(self, sectorId): return sectorId in self.gameMode.sectors def _getSectorByID(self, sectorId): """ACSectorClient instance @rtype: ArenaHelpers.GameModes.AreaConquest.ACSectorClient.ACSectorClient """ return self.gameMode.sectors[sectorId] def _appendASWave(self, sectorID, targetID, teamIndex, waveID, startPoint, endPoint, strikeTime, state, bomberIDsStates): item = self._model.airStrikes.append(sectorID=sectorID, targetSectorID=targetID, teamIndex=teamIndex, waveID=waveID, startPoint=startPoint, endPoint=endPoint, strikeTime=strikeTime, strikeState=state) for bomber in bomberIDsStates: item.bomberIDsStates.appendSilently(id=bomber['id'], state=state) item.bomberIDsStates.finishAppending() def dispose(self): for item in self._disableBomberCallbacks.itervalues(): BigWorld.cancelCallback(item) self._disableBomberCallbacks.clear() self.gameMode.eGameModeReady -= self._setupModel self.gameMode.removeEventHandler( AC_EVENTS.ROCKET_V2_TARGET_SECTOR_CHANGED, self._onRocketEffectSectorChanged) self._subscription.unsubscribe() self._logger = None self._model = None self._clientArena = None self._db = None self._playerAvatar = None self._gameMode = None self._subscription = None return
class ExternalModifiers(AvatarControllerBase): def __init__(self, owner, consumables, equipment, crewSkills): AvatarControllerBase.__init__(self, owner) self.__skillConditions = SkillConditions(owner, SKILL_EVENT) self.__objects = { OBJ_GROUPS.CREW: [ CrewSkills(owner, obj, self.__skillConditions, index) for index, obj in enumerate(crewSkills) ], OBJ_GROUPS.CONSUMABLES: [ConsumableEquipmentFeaturedObject(obj) for obj in consumables], OBJ_GROUPS.EQUIPMENT: [ EquipmentFeaturedObject(obj, getCrewSkillsID(crewSkills)) for obj in equipment ], OBJ_GROUPS.CAMOUFLAGE: [ CamouflageFeatureObject(owner.camouflageBonusSchemeName, owner.isCamouflageSpecializedForCurMap) ] } self.__specializationIdToObj = {} for crewMember in self.__objects[OBJ_GROUPS.CREW]: self.__specializationIdToObj[ crewMember.specializationID] = crewMember self.eModifiersChanged = Event.Event() self.modifiers = Modifiers() readyToUseSubscriptions = ( EventSubscription(c.eReadyToUse, self._onConsumableReadyToUse) for c in self.__objects[OBJ_GROUPS.CONSUMABLES]) self._subscription = CompositeSubscription(*readyToUseSubscriptions) if IS_CELLAPP: self._subscription.extend( EventSubscription(self._owner.eDestruction, self.onOwnerDeath)) self._subscription.subscribe() def getFeatureObjects(self, featureObjectClass): return self.__objects.get(featureObjectClass, None) def destroy(self): self._subscription.unsubscribe() self._subscription = None AvatarControllerBase.destroy(self) for crewMember in self.__objects[OBJ_GROUPS.CREW]: crewMember.destroy() self.__objects.clear() self.__specializationIdToObj.clear() self.eModifiersChanged.clear() self.__skillConditions.destroy() return def onPartStateChanged(self, part): self.onPartsStateChanged([part]) def onPartsStateChanged(self, parts): reCalc = False for part in parts: specID = getCrewSpecializationByName( part.partTypeData.componentType) if specID in self.__specializationIdToObj: self.__specializationIdToObj[specID].changeState( part.logicalState) reCalc = True if reCalc: self.reCalc() def __findSlotIDByConsumableName(self, name): for slotID, slot in enumerate(self._owner.consumables): if slot['key'] != -1: consumable = db.DBLogic.g_instance.getConsumableByID( slot['key']) if consumable: if consumable.localizeTag == name: return slotID else: LOG_ERROR("Can't find consumable {c} description".format( c=slot['key'])) def isConsumablePresent(self, name): slotID = self.__findSlotIDByConsumableName(name) if slotID is not None: chargesCount = self._owner.consumables[slotID]['chargesCount'] return chargesCount > 0 or chargesCount == -1 else: return False def tryToUseConsumable(self, name): slotID = self.__findSlotIDByConsumableName(name) if slotID is not None: self.onUseConsumable(slotID) return def onUseConsumable(self, slotID): slot = self._owner.consumables[slotID] if slot['key'] != -1: consumable = self.__objects[OBJ_GROUPS.CONSUMABLES][slotID] from debug_utils import LOG_DEBUG_DEV LOG_DEBUG_DEV('onUseConsumable', slotID) if consumable.use(self._owner): self.reCalc() self._owner.publish(GameLogicEvents.CONSUMABLE_USED, slotID) def generateUsedConsumables(self): return [] def generateUsableConsumables(self): for slotID, consumableData in enumerate(self._owner.consumables): if consumableData['key'] != -1: consumable = self.__objects[OBJ_GROUPS.CONSUMABLES][slotID] if not consumable.isUsable(self._owner): continue consumableDb = db.DBLogic.g_instance.getConsumableByID( consumableData['key']) if consumableDb.behaviour == 1: consumableData['chargesCount'] = 0 continue yield slotID def onControllersCreated(self): crew = self.__objects.get(OBJ_GROUPS.CREW, []) for c in crew: c.afterRestore() for slotID, slotData in enumerate(self._owner.consumables): if slotData['key'] != -1: consumable = db.DBLogic.g_instance.getConsumableByID( slotData['key']) if consumable.behaviour == 1: self._owner.publish(GameLogicEvents.CONSUMABLE_USED, slotID) def restart(self): pass @property def crew(self): return self.__objects[OBJ_GROUPS.CREW] @property def consumables(self): """Consumables objects container :rtype: list[ConsumableEquipmentFeaturedObject] """ return self.__objects[OBJ_GROUPS.CONSUMABLES] def reCalc(self): if __debug__ and IS_DEVELOPMENT: oldModifiers = self.modifiers.dump() self.modifiers.reset() for objGroup in self.__objects.values(): for obj in objGroup: obj.applyObjMods(self.modifiers) self._owner.disguise = (self.modifiers.STEALTH - 1) * 100 if __debug__ and IS_DEVELOPMENT: self.modifiers.printDiff(oldModifiers) self.eModifiersChanged(self.modifiers) def update1sec(self, ms): if not EntityStates.inState(self._owner, EntityStates.GAME): return if IS_DEVELOPMENT and BigWorld.globalData.get( 'modifiersUpdateRequired', False) and self._owner.__class__.__name__ == 'Avatar': LOG_DEBUG(self._owner.id, 'reload request') BigWorld.globalData['modifiersUpdateRequired'] = False for crewMember in self.__objects[OBJ_GROUPS.CREW]: crewMember.reload() wasChanged = True else: wasChanged = False for c in self.__objects[OBJ_GROUPS.CONSUMABLES]: if c.update1sec(): wasChanged = True for crewMember in self.__objects[OBJ_GROUPS.CREW]: if crewMember.update1sec(): wasChanged = True if wasChanged: self.reCalc() def onParentSetState(self, stateID, data): LOG_DEBUG('Mods.onParentSetState', EntityStates.getStateName(stateID)) if stateID == EntityStates.GAME: for crewMember in self.__objects[OBJ_GROUPS.CREW]: crewMember.initGame() def getTargetSkillModsActivity(self, crew_member): return EnemySkillObserver.get_target_skill_mods_activity( self, crew_member) @staticmethod def getTargetSkillModValue(crew_member, modsActivity): return EnemySkillObserver.get_target_skill_mod_value( crew_member, modsActivity) def backup(self): if OBJ_GROUPS.CREW not in self.__objects: return None else: res = [c.backup() for c in self.__objects[OBJ_GROUPS.CREW]] res.append(self.__skillConditions.backup()) return res def restore(self, container): if container is None: return else: self.__skillConditions.restore(container.pop()) crew = self.__objects.get(OBJ_GROUPS.CREW) if not crew: return for c, crewMember in zip(container, crew): crewMember.restore(c) return def onOwnerRespawn(self, *args, **kwargs): """Handler for Avatar.eRespawn event """ currentTime = BigWorld.time() needUpdate = any([ consumable.onOwnerRespawn(currentTime) for consumable in self.consumables ]) if needUpdate: self.reCalc() def onOwnerDeath(self, *args, **kwargs): """Handler for Avatar.eDestruction event """ currentTime = BigWorld.time() for consumable in self.consumables: consumable.onOwnerDestruction(currentTime) def _onConsumableReadyToUse(self, consumable): if consumable.isAutoUsable and consumable.isUsable(self._owner): self._owner.schedulePartAutoFix(consumable.autoRepairPartType)
class ACGameModeClient(GameModeClient.GameModeClient): updateEventsMap = { ARENA_UPDATE.UPDATE_AC_POINTS: AC_ARENA_UPDATE_EVENTS.UPDATE_AC_POINTS, ARENA_UPDATE.UPDATE_GLOBAL_COUNTERS: AC_ARENA_UPDATE_EVENTS.UPDATE_GLOBAL_COUNTERS, ARENA_UPDATE.UPDATE_RESOURCE_POINTS: AC_ARENA_UPDATE_EVENTS.UPDATE_RESOURCE_POINTS, ARENA_UPDATE.CHANGE_DYNAMIC_TIME: AC_ARENA_UPDATE_EVENTS.CHANGE_DYNAMIC_TIME, ARENA_UPDATE.AC_SECTOR_PERMANENT_LOCK: AC_ARENA_UPDATE_EVENTS.AC_SECTOR_PERMANENT_LOCK, ARENA_UPDATE.AC_ACTION_MESSAGE: AC_ARENA_UPDATE_EVENTS.AC_ACTION_MESSAGE, ARENA_UPDATE.AC_SECTORS_STATUS: AC_ARENA_UPDATE_EVENTS.AC_SECTORS_STATUS, ARENA_UPDATE.AC_GAME_TICK: AC_ARENA_UPDATE_EVENTS.AC_GAME_TICK, ARENA_UPDATE.AC_BATTLE_EVENT: AC_ARENA_UPDATE_EVENTS.AC_BATTLE_EVENT, ARENA_UPDATE.AC_ROCKET_V2_LAUNCHED: AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_LAUNCHED, ARENA_UPDATE.AC_ROCKET_V2_HIT_TARGET: AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_HIT_TARGET, ARENA_UPDATE.AC_ROCKET_V2_TARGET_OBJECT_CHANGED: AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_TARGET_OBJECT_CHANGED, ARENA_UPDATE.AC_BOMBER_IN_WAVE_DIED: AC_ARENA_UPDATE_EVENTS.AC_BOMBER_IN_WAVE_DIED, ARENA_UPDATE.AC_BOMBER_DISPATCHER_TARGET_SECTOR_CHANGED: AC_ARENA_UPDATE_EVENTS.AC_BOMBER_DISPATCHER_TARGET_SECTOR_CHANGED } def __init__(self, clientArena): super(ACGameModeClient, self).__init__(clientArena) self._scoreGlobal = (0, 0) self._globalCounters = {} self._sectors = {} self._currentTick = 0 self._currentTickStartedAt = self.player.arenaStartTime self._globalTime = 0 self._dynamicTime = 0 self._isReady = False self._eManager = EventManager() self.eGameModeReady = Event(self._eManager) self._rocketV2Manager = RocketV2Manager.RocketV2Manager(self) self._signalFlaresManager = SignalFlaresManager.SignalFlaresManager( self) self._waveInfoManager = WaveInfoManager(self) self._lastPlayerManager = LastPlayerManager(self) self._pendingEvents = [] self.createSectorsData() self.registerArenaUpdateEvents(self.updateEventsMap) gameActionsManager = self.clientArena.gameActionsManager self._subscription = CompositeSubscription( EventSubscription(gameActionsManager.eWaveAdded, self._onASWaveAdded), EventSubscription(gameActionsManager.eWaveRemoved, self._onASWaveRemoved), EventSubscription(gameActionsManager.eWaveStateChanged, self._onASWaveStateChanged), EventSubscription(gameActionsManager.eBomberStateChanged, self._onASBomberStateChanged)) self._subscription.subscribe() @property def isReady(self): return self._isReady @property def rocketV2Manager(self): """ @rtype: RocketV2Manager.RocketV2Manager """ return self._rocketV2Manager @property def scoreGlobal(self): """Global game score @rtype: (int, int) """ return self._scoreGlobal @property def sectors(self): """Sectors dict @rtype: dict[basestring, ACSectorClient.ACSectorClient] """ raise self.isReady or AssertionError( 'Attempt to get sectors data while GameMode is not ready') return self._sectors @property def currentTick(self): """Current game tick number @rtype: int """ return self._currentTick @property def currentTickStartedAt(self): """Time when current tick started by BigWorld.serverTime() @rtype: float """ return self._currentTickStartedAt @property def arenaTimeRemaining(self): """battle time remaining @rtype: float """ return self.player.arenaStartTime + self.arenaTypeData.gameModeSettings.battleDuration - BigWorld.serverTime( ) @property def waveInfoManager(self): """ @rtype: WaveInfoManager.WaveInfoManager """ return self._waveInfoManager @property def uiSettings(self): return self.arenaTypeData.gameModeSettings.uiSettings @property def gameModeName(self): return GAME_MODE.NAMES[self.clientArena.gameModeEnum] @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_BATTLE_EVENT) def onBattleEvent(self, payload, *args, **kwargs): self._logDebug( ':onUpdateACSBattleEvent: onBattleEvent'.format(payload)) battleEventId = payload self.dispatch(AC_EVENTS.BATTLE_EVENT, battleEventId) @eventHandler(AC_ARENA_UPDATE_EVENTS.UPDATE_AC_POINTS) def onUpdateACPoints(self, payload, *args, **kwargs): points = tuple(payload) self._logDebug(':onUpdateACPoints: points={0}'.format(points)) maxPoints = self._arenaTypeData.gameModeSettings.pointsToWin self._scoreGlobal = (min(points[0], maxPoints), min(points[1], maxPoints)) self.dispatch(AC_EVENTS.GLOBAL_SCORE_UPDATED, self.scoreGlobal) @eventHandler(AC_ARENA_UPDATE_EVENTS.CHANGE_DYNAMIC_TIME) def onChangeDynamicTime(self, payload, *args, **kwargs): time = payload oldTime = self._dynamicTime self._dynamicTime = time self.dispatch(AC_EVENTS.DYNAMIC_TIMER_UPDATE, time, oldTime) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_SECTOR_PERMANENT_LOCK) def onSectorPermanentLock(self, payload, *args, **kwargs): sectorId = payload self.dispatch(AC_EVENTS.SECTOR_PERMANENT_LOCK, sectorId) @eventHandler(AC_ARENA_UPDATE_EVENTS.UPDATE_GLOBAL_COUNTERS) def onUpdateGlobalCounters(self, payload, *args, **kwargs): counters = payload self._logDebug( ':onUpdateGlobalCounters: counters={0}'.format(counters)) self._globalCounters = counters self.dispatch(AC_EVENTS.GLOBAL_COUNTERS_UPDATED, self._globalCounters) @eventHandler(AC_ARENA_UPDATE_EVENTS.UPDATE_RESOURCE_POINTS) def onUpdateResourcePoints(self, payload, *args, **kwargs): totalPoints, killerID, victimID, pointsInc = payload self._logDebug(':onUpdateResourcePoints: {},{},{},{}'.format( totalPoints, killerID, victimID, pointsInc)) self.dispatch(AC_EVENTS.RESOURCE_POINTS_UPDATED, totalPoints, killerID, victimID, pointsInc) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_SECTORS_STATUS) def onACSectorStatus(self, payload, *args, **kwargs): self._logDebug(':onACSectorStatus: payload={0}'.format(payload)) sectorID, sectorPoints, capturePoints = payload sector = self.sectors[sectorID] sector.updateCapturePoints(sectorPoints) self.dispatch(AC_EVENTS.SECTOR_CAPTURE_POINTS_CHANGED, sector.ident, sector.capturePointsByTeams) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_ACTION_MESSAGE) def onACActionMessage(self, payload, *args, **kwargs): self._logDebug(':onACActionMessage: payload={0}'.format(payload)) action, teamIndex, avatarId, sectorId, tickNumber, points = payload settings = SETTINGS.ACTION_SETTINGS.get(action) if not settings: self._logError( ':onACActionMessage: Unknown action got, id={0}'.format( action)) return self.dispatch(AC_EVENTS.SECTOR_ACTION, sectorId, teamIndex, settings) if settings['sectorScore']: sector = self.sectors[sectorId] sector.addCapturePoints(teamIndex, points) self._logDebug( ':onACActionMessage: updated sector capture points: {0}'. format(sector.capturePointsByTeams)) self.dispatch(AC_EVENTS.SECTOR_CAPTURE_POINTS_CHANGED, sector.ident, sector.capturePointsByTeams) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_GAME_TICK) def onACGameTick(self, payload, *args, **kwargs): self._logDebug(':onACGameTick: payload={0}'.format(payload)) tickNumber = payload self.dispatch(AC_EVENTS.GAME_MODE_TICK, tickNumber) self._currentTick = tickNumber + 1 self._currentTickStartedAt = BigWorld.serverTime() @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_LAUNCHED) def onRocketV2Launched(self, payload, *args, **kwargs): launchPosition, targetPosition = Math.Vector3(), Math.Vector3() sectorIdent, launchPosition.x, launchPosition.y, launchPosition.z, targetID, targetPosition.x, targetPosition.y, targetPosition.z, flyingTime = payload self.dispatch(AC_EVENTS.ROCKET_V2_LAUNCHED, sectorIdent, launchPosition, targetPosition, flyingTime) def onRocketV2TargetSectorChanged(self, sectorID, oldTargetID, newTargetID, *args, **kwargs): self.dispatch(AC_EVENTS.ROCKET_V2_TARGET_SECTOR_CHANGED, sectorID, newTargetID) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_TARGET_OBJECT_CHANGED) def onRocketV2TargetObjectChanged(self, payload, *args, **kwargs): sectorIdent, sectorTeamIndex, newTargetObjId = payload self.dispatch(AC_EVENTS.ROCKET_V2_TARGET_OBJECT_CHANGED, sectorIdent, sectorTeamIndex, newTargetObjId) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_ROCKET_V2_HIT_TARGET) def onRocketV2HitTarget(self, payload, *args, **kwargs): sectorIdent, teamIndex, targetTeamObjectId, targetPositionX, targetPositionY, targetPositionZ, targetTeamIndex = payload self.dispatch(AC_EVENTS.ROCKET_V2_HIT_TARGET, sectorIdent, teamIndex, targetTeamObjectId) @eventHandler(AC_ARENA_UPDATE_EVENTS.AC_BOMBER_IN_WAVE_DIED) def onBomberInWaveDied(self, payload): sectorIdent, waveID, bomberID = payload self.dispatch(AC_EVENTS.BOMBER_IN_WAVE_DIED, sectorIdent, waveID, bomberID) @eventHandler( AC_ARENA_UPDATE_EVENTS.AC_BOMBER_DISPATCHER_TARGET_SECTOR_CHANGED) def onBombersChangeTarget(self, payload): sectorIdent, newTargetSectorIdent = payload self.dispatch(AC_EVENTS.BOMBER_DISPATCHER_TARGET_SECTOR_CHANGED, sectorIdent, newTargetSectorIdent) def createSectorsData(self): """Create sectors data using arena settings """ for sectorId, settings in self.arenaTypeData.sectors.sectors.iteritems( ): entity = next( (sector for sector in ACSector.entities if sector.ident == sectorId), None) if entity: self._sectors[ sectorId] = sector = ACSectorClient.ACSectorClient( settings, entity) sector.eStateChanged += self.onSectorStateChanged sector.eRocketV2TargetSectorIDChanged += self.onRocketV2TargetSectorChanged self._checkIsReady() return def getPointsInTick(self, tickNumber=None): """Return Points in tick @param tickNumber: tick number """ tickNumber = tickNumber or self.currentTick score = [0, 0] for sector in self.sectors.itervalues(): if sector.teamIndex in (TEAM_ID.TEAM_0, TEAM_ID.TEAM_1): score[sector.teamIndex] += sector.getPointsInTick(tickNumber) return score def getTickPeriod(self): """Return tick period """ period = self.arenaTypeData.gameModeSettings.globalTickPeriod if self.teamSuperiority(TEAM_ID.TEAM_0) or self.teamSuperiority( TEAM_ID.TEAM_1): period = self.arenaTypeData.gameModeSettings.superiorityGlobalTickPeriod return period def capturedSectors(self, teamIndex): """Return captured sectors """ capturedSectors = 0 for sector in self._sectors.itervalues(): if not sector.isCapturable: continue if sector.teamIndex == teamIndex: capturedSectors += 1 return capturedSectors def teamSuperiority(self, teamIndex): """Check capture sectors by team """ sectors = 0 capturedSectors = 0 for sector in self._sectors.itervalues(): if not sector.isCapturable: continue sectors += 1 if sector.teamIndex == teamIndex: capturedSectors += 1 return sectors == capturedSectors def checkSectorForLock(self, ident): if ident in self._sectors: return self._sectors[ident].isLockForBattle return False def onSectorStateChanged(self, ident, oldState, state, *args, **kwargs): """Event handler for state changed event @param ident: Sector identifier @type state: BWUserTypesCommon.ACSectorState.ACSectorState @type oldState: BWUserTypesCommon.ACSectorState.ACSectorState """ self.dispatch(AC_EVENTS.SECTOR_STATE_CHANGED, ident, oldState.state, oldState.teamIndex, state.state, state.teamIndex, state.nextStateTimestamp) def _checkIsReady(self): if self._isReady: return self._isReady = all((ident in self._sectors for ident in self.arenaTypeData.sectors.sectors)) if self._isReady: self._processSuspendedEvents() self.eGameModeReady() def onACSectorCreated(self, entity): """Callback from sector entity on enter world event @type entity: ACSector """ raise entity.ident in self.arenaTypeData.sectors.sectors or AssertionError( "Unexpected sector created: '{0}', arena: {1}".format( entity.ident, self.arenaTypeData.typeName)) settings = self.arenaTypeData.sectors.sectors[entity.ident] self._sectors[entity.ident] = sector = ACSectorClient.ACSectorClient( settings, entity) sector.eStateChanged += self.onSectorStateChanged self._checkIsReady() @property def lastPlayerManager(self): return self._lastPlayerManager def dispatch(self, event, *args, **kwargs): if not self.isReady: self._suspendEvent(event, args, kwargs) self._logDebug( "Suspended event processing while game mode is not ready: event = '{0}', args = {1}, kwargs = {2}" .format(event, args, kwargs)) return super(ACGameModeClient, self).dispatch(event, *args, **kwargs) def destroy(self): self._subscription.unsubscribe() self._subscription = None self._waveInfoManager.destroy() self._lastPlayerManager.destroy() self._eManager.clear() self._rocketV2Manager.destroy() self._signalFlaresManager.destroy() self.clear() super(ACGameModeClient, self).destroy() return def _suspendEvent(self, event, args, kwargs): self._pendingEvents.append((event, args, kwargs)) def _processSuspendedEvents(self): for event, args, kwargs in self._pendingEvents: self.dispatch(event, *args, **kwargs) self._pendingEvents[:] = [] def _onASWaveAdded(self, record, *args, **kwargs): """Handler for GameActionsManager.eWaveAdded event :param record: AIR_STRIKE_WAVE_RECORD """ self.dispatch(AC_EVENTS.BOMBERS_LAUNCHED, record['sectorID'], record['targetID'], record['teamIndex'], record['waveID'], record['bomberIDsStates'], record['startTime']) def _onASWaveRemoved(self, waveID, *args, **kwargs): """Handler for GameActionsManager.eWaveRemoved event :param waveID: Unique wave identifier """ self.dispatch(AC_EVENTS.BOMBERS_DIED, waveID) def _onASWaveStateChanged(self, record, stateOld, state, *args, **kwargs): """Handler for GameActionsManager.eWaveStateChanged event :param record: AIR_STRIKE_WAVE_RECORD :param stateOld: Old state value :param state: New state value """ if state == AIR_STRIKE_WAVE_STATE.ATTACK_IN_PROGRESS and stateOld == AIR_STRIKE_WAVE_STATE.BOMBS_DROPPED: self.dispatch(AC_EVENTS.BOMBERS_ATTACK_STARTED, record['sectorID'], record['waveID'], record['size'], len(record['bomberIDsStates'])) def _onASBomberStateChanged(self, record, bomberID, stateOld, state, *args, **kwargs): """Handler for GameActionsManager.eBomberStateChanged event :param record: AIR_STRIKE_WAVE_RECORD :param bomberID: Unique bomber id :param stateOld: Old state value :param state: New state value """ if state == AIR_STRIKE_WAVE_STATE.ATTACK_NOTIFIED and stateOld == AIR_STRIKE_WAVE_STATE.INTRO_FLIGHT: self.dispatch(AC_EVENTS.BOMBER_ATTACK_NOTIFIED, record['sectorID'], record['waveID'], bomberID, record['size'], len(record['bomberIDsStates'])) elif state == AIR_STRIKE_WAVE_STATE.BOMBS_DROPPED and stateOld == AIR_STRIKE_WAVE_STATE.ATTACK_NOTIFIED: self.dispatch(AC_EVENTS.BOMBER_BOMBS_DROPPED, record['sectorID'], record['waveID'], bomberID, record['size'], len(record['bomberIDsStates']))
class AirStrikeDefeatedEventProvider(object): """ Provides with event when air strike bombers are defeated with player participation before they started to attack @type _eventCandidates: dict[int, EventCandidate] """ def __init__(self, gameEnvironment, gameMode): """ @type gameEnvironment: GameEnvironment.GameEnvironment @type gameMode: ArenaHelpers.GameModes.AreaConquest.ACGameModeClient.ACGameModeClient """ self._gameEnvironment = gameEnvironment self._gameMode = gameMode self._eventCandidates = {} self.__waveDiedCallbacks = {} self.eAirStrikeDefeated = Event() self._subscribe() def destroy(self): self.__clearAllCallbacks() self._unsubscribe() self.eAirStrikeDefeated.clear() self._gameEnvironment = None self._gameMode = None return def _subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._gameEnvironment.eAvatarHealthChange, self._onAvatarHealthChanged), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_LAUNCHED, self._onACBombersWaveLaunched), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_DIED, self._onACBombersWaveDied), EDSubscription(self._gameMode, AC_EVENTS.BOMBERS_ATTACK_STARTED, self._onACBombersAttackStarted)) self._subscription.subscribe() def _unsubscribe(self): self._subscription.unsubscribe() self._subscription = None return def __clearCB(self, waveID): if waveID in self.__waveDiedCallbacks: BigWorld.cancelCallback(self.__waveDiedCallbacks[waveID]) del self.__waveDiedCallbacks[waveID] def __clearAllCallbacks(self): for waveID, callback in self.__waveDiedCallbacks.iteritems(): BigWorld.cancelCallback(callback) self.__waveDiedCallbacks = {} def _onAvatarHealthChanged(self, entity, *args, **kwargs): if entity.lastDamagerID != BigWorld.player().id: return for waveID, candidate in self._eventCandidates.iteritems(): if candidate.isDamagedByPlayer: continue if entity.id in candidate.bomberIDs: candidate.isDamagedByPlayer = True break def _onACBombersWaveLaunched(self, sectorID, targetID, teamIndex, waveID, bomberIDsStates, startTime, *args, **kwargs): if BigWorld.player().teamIndex == teamIndex: return bomberIDs = [bomber['id'] for bomber in bomberIDsStates] self._eventCandidates[waveID] = EventCandidate(waveID, bomberIDs, targetID, teamIndex) def _onACBombersAttackStarted(self, sectorID, waveID, waveSize, aliveBombers, *args, **kwargs): if waveID in self._eventCandidates: del self._eventCandidates[waveID] def _onACBombersWaveDied(self, waveID, *args, **kwargs): if waveID in self._eventCandidates: if self._eventCandidates[waveID].isDamagedByPlayer: if waveID not in self.__waveDiedCallbacks: onACBombersWaveDiedCallback = partial( self._onACBombersWaveDied, waveID, *args, **kwargs) self.__waveDiedCallbacks[waveID] = BigWorld.callback( 0.5, onACBombersWaveDiedCallback) return targetID = self._eventCandidates[waveID].targetID if not self._eventCandidates[ waveID].teamIndex == self._gameMode.sectors[ targetID].teamIndex: self.eAirStrikeDefeated() self.__clearCB(waveID) del self._eventCandidates[waveID]
class EntitiesSource(DataSource): def __init__(self, features): self._logger = BWLogging.getLogger(self.__class__.__name__) self._model = features.require(Feature.GAME_MODEL).entities self._gameEnvironment = features.require(Feature.GAME_ENVIRONMENT) self._clientArena = features.require(Feature.CLIENT_ARENA) self._playerAvatar = features.require(Feature.PLAYER_AVATAR) self._db = features.require(Feature.DB_LOGIC) self._planeConfigurationsDB = features.require( Feature.PLANES_CONFIGURATIONS_DB) self._playerTeamIndex = self._playerAvatar.teamIndex self._playerAvatar.eTacticalSpectator += self._hideAvatarData self._teamObjectsSource = TeamObjectsSource(self._model.teamObjects, features) self._tempVisibleObjectsSource = TempVisibleObjectsSource( self._model, features) self._lastTacticalSpectatorID = self._playerAvatar.id self._sources = {} self._subscribe() def _subscribe(self): self._subscription = CompositeSubscription( EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updateAvatarPlaneTypeRank), EventSubscription(self._clientArena.onAvatarPlaneTypeRankChanged, self._updatePlaneScoresData), EventSubscription( self._clientArena.onPlayerEconomicExtDataReceived, self._updatePlaneScoresData), EventSubscription(self._clientArena.onAvatarChangedPlane, self._updateAvatarPlaneTypeRank), EventSubscription(self._clientArena.onAvatarEnterWorld, self._onAvatarEnterWorld), EventSubscription(self._clientArena.onAvatarLeaveWorld, self._onAvatarLeaveWorld), EventSubscription(self._clientArena.onEconomicPlayersPoints, self._onPlayersPoints), EventSubscription(self._clientArena.onUpdatePlayerStats, self._onUpdatePlayerStats)) self._subscription.subscribe() if self._clientArena.isAllServerDataReceived(): self._onNewAvatarsInfo(None) else: self._clientArena.onNewAvatarsInfo += self._onNewAvatarsInfo return def _onNewAvatarsInfo(self, avatarInfos): self._clientArena.onNewAvatarsInfo -= self._onNewAvatarsInfo for avatarInfo in self._clientArena.avatarInfos.values(): id_ = avatarInfo['avatarID'] if avatarInfo['isNPC'] and avatarInfo[ 'NPCType'] == ACNPCTypes.Bomber: bomberModel = self._onNewBomber(id_, avatarInfo) self._checkBombersWithEntity(id_, bomberModel) else: self._onNewAvatar(id_, avatarInfo) def _checkBombersWithEntity(self, bomberID, bomberModel): entity = BigWorld.entities.get(bomberID) if entity is not None: if entity.inWorld: self._updateAvatarOnEnterWorld(entity, bomberModel) return def _hideAvatarData(self, *args, **kwargs): model = self._getEntityModel(self._lastTacticalSpectatorID) if model is not None: entity = BigWorld.entities.get(self._lastTacticalSpectatorID) if entity is not None: model.inWorld = entity.inWorld model = self._getEntityModel(self._playerAvatar.id) if model is not None: model.inWorld = False self._lastTacticalSpectatorID = self._playerAvatar.id return def _onNewAvatar(self, id, avatarInfo): entity = BigWorld.entities.get(id) if entity: self._addAvatarFromEntity(entity, avatarInfo, id) else: self._addAvatarFromInfo(avatarInfo, id) self._updatePlaneScoresData(id) def _onNewBomber(self, id, avatarInfo): LOG_DEBUG('EntitySource :: _onNewBomber', id) settings = avatarInfo.get('settings') return self._model.bombers.append( id=id, planeName=localizeAirplane(settings.airplane.name), playerName=avatarInfo['playerName'], teamIndex=getClientTeamIndex(avatarInfo['teamIndex'], self._playerAvatar.teamIndex), maxHealth=int(ceil(avatarInfo['maxHealth'])), inWorld=False) def _addAvatarFromEntity(self, entity, avatarInfo, id): if id == self._playerAvatar.id: return avatarModel = self._addAvatarFromInfo(avatarInfo, id) self._updateAvatarOnEnterWorld(entity, avatarModel) def _addAvatarFromInfo(self, avatarInfo, id): settings = avatarInfo.get('settings') if not settings: globalID = avatarInfo['airplaneInfo']['globalID'] import _airplanesConfigurations_db planeID = _airplanesConfigurations_db.getAirplaneConfiguration( globalID).planeID settings = self._db.getAircraftData(planeID) untypedName = avatarInfo.get('playerName', '') globalID = avatarInfo['airplaneInfo']['globalID'] currentPlaneType = settings.airplane.planeType currentRankID = avatarInfo['planeTypeRank'][currentPlaneType] if type(untypedName) is unicode: playerName = untypedName else: playerName = unicode(untypedName, 'utf-8') return self._model.avatars.append( id=id, clanName=unicode(avatarInfo.get('clanAbbrev', '')), playerName=playerName, planeGlobalID=globalID, isDefender=bool(avatarInfo.get('defendSector')), isBot=bool(avatarInfo.get('databaseID') == 0), planeType=settings.airplane.planeType, planeName=localizeAirplane(settings.airplane.name), planeLevel=settings.airplane.level, previewIconPath=settings.airplane.previewIconPath, teamIndex=getClientTeamIndex(avatarInfo['teamIndex'], self._playerAvatar.teamIndex), squadIndex=avatarInfo['squadID'], maxHealth=int(ceil(avatarInfo['maxHealth'])), points=avatarInfo['economics']['totalBattlePoints'], inWorld=False, state=getLogicState(avatarInfo), isLost=checkLost(avatarInfo), rankID=currentRankID) def _onUpdatePlayerStats(self, avatarInfo): self._updateStateAvatarInfo(avatarInfo) def _onPlayersPoints(self, data): for id, points in data.iteritems(): avatarModel = self._model.avatars.first(lambda e: e.id.get() == id) if avatarModel: avatarModel.points = points def _updateAvatarOnEnterWorld(self, entity, avatarModel): avatarModel.inWorld = True from Bomber import Bomber if not isinstance(entity, Bomber): self._updatePlaneIfChanged(entity, avatarModel) source = AvatarSource(avatarModel, entity, self._playerTeamIndex) else: source = EntitySource(avatarModel, entity, self._playerTeamIndex, isBomber=True) LOG_DEBUG('EntitySource :: _updateAvatarOnEnterWorld') if entity.id in self._sources: self._sources[entity.id].dispose() self._sources[entity.id] = source def _updatePlaneIfChanged(self, entity, avatarModel): settings = entity.settings newPlaneName = localizeAirplane(settings.airplane.name) if newPlaneName != avatarModel.planeName.get(): avatarModel.planeName = newPlaneName avatarModel.planeType = settings.airplane.planeType avatarModel.planeLevel = settings.airplane.level def _onAvatarEnterWorld(self, entity): if not entity.id not in self._sources: raise AssertionError avatarModel = self._getEntityModel(entity.id) avatarModel is not None and self._updateAvatarOnEnterWorld( entity, avatarModel) return def _onAvatarLeaveWorld(self, entity): avatarModel = self._getEntityModel(entity.id) if avatarModel is not None: avatarModel.inWorld = False source = self._sources.get(entity.id) if source: source.dispose() del self._sources[entity.id] return def _getEntityModel(self, id): avatarModel = self._model.avatars.first(lambda e: e.id.get() == id) if avatarModel is None: avatarModel = self._model.bombers.first(lambda e: e.id.get() == id) return avatarModel def _updateStateAvatarInfo(self, avatarInfo): if avatarInfo: avatarID = avatarInfo['avatarID'] avatarModel = self._model.avatars.first( lambda e: e.id.get() == avatarID) if avatarModel: logicState = getLogicState(avatarInfo) avatarModel.state = logicState isLost = checkLost(avatarInfo) if avatarModel.isLost.get() != isLost: avatarModel.isLost = isLost def _updateAvatarPlaneTypeRank(self, avatarID, *args, **kwargs): """Update rank for avatar in model. :param avatarID: Identifier of Avatar to update """ avatarInfo = self._clientArena.avatarInfos[avatarID] settings = avatarInfo.get('settings') if not settings: globalID = avatarInfo['airplaneInfo']['globalID'] import _airplanesConfigurations_db planeID = _airplanesConfigurations_db.getAirplaneConfiguration( globalID).planeID settings = self._db.getAircraftData(planeID) currentPlaneType = settings.airplane.planeType currentRankID = avatarInfo['planeTypeRank'][currentPlaneType] avatarModel = self._model.avatars.first( lambda e: e.id.get() == avatarID) if avatarModel: avatarModel.rankID = currentRankID def _updatePlaneScoresData(self, avatarID, *args, **kwargs): """Update score data for all avatar planes. Is called when avatar rank is changed and when new battle points received from server """ avatarInfo = self._clientArena.avatarInfos[avatarID] economics = avatarInfo['economics'] planeTypeRanks = avatarInfo['planeTypeRank'] pointsByPlanes = economics['pointsByPlanes'] if not pointsByPlanes: globalID = avatarInfo['airplaneInfo']['globalID'] planeID = self._planeConfigurationsDB.getAirplaneConfiguration( globalID).planeID pointsByPlanes = [(planeID, 0)] avatarItem = self._model.avatars.first( lambda e: e.id.get() == avatarID) if not avatarItem: return for planeID, battlePoints in pointsByPlanes: planeData = self._db.getAircraftData(planeID) planeType = planeData.airplane.planeType scoreItem = avatarItem.planeScoresData.first( lambda e: e.planeID.get() == planeID) if scoreItem: scoreItem.battlePoints = battlePoints scoreItem.rankID = planeTypeRanks[planeType] else: avatarItem.planeScoresData.append( planeID=planeID, planeType=planeType, planeName=localizeAirplane(planeData.airplane.name), battlePoints=battlePoints, rankID=planeTypeRanks[planeType]) def dispose(self): self._subscription.subscribe() self._subscription = None self._clientArena.onNewAvatarsInfo -= self._onNewAvatarsInfo self._playerAvatar.eTacticalSpectator -= self._hideAvatarData self._teamObjectsSource.dispose() self._tempVisibleObjectsSource.dispose() for source in self._sources.itervalues(): source.dispose() self._sources = {} return
class OutroSource(DataSource): def __init__(self, features): self._model = features.require(Feature.GAME_MODEL).outro self._db = features.require(Feature.DB_LOGIC) self._bigWorld = features.require(Feature.BIG_WORLD) self._economics = features.require(Feature.CLIENT_ECONOMICS) self._player = features.require(Feature.REAL_PLAYER_AVATAR) self._clientArena = features.require(Feature.CLIENT_ARENA) self._clientArena.onGameResultChanged += self._update self._economics.onUpdateBattlePoints += self._updatePlayerEconomics self._cachedTeammates = [] self._updateRateSubscription = None self._isFirstBattleResultUpdate = True return def _update(self, gameResult, winState): playerTeamIndex = self._player.teamIndex enemyTeamIndex = 1 - self._player.teamIndex logger.debug('RESULT::::: {0}'.format(gameResult)) if gameResult in GAME_RESULT_LOC_IDS: resIndex = 2 if winState == 2 else int(playerTeamIndex != winState) reason = GAME_RESULT_LOC_IDS[gameResult][resIndex] self._model.reason = reason logger.debug('Update: {0}, {1}, {2}, {3}'.format( gameResult, winState, playerTeamIndex, reason)) self._model.winnerTeamIndex = winState self._updateBattleTime() scoreGlobal = self._clientArena.gameMode.scoreGlobal self._model.allyPoints = scoreGlobal[playerTeamIndex] self._model.enemyPoints = scoreGlobal[enemyTeamIndex] self._updatePlayerTeamRate() self._updatePlayerEconomics() if not self._updateRateSubscription: self._updateRateSubscription = CompositeSubscription( EventSubscription(self._clientArena.onEconomicEvents, self._updatePlayerTeamRate), EventSubscription(self._clientArena.onEconomicPlayersPoints, self._updatePlayerTeamRate)) self._updateRateSubscription.subscribe() self._updateBestRankData() def _updateBattleTime(self): if self._isFirstBattleResultUpdate: battleTimeRaw = self._bigWorld.serverTime( ) - self._bigWorld.player().arenaStartTime + ARENA_WAIT4DRAW_DELAY self._model.goToHangarTime = int(battleTimeRaw + OUTRO_TIME + OUTRO_TIME_QUIT_DELAY + 0.5) self._model.battleTime = int(battleTimeRaw + 0.5) self._isFirstBattleResultUpdate = False def _updatePlayerTeamRate(self, *args, **kwargs): """Update model.playerLevel based player's on battle points """ places = {} teammatesArray = self._getTeammatesArray() for avatarID in teammatesArray: avatarInfo = self._clientArena.avatarInfos[avatarID] battlePoints = avatarInfo['economics']['totalBattlePoints'] planeType = self._db.getAircraftData( avatarInfo['bestRankPlaneID']).airplane.planeType rankID = avatarInfo['planeTypeRank'][planeType] bestRankOrderIndex = 0 if rankID != RankModel.EMPTY_RANK_ID: bestRankOrderIndex = RankModel.getRankByID(rankID).orderIndex places.setdefault((bestRankOrderIndex, battlePoints), []).append(avatarID) places = sorted(places.iteritems(), key=lambda item: item[0], reverse=True) playerPointsRate = None for place, (data, players) in enumerate(places, start=1): if self._player.id in players: playerPointsRate = place break raise playerPointsRate or AssertionError( 'Sorting error, data: {}'.format(places)) logger.debug('Update player points rate: {0}'.format(playerPointsRate)) self._model.playerLevel = playerPointsRate return def _getTeammatesArray(self): """Return list with teammates avatarIDs :rtype: list[int] """ if not self._cachedTeammates: self._cachedTeammates = [] for avatarID, avatarInfo in self._clientArena.avatarInfos.iteritems( ): if not avatarInfo[ 'isNPC'] and self._player.teamIndex == avatarInfo[ 'teamIndex']: self._cachedTeammates.append(avatarID) return self._cachedTeammates def _updateBestRankData(self): avatarInfo = self._clientArena.avatarInfos[self._player.id] bestPlaneID = avatarInfo['bestRankPlaneID'] planeData = self._db.getAircraftData(bestPlaneID) planeType = planeData.airplane.planeType bestRankID = avatarInfo['planeTypeRank'][planeType] logger.debug('Best rank id = {0}, planeID = {1}'.format( bestRankID, bestPlaneID)) self._model.bestPlane = localizeAirplane(planeData.airplane.name) self._model.bestClass = localizeLobby( PREBATTLE_PLANE_TYPE_NAME[planeType]) self._model.bestPlaneType = planeType self._model.bestRank = bestRankID self._model.bestTasks.clean() for objective in self._player.coachManager.getPlaneTypeObjectives( planeType): self._model.bestTasks.append( id=objective.id, title=objective.model.client.name.locale, description=objective.model.client.description.locale, progress=objective.progressCurrent, maxProgress=objective.progressMax, value=objective.progressRawValue, requiredValue=objective.getNextProgressBound()) def _updatePlayerEconomics(self, *args, **kwargs): """Update outro economics data """ self._model.battlePoints = self._economics.battlePoints self._model.masteryPoints = self._economics.experience def dispose(self): if self._updateRateSubscription: self._updateRateSubscription.unsubscribe() self._updateRateSubscription = None self._economics.onUpdateBattlePoints -= self._updatePlayerEconomics self._clientArena.onGameResultChanged -= self._update self._model = None self._bigWorld = None return