Advertisement
Guest User

Untitled

a guest
May 1st, 2014
1,839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 85.45 KB | None | 0 0
  1. """
  2. WOT VERSION: 0.9.0
  3. WOT SERVER : EU/NA/RU
  4. =======================
  5. KT BASE CAPTURE SOUND
  6. =======================
  7. ----------------------
  8. (c) Kriegstreiber 2014
  9. ----------------------
  10. """
  11. import weakref
  12. import BigWorld
  13. import ResMgr
  14. import FMOD
  15. import GUI
  16. import Math
  17. import math
  18. import VOIP
  19. import SoundGroups
  20. import Vehicle
  21. import constants
  22. import BattleReplay
  23. import CommandMapping
  24. from account_helpers.AccountSettings import AccountSettings
  25. from account_helpers.SettingsCore import g_settingsCore
  26. from gui.Scaleform.battle_arena_ctrl import BattleArenaController
  27. from gui.Scaleform.PlayersPanel import PlayersPanel
  28. from gui.arena_info.arena_vos import VehicleActions
  29. from gui.prb_control.formatters import getPrebattleFullDescription
  30. from gui.shared.utils.key_mapping import getScaleformKey
  31. from messenger import MessengerEntry, g_settings
  32. import nations
  33. from windows import BattleWindow
  34. from SettingsInterface import SettingsInterface
  35. from debug_utils import LOG_CURRENT_EXCEPTION, LOG_DEBUG, LOG_ERROR, LOG_CODEPOINT_WARNING
  36. from helpers import i18n, html, isPlayerAvatar, getClientLanguage
  37. from helpers.i18n import makeString
  38. from PlayerEvents import g_playerEvents
  39. from MemoryCriticalController import g_critMemHandler
  40. from items.vehicles import NUM_EQUIPMENT_SLOTS, VEHICLE_CLASS_TAGS
  41. from gui import DEPTH_OF_Battle, DEPTH_OF_VehicleMarker, TANKMEN_ROLES_ORDER_DICT, GUI_SETTINGS, g_tankActiveCamouflage, g_guiResetters, g_repeatKeyHandlers
  42. from gui.BattleContext import g_battleContext, PLAYER_ENTITY_NAME
  43. from gui.Scaleform import VoiceChatInterface, ColorSchemeManager
  44. from gui.Scaleform.SoundManager import SoundManager
  45. from gui.shared.utils.sound import Sound
  46. from gui.shared.utils.functions import getBattleSubTypeBaseNumder, isControlPointExists
  47. from gui.Scaleform.Flash import Flash
  48. from gui.Scaleform.windows import UIInterface
  49. from gui.Scaleform.MovingText import MovingText
  50. from gui.Scaleform.Minimap import Minimap
  51. from gui.Scaleform.RadialMenu import RadialMenu
  52. from gui.Scaleform.CursorDelegator import g_cursorDelegator
  53. from gui.Scaleform.ingame_help import IngameHelp
  54. from gui.shared.gui_items.Vehicle import VEHICLE_BATTLE_TYPES_ORDER_INDICES
  55. from gui.Scaleform import SCALEFORM_SWF_PATH
  56. _CONTOUR_ICONS_MASK = '../maps/icons/vehicle/contour/%(unicName)s.png'
  57. _BASE_CAPTURE_SOUND_NAME_ENEMY = '/GUI/notifications_FX/base_capture_siren/WWIIHWA'
  58. _BASE_CAPTURE_SOUND_NAME_ALLY = '/GUI/notifications_FX/base_capture_siren/WWIIHWA'
  59. _BATTLE_START_NOTIFICATION_TIME = 5.0
  60. _CFG = {}
  61. CONFIG = ResMgr.openSection('gui/base_capture.xml')
  62. if CONFIG is not None:
  63.     try:
  64.         _CFG['base_capture_sound_enemy'] = CONFIG.readString('base_capture_sound', '/GUI/notifications_FX/base_capture_siren/WWIIHWA')
  65.         _CFG['base_capture_sound_ally'] = CONFIG.readString('base_capture_sound', '/GUI/notifications_FX/base_capture_siren/WWIIHWA')
  66.         _BASE_CAPTURE_SOUND_NAME_ENEMY = _CFG['base_capture_sound_enemy']
  67.         _BASE_CAPTURE_SOUND_NAME_ALLY = _CFG['base_capture_sound_ally']
  68.         print '[NOTE] WWIIHWA Ambiente: base_capture_sound set to: ' + _BASE_CAPTURE_SOUND_NAME_ALLY
  69.     except:
  70.         LOG_CURRENT_EXCEPTION()
  71.  
  72. def _changeStringCasing(string, isUpper):
  73.     langID = getClientLanguage()
  74.     if langID == 'tr':
  75.         return BigWorld.wg_changeStringCasing(string, 31, 1, 0, isUpper)
  76.     if langID == 'ro':
  77.         return BigWorld.wg_changeStringCasing(string, 24, 1, 0, isUpper)
  78.     if isUpper:
  79.         return string.upper()
  80.     return string.lower()
  81.  
  82.  
  83. def _toUpper(string):
  84.     return _changeStringCasing(string, True)
  85.  
  86.  
  87. def _toLower(string):
  88.     return _changeStringCasing(string, False)
  89.  
  90.  
  91. class Battle(BattleWindow):
  92.     teamBasesPanel = property(lambda self: self.__teamBasesPanel)
  93.     consumablesPanel = property(lambda self: self.__consumablesPanel)
  94.     damagePanel = property(lambda self: self.__damagePanel)
  95.     vMarkersManager = property(lambda self: self.__vMarkersManager)
  96.     vErrorsPanel = property(lambda self: self.__vErrorsPanel)
  97.     vMsgsPanel = property(lambda self: self.__vMsgsPanel)
  98.     pMsgsPanel = property(lambda self: self.__pMsgsPanel)
  99.     minimap = property(lambda self: self.__minimap)
  100.     radialMenu = property(lambda self: self.__radialMenu)
  101.     damageInfoPanel = property(lambda self: self.__damageInfoPanel)
  102.     fragCorrelation = property(lambda self: self.__fragCorrelation)
  103.     leftPlayersPanel = property(lambda self: self.__leftPlayersPanel)
  104.     rightPlayersPanel = property(lambda self: self.__rightPlayersPanel)
  105.     VEHICLE_DESTROY_TIMER = {'ALL': 'all',
  106.      constants.VEHICLE_MISC_STATUS.VEHICLE_DROWN_WARNING: 'drown',
  107.      constants.VEHICLE_MISC_STATUS.VEHICLE_IS_OVERTURNED: 'overturn',
  108.      constants.VEHICLE_MISC_STATUS.IN_DEATH_ZONE: 'death_zone'}
  109.     DENUNCIATIONS = {'bot': constants.DENUNCIATION.BOT,
  110.      'flood': constants.DENUNCIATION.FLOOD,
  111.      'offend': constants.DENUNCIATION.OFFEND,
  112.      'notFairPlay': constants.DENUNCIATION.NOT_FAIR_PLAY,
  113.      'forbiddenNick': constants.DENUNCIATION.FORBIDDEN_NICK,
  114.      'swindle': constants.DENUNCIATION.SWINDLE,
  115.      'blackmail': constants.DENUNCIATION.BLACKMAIL}
  116.     _speakPlayers = {}
  117.     __cameraVehicleID = -1
  118.  
  119.     def __init__(self):
  120.         self.__soundManager = None
  121.         self.__timerCallBackId = None
  122.         self.__arena = BigWorld.player().arena
  123.         self.__playersPanelStateChanged = False
  124.         self.__battleNotificationExecuted = False
  125.         BattleWindow.__init__(self, 'battle.swf')
  126.         self.__timerSound = Sound('/GUI/notifications_FX/timer')
  127.         self.__isTimerVisible = False
  128.         self.__isHelpWindowShown = False
  129.         self.component.wg_inputKeyMode = 1
  130.         self.component.position.z = DEPTH_OF_Battle
  131.         self.movie.backgroundAlpha = 0
  132.         self.addFsCallbacks({'battle.leave': self.onExitBattle})
  133.         self.addExternalCallbacks({'battle.showCursor': self.cursorVisibility,
  134.          'battle.tryLeaveRequest': self.tryLeaveRequest,
  135.          'Battle.UsersRoster.Appeal': self.onDenunciationReceived,
  136.          'Battle.playersPanelStateChange': self.onPlayersPanelStateChange,
  137.          'Battle.selectPlayer': self.selectPlayer,
  138.          'battle.helpDialogOpenStatus': self.helpDialogOpenStatus})
  139.         BigWorld.wg_setRedefineKeysMode(False)
  140.         self.onPostmortemVehicleChanged(BigWorld.player().playerVehicleID)
  141.         return
  142.  
  143.     def getCameraVehicleID(self):
  144.         return self.__cameraVehicleID
  145.  
  146.     def showAll(self, isShow):
  147.         self.call('battle.showAll', [isShow])
  148.         self.__vMarkersManager.active(isShow)
  149.  
  150.     def showCursor(self, isShow):
  151.         self.cursorVisibility(-1, isShow)
  152.  
  153.     def onPlayersPanelStateChange(self, cid, state):
  154.         ppSettings = dict(AccountSettings.getSettings('players_panel'))
  155.         ppSettings['state'] = state
  156.         AccountSettings.setSettings('players_panel', ppSettings)
  157.         self.__playersPanelStateChanged = True
  158.  
  159.     @property
  160.     def soundManager(self):
  161.         return self.__soundManager
  162.  
  163.     def selectPlayer(self, cid, vehId):
  164.         player = BigWorld.player()
  165.         if isPlayerAvatar():
  166.             player.selectPlayer(int(vehId))
  167.  
  168.     def onDenunciationReceived(self, cid, uid, userName, topic):
  169.         topicID = self.DENUNCIATIONS.get(topic)
  170.         if topicID is not None:
  171.             self.__makeDenunciation(uid, userName, topicID)
  172.         return
  173.  
  174.     def __makeDenunciation(self, uid, userName, topicID):
  175.         player = BigWorld.player()
  176.         violatorKind = constants.VIOLATOR_KIND.UNKNOWN
  177.         for id, p in player.arena.vehicles.iteritems():
  178.             if p['accountDBID'] == uid:
  179.                 violatorKind = constants.VIOLATOR_KIND.ALLY if player.team == p['team'] else constants.VIOLATOR_KIND.ENEMY
  180.  
  181.         player.makeDenunciation(uid, topicID, violatorKind)
  182.         self.__arenaCtrl.invalidateGUI()
  183.         topicStr = makeString('#menu:denunciation/%d' % topicID)
  184.         message = makeString('#system_messages:denunciation/success') % {'name': userName,
  185.          'topic': topicStr}
  186.         MessengerEntry.g_instance.gui.addClientMessage(g_settings.htmlTemplates.format('battleErrorMessage', ctx={'error': message}))
  187.  
  188.     def onPostmortemVehicleChanged(self, id):
  189.         if self.__cameraVehicleID == id:
  190.             return
  191.         else:
  192.             self.__cameraVehicleID = id
  193.             self.__setPlayerInfo(id)
  194.             self.__arenaCtrl.invalidateGUI(True)
  195.             self.__damagePanel.switchToVehicle(id)
  196.             self.hideVehicleTimer('ALL')
  197.             self.vErrorsPanel.clear()
  198.             self.vMsgsPanel.clear()
  199.             aim = BigWorld.player().inputHandler.aim
  200.             if aim is not None:
  201.                 aim.updateAmmoState(True)
  202.             return
  203.  
  204.     def onCameraChanged(self, cameraMode, curVehID = None):
  205.         LOG_DEBUG('onCameraChanged', cameraMode, curVehID)
  206.         self.damagePanel.showAll(cameraMode != 'video')
  207.  
  208.         def setVisible(cname):
  209.             m = self.getMember(cname)
  210.             if m is not None:
  211.                 m.visible = cameraMode != 'video'
  212.             return
  213.  
  214.         setVisible('vehicleMessagesPanel')
  215.         setVisible('vehicleErrorsPanel')
  216.         if cameraMode == 'video':
  217.             self.__cameraVehicleID = -1
  218.             self.damagePanel._reset()
  219.             self.vErrorsPanel.clear()
  220.             self.vMsgsPanel.clear()
  221.             self.hideVehicleTimer('ALL')
  222.             aim = BigWorld.player().inputHandler.aim
  223.             if aim is not None:
  224.                 aim.updateAmmoState(True)
  225.         aim = BigWorld.player().inputHandler.aim
  226.         if aim is not None:
  227.             aim.onCameraChange()
  228.         return
  229.  
  230.     def showVehicleTimer(self, code, time, warnLvl = 'critical'):
  231.         LOG_DEBUG('show vehicles destroy timer', code, time, warnLvl)
  232.         self.call('destroyTimer.show', [self.VEHICLE_DESTROY_TIMER[code], time, warnLvl])
  233.  
  234.     def hideVehicleTimer(self, code):
  235.         LOG_DEBUG('hide vehicles destroy timer', code)
  236.         self.call('destroyTimer.hide', [self.VEHICLE_DESTROY_TIMER[code]])
  237.  
  238.     def setVehicleTimerPosition(self, code, time, warnLvl, position):
  239.         self.call('destroyTimer.setTimerPosition', [self.VEHICLE_DESTROY_TIMER[code],
  240.          time,
  241.          warnLvl,
  242.          position])
  243.  
  244.     def showSixthSenseIndicator(self, isShow):
  245.         self.call('sixthSenseIndicator.show', [isShow])
  246.  
  247.     def speakingPlayersReset(self):
  248.         for id in self._speakPlayers.keys():
  249.             self.setPlayerSpeaking(id, False)
  250.  
  251.         self._speakPlayers.clear()
  252.  
  253.     def setVisible(self, bool):
  254.         LOG_DEBUG('[Battle] visible', bool)
  255.         self.component.visible = bool
  256.  
  257.     def afterCreate(self):
  258.         player = BigWorld.player()
  259.         LOG_DEBUG('[Battle] afterCreate')
  260.         setattr(self.movie, '_global.wg_isShowLanguageBar', GUI_SETTINGS.isShowLanguageBar)
  261.         setattr(self.movie, '_global.wg_isShowVoiceChat', GUI_SETTINGS.voiceChat)
  262.         setattr(self.movie, '_global.wg_voiceChatProvider', VoiceChatInterface.g_instance.voiceChatProvider)
  263.         setattr(self.movie, '_global.wg_isChina', constants.IS_CHINA)
  264.         setattr(self.movie, '_global.wg_isKorea', constants.IS_KOREA)
  265.         BattleWindow.afterCreate(self)
  266.         g_playerEvents.onBattleResultsReceived += self.__showFinalStatsResults
  267.         BigWorld.wg_setScreenshotNotifyCallback(self.__screenshotNotifyCallback)
  268.         player.inputHandler.onPostmortemVehicleChanged += self.onPostmortemVehicleChanged
  269.         player.inputHandler.onCameraChanged += self.onCameraChanged
  270.         g_settingsCore.onSettingsChanged += self.__accs_onSettingsChanged
  271.         if self.__arena:
  272.             self.__arena.onPeriodChange += self.__onSetArenaTime
  273.         self.proxy = weakref.proxy(self)
  274.         self._speakPlayers.clear()
  275.         VoiceChatInterface.g_instance.populateUI(self.proxy)
  276.         self.colorManager = ColorSchemeManager._ColorSchemeManager()
  277.         self.colorManager.populateUI(self.proxy)
  278.         self.movingText = MovingText()
  279.         self.movingText.populateUI(self.proxy)
  280.         self.__settingsInterface = SettingsInterface()
  281.         self.__settingsInterface.populateUI(self.proxy)
  282.         self.__soundManager = SoundManager()
  283.         self.__soundManager.populateUI(self.proxy)
  284.         self.__teamBasesPanel = TeamBasesPanel(self.proxy)
  285.         self.__fragCorrelation = FragCorrelationPanel(self.proxy)
  286.         self.__debugPanel = DebugPanel(self.proxy)
  287.         self.__consumablesPanel = ConsumablesPanel(self.proxy)
  288.         self.__damagePanel = DamagePanel(self.proxy)
  289.         self.__vMarkersManager = VehicleMarkersManager(self.proxy)
  290.         self.__ingameHelp = IngameHelp(self.proxy)
  291.         self.__minimap = Minimap(self.proxy)
  292.         self.__radialMenu = RadialMenu(self.proxy)
  293.         isColorBlind = AccountSettings.getSettings('isColorBlind')
  294.         self.__leftPlayersPanel = PlayersPanel(self.proxy, True, isColorBlind=isColorBlind)
  295.         self.__rightPlayersPanel = PlayersPanel(self.proxy, False, isColorBlind=isColorBlind)
  296.         self.isVehicleCountersVisible = g_settingsCore.getSetting('showVehiclesCounter')
  297.         self.__fragCorrelation.showVehiclesCounter(self.isVehicleCountersVisible)
  298.         self.__damageInfoPanel = VehicleDamageInfoPanel(self.proxy)
  299.         self.__vErrorsPanel = FadingMessagesPanel(self.proxy, 'VehicleErrorsPanel', 'gui/vehicle_errors_panel.xml', isColorBlind=isColorBlind)
  300.         self.__vMsgsPanel = FadingMessagesPanel(self.proxy, 'VehicleMessagesPanel', 'gui/vehicle_messages_panel.xml', isColorBlind=isColorBlind)
  301.         self.__pMsgsPanel = FadingMessagesPanel(self.proxy, 'PlayerMessagesPanel', 'gui/player_messages_panel.xml', isColorBlind=isColorBlind)
  302.         self.__teamBasesPanel.start()
  303.         self.__debugPanel.start()
  304.         self.__consumablesPanel.start()
  305.         self.__damagePanel.start()
  306.         self.__ingameHelp.start()
  307.         self.__vErrorsPanel.start()
  308.         self.__vMsgsPanel.start()
  309.         self.__pMsgsPanel.start()
  310.         self.__vMarkersManager.start()
  311.         self.__vMarkersManager.setMarkerDuration(GUI_SETTINGS.markerHitSplashDuration)
  312.         markers = {'enemy': g_settingsCore.getSetting('enemy'),
  313.          'dead': g_settingsCore.getSetting('dead'),
  314.          'ally': g_settingsCore.getSetting('ally')}
  315.         self.__vMarkersManager.setMarkerSettings(markers)
  316.         self.__initMemoryCriticalHandlers()
  317.         MessengerEntry.g_instance.gui.invoke('populateUI', self.proxy)
  318.         g_guiResetters.add(self.__onRecreateDevice)
  319.         g_repeatKeyHandlers.add(self.component.handleKeyEvent)
  320.         self.__onRecreateDevice()
  321.         self.__setPlayerInfo(player.playerVehicleID)
  322.         self.__leftPlayersPanel.populateUI(self.proxy)
  323.         self.__rightPlayersPanel.populateUI(self.proxy)
  324.         self.__populateData()
  325.         self.__minimap.start()
  326.         self.__radialMenu.setSettings(self.__settingsInterface)
  327.         self.__radialMenu.populateUI(self.proxy)
  328.         self.__arenaCtrl = BattleArenaController(self)
  329.         g_battleContext.addArenaCtrl(self.__arenaCtrl)
  330.         BigWorld.callback(1, self.__setArenaTime)
  331.         self.updateFlagsColor()
  332.         VoiceChatInterface.g_instance.onVoiceChatInitFailed += self.onVoiceChatInitFailed
  333.         self.movie.setFocussed(SCALEFORM_SWF_PATH)
  334.         if self.__arena.period == constants.ARENA_PERIOD.BATTLE:
  335.             self.call('players_panel.setState', [AccountSettings.getSettings('players_panel')['state']])
  336.         else:
  337.             self.call('players_panel.setState', ['large'])
  338.         self.call('sixthSenseIndicator.setDuration', [GUI_SETTINGS.sixthSenseDuration])
  339.         g_tankActiveCamouflage[player.vehicleTypeDescriptor.type.compactDescr] = self.__arena.arenaType.vehicleCamouflageKind
  340.         if BattleReplay.g_replayCtrl.isPlaying:
  341.             BattleReplay.g_replayCtrl.onBattleSwfLoaded()
  342.         player.battleMessages.onShowPlayerMessage += self.onShowPlayerMessage
  343.         player.battleMessages.onShowVehicleMessage += self.onShowVehicleMessage
  344.         keyCode = CommandMapping.g_instance.get('CMD_VOICECHAT_MUTE')
  345.         if not BigWorld.isKeyDown(keyCode):
  346.             VOIP.getVOIPManager().setMicMute(True)
  347.  
  348.     def beforeDelete(self):
  349.         LOG_DEBUG('[Battle] beforeDelete')
  350.         if self.colorManager:
  351.             self.colorManager.dispossessUI()
  352.         if VoiceChatInterface.g_instance:
  353.             VoiceChatInterface.g_instance.dispossessUI(self.proxy)
  354.         self.__destroyMemoryCriticalHandlers()
  355.         if self.movingText is not None:
  356.             self.movingText.dispossessUI()
  357.             self.movingText = None
  358.         if self.__soundManager is not None:
  359.             self.__soundManager.dispossessUI()
  360.             self.__soundManager = None
  361.         if self.colorManager is not None:
  362.             self.colorManager.dispossessUI()
  363.             self.colorManager = None
  364.         if self.component:
  365.             g_repeatKeyHandlers.discard(self.component.handleKeyEvent)
  366.         g_settingsCore.onSettingsChanged -= self.__accs_onSettingsChanged
  367.         self.__teamBasesPanel.destroy()
  368.         self.__debugPanel.destroy()
  369.         self.__consumablesPanel.destroy()
  370.         self.__damagePanel.destroy()
  371.         self.__vMarkersManager.destroy()
  372.         self.__ingameHelp.destroy()
  373.         self.__vErrorsPanel.destroy()
  374.         self.__vMsgsPanel.destroy()
  375.         self.__pMsgsPanel.destroy()
  376.         self.__radialMenu.destroy()
  377.         self.__minimap.destroy()
  378.         self.__timerSound.stop()
  379.         if self.__arenaCtrl is not None:
  380.             g_battleContext.removeArenaCtrl(self.__arenaCtrl)
  381.             self.__arenaCtrl.destroy()
  382.             self.__arenaCtrl = None
  383.         MessengerEntry.g_instance.gui.invoke('dispossessUI')
  384.         g_playerEvents.onBattleResultsReceived -= self.__showFinalStatsResults
  385.         if self.__arena:
  386.             self.__arena.onPeriodChange -= self.__onSetArenaTime
  387.         self.__arena = None
  388.         g_guiResetters.discard(self.__onRecreateDevice)
  389.         self.__settingsInterface.dispossessUI()
  390.         self.__settingsInterface = None
  391.         VoiceChatInterface.g_instance.onVoiceChatInitFailed -= self.onVoiceChatInitFailed
  392.         BattleWindow.beforeDelete(self)
  393.         return
  394.  
  395.     def __screenshotNotifyCallback(self, path):
  396.         self.vMsgsPanel.showMessage('SCREENSHOT_CREATED', {'path': i18n.encodeUtf8(path)})
  397.  
  398.     def onVoiceChatInitFailed(self):
  399.         if GUI_SETTINGS.voiceChat:
  400.             self.call('VoiceChat.initFailed', [])
  401.  
  402.     def onShowPlayerMessage(self, code, postfix, targetID, attackerID):
  403.         targetInfo = self.__arena.vehicles.get(targetID)
  404.         attackerInfo = self.__arena.vehicles.get(attackerID)
  405.         LOG_DEBUG('onShowPlayerMessage', code, postfix, targetID, attackerID)
  406.         self.pMsgsPanel.showMessage(code, {'target': g_battleContext.getFullPlayerName(targetInfo, showClan=False),
  407.          'attacker': g_battleContext.getFullPlayerName(attackerInfo, showClan=False)}, extra=(('target', targetID), ('attacker', attackerID)), postfix=postfix)
  408.  
  409.     def onShowVehicleMessage(self, code, postfix, entityID, extra):
  410.         LOG_DEBUG('onShowVehicleMessage', code, postfix, entityID, extra)
  411.         names = {'device': '',
  412.          'entity': '',
  413.          'target': ''}
  414.         if extra is not None:
  415.             names['device'] = extra.deviceUserString
  416.         if entityID:
  417.             targetInfo = self.__arena.vehicles.get(entityID)
  418.             if targetInfo is None:
  419.                 LOG_CODEPOINT_WARNING()
  420.                 return
  421.             names['entity'] = g_battleContext.getFullPlayerName(targetInfo)
  422.         self.vMsgsPanel.showMessage(code, names, postfix=postfix)
  423.         return
  424.  
  425.     def clearCommands(self):
  426.         pass
  427.  
  428.     def bindCommands(self):
  429.         self.__consumablesPanel.bindCommands()
  430.         self.__ingameHelp.buildCmdMapping()
  431.  
  432.     def updateFlagsColor(self):
  433.         isColorBlind = AccountSettings.getSettings('isColorBlind')
  434.         colorGreen = self.colorManager.getSubScheme('flag_team_green', isColorBlind=isColorBlind)['rgba']
  435.         colorRed = self.colorManager.getSubScheme('flag_team_red', isColorBlind=isColorBlind)['rgba']
  436.         if 1 == BigWorld.player().team:
  437.             BigWorld.wg_setFlagColor(1, colorGreen / 255)
  438.             BigWorld.wg_setFlagColor(2, colorRed / 255)
  439.         else:
  440.             BigWorld.wg_setFlagColor(2, colorGreen / 255)
  441.             BigWorld.wg_setFlagColor(1, colorRed / 255)
  442.         BigWorld.wg_setFlagEmblem(0, 'system/maps/wg_emblem.dds', Math.Vector4(0.0, 0.1, 0.5, 0.9))
  443.         BigWorld.wg_setFlagEmblem(1, 'system/maps/wg_emblem.dds', Math.Vector4(0.0, 0.1, 0.5, 0.9))
  444.         BigWorld.wg_setFlagEmblem(2, 'system/maps/wg_emblem.dds', Math.Vector4(0.0, 0.1, 0.5, 0.9))
  445.  
  446.     def setPlayerSpeaking(self, accountDBID, flag):
  447.         if not GUI_SETTINGS.voiceChat:
  448.             return
  449.         self._speakPlayers[accountDBID] = flag
  450.         self.__callEx('setPlayerSpeaking', [accountDBID, flag])
  451.         vID = g_battleContext.getVehIDByAccDBID(accountDBID)
  452.         if vID > 0:
  453.             self.__vMarkersManager.showDynamic(vID, flag)
  454.  
  455.     def isPlayerSpeaking(self, accountDBID):
  456.         if GUI_SETTINGS.voiceChat:
  457.             return self._speakPlayers.get(accountDBID, False)
  458.         else:
  459.             return False
  460.  
  461.     def showPostmortemTips(self):
  462.         if self.radialMenu is not None:
  463.             self.radialMenu.forcedHide()
  464.         if not g_battleContext.isPlayerObserver():
  465.             self.__callEx('showPostmortemTips', [1.0, 5.0, 1.0])
  466.         return
  467.  
  468.     def cursorVisibility(self, callbackId, visible, x = None, y = None, customCall = False, enableAiming = True):
  469.         if visible:
  470.             g_cursorDelegator.syncMousePosition(self, x, y, customCall)
  471.         else:
  472.             g_cursorDelegator.restoreMousePosition()
  473.         if BigWorld.player() is not None and isPlayerAvatar():
  474.             BigWorld.player().setForcedGuiControlMode(visible, False, enableAiming)
  475.         return
  476.  
  477.     def tryLeaveRequest(self, _):
  478.         resStr = 'quitBattle'
  479.         replayCtrl = BattleReplay.g_replayCtrl
  480.         if not replayCtrl.isPlaying and constants.IS_KOREA and self.__arena is not None and self.__arena.guiType != constants.ARENA_GUI_TYPE.TRAINING:
  481.             player = BigWorld.player()
  482.             vehicleID = getattr(player, 'playerVehicleID', -1)
  483.             isVehicleAlive = getattr(player, 'isVehicleAlive', 0)
  484.             if vehicleID in self.__arena.vehicles:
  485.                 vehicle = self.__arena.vehicles[vehicleID]
  486.                 if isVehicleAlive and vehicle.get('igrType') != constants.IGR_TYPE.NONE:
  487.                     resStr = 'quitBattleIGR'
  488.             else:
  489.                 LOG_ERROR("Player's vehicle not found", vehicleID)
  490.         self.__callEx('tryLeaveResponse', [resStr])
  491.         return
  492.  
  493.     def onExitBattle(self, arg):
  494.         arena = getattr(BigWorld.player(), 'arena', None)
  495.         LOG_DEBUG('onExitBattle', arena)
  496.         if arena:
  497.             BigWorld.player().leaveArena()
  498.         return
  499.  
  500.     def toggleHelpWindow(self):
  501.         self.__callEx('showHideHelp', [not self.__isHelpWindowShown])
  502.  
  503.     def helpDialogOpenStatus(self, cid, isOpened):
  504.         self.__isHelpWindowShown = isOpened
  505.  
  506.     def __setPlayerInfo(self, vID):
  507.         playerName, pName, clanAbbrev, regionCode, vTypeName = ('', '', '', '', '')
  508.         vInfo = self.__arena.vehicles.get(vID)
  509.         if vInfo is not None:
  510.             playerName, pName, clanAbbrev, regionCode, _ = g_battleContext.getFullPlayerNameWithParts(vInfo, showVehShortName=False)
  511.             vTypeName = vInfo['vehicleType'].type.userString
  512.         self.__callEx('setPlayerInfo', [playerName,
  513.          pName,
  514.          clanAbbrev,
  515.          regionCode,
  516.          vTypeName])
  517.         return
  518.  
  519.     def __populateData(self):
  520.         from gui.shared.utils.functions import getBattleSubTypeWinText, getArenaSubTypeName, isBaseExists
  521.         arena = getattr(BigWorld.player(), 'arena', None)
  522.         arenaData = ['',
  523.          0,
  524.          '',
  525.          '',
  526.          '']
  527.         if arena:
  528.             arenaData = [_toUpper(arena.arenaType.name)]
  529.             descExtra = getPrebattleFullDescription(arena.extraData or {})
  530.             arenaSubType = getArenaSubTypeName(BigWorld.player().arenaTypeID)
  531.             if descExtra:
  532.                 arenaData.extend([arena.guiType + 1, descExtra])
  533.             elif arena.guiType in [constants.ARENA_GUI_TYPE.RANDOM, constants.ARENA_GUI_TYPE.TRAINING]:
  534.                 arenaTypeName = '#arenas:type/%s/name' % arenaSubType
  535.                 if arenaSubType == 'assault':
  536.                     arenaSubType += '1' if isBaseExists(BigWorld.player().arenaTypeID, BigWorld.player().team) else '2'
  537.                 arenaData.extend([arenaSubType, arenaTypeName])
  538.             else:
  539.                 arenaData.extend([arena.guiType + 1, '#menu:loading/battleTypes/%d' % arena.guiType])
  540.             extraData = arena.extraData or {}
  541.             myTeam = BigWorld.player().team
  542.             team1 = extraData.get('opponents', {}).get('%s' % myTeam, {}).get('name', '#menu:loading/team1')
  543.             team2 = extraData.get('opponents', {}).get('2' if myTeam == 1 else '1', {}).get('name', '#menu:loading/team2')
  544.             arenaData.extend([team1, team2])
  545.             teamHasBase = 1 if isBaseExists(BigWorld.player().arenaTypeID, myTeam) else 2
  546.             winText = getBattleSubTypeWinText(BigWorld.player().arenaTypeID, teamHasBase)
  547.             arenaData.append(winText)
  548.         self.__callEx('arenaData', arenaData)
  549.         return
  550.  
  551.     def __showFinalStatsResults(self, isActiveVehicle, results):
  552.         if isActiveVehicle:
  553.             if GUI_SETTINGS.battleStatsInHangar:
  554.                 if self.__arena:
  555.                     g_battleContext.lastArenaUniqueID = self.__arena.arenaUniqueID
  556.             self.onExitBattle(None)
  557.         return
  558.  
  559.     def __showFinalStats(self, winnerTeam, reason):
  560.         if hasattr(BigWorld.player(), 'team'):
  561.             status = 'tie' if winnerTeam == 0 else ('win' if winnerTeam == BigWorld.player().team else 'lose')
  562.             status = makeString('#menu:finalStatistic/commonStats/resultlabel/%s' % status)
  563.             self.__callEx('showStatus', [status])
  564.  
  565.     def __hideTimer(self):
  566.         self.__callEx('showBattleTimer', [False])
  567.  
  568.     def __onSetArenaTime(self, *args):
  569.         if self.__timerCallBackId is not None:
  570.             BigWorld.cancelCallback(self.__timerCallBackId)
  571.         self.__setArenaTime()
  572.         return
  573.  
  574.     def __setArenaTime(self):
  575.         self.__timerCallBackId = None
  576.         if self.__arena is None:
  577.             return
  578.         else:
  579.             skipGUIMessages = False
  580.             replayCtrl = BattleReplay.g_replayCtrl
  581.             if replayCtrl.isPlaying:
  582.                 period = replayCtrl.getArenaPeriod()
  583.                 arenaLengthExact = replayCtrl.getArenaLength()
  584.                 arenaLength = int(arenaLengthExact)
  585.                 if period == 0:
  586.                     self.__timerCallBackId = BigWorld.callback(1, self.__setArenaTime)
  587.                     return
  588.                 skipGUIMessages = replayCtrl.isTimeWarpInProgress
  589.             else:
  590.                 period = self.__arena.period
  591.                 arenaLengthExact = self.__arena.periodEndTime - BigWorld.serverTime()
  592.                 arenaLength = int(arenaLengthExact)
  593.                 if period == constants.ARENA_PERIOD.PREBATTLE:
  594.                     if arenaLength <= _BATTLE_START_NOTIFICATION_TIME and not self.__battleNotificationExecuted:
  595.                         BigWorld.WGWindowsNotifier.onBattleBeginning()
  596.                         self.__battleNotificationExecuted = True
  597.                 else:
  598.                     self.__battleNotificationExecuted = False
  599.                 if replayCtrl.isRecording:
  600.                     replayCtrl.setArenaPeriod(period, arenaLengthExact)
  601.             arenaLength = arenaLength if arenaLength > 0 else 0
  602.             if period != constants.ARENA_PERIOD.AFTERBATTLE:
  603.                 if replayCtrl.isPlaying:
  604.                     if replayCtrl.isFinished() == False:
  605.                         self.__callEx('timerBar.setTotalTime', [arenaLength])
  606.                 else:
  607.                     self.__callEx('timerBar.setTotalTime', [arenaLength])
  608.             if skipGUIMessages == False:
  609.                 if period == constants.ARENA_PERIOD.WAITING:
  610.                     self.__callEx('timerBig.setTimer', [makeString('#ingame_gui:timer/waiting')])
  611.                     self.__isTimerVisible = True
  612.                 elif period == constants.ARENA_PERIOD.PREBATTLE:
  613.                     self.__callEx('timerBig.setTimer', [makeString('#ingame_gui:timer/starting'), arenaLength])
  614.                     self.__isTimerVisible = True
  615.                     if self.__timerSound.isPlaying == False and arenaLengthExact >= 0.0:
  616.                         self.__timerSound.play()
  617.                     if self.__timerSound.isPlaying and arenaLengthExact < 0.0:
  618.                         self.__timerSound.stop()
  619.                 elif period == constants.ARENA_PERIOD.BATTLE and self.__isTimerVisible:
  620.                     self.__isTimerVisible = False
  621.                     self.__timerSound.stop()
  622.                     self.__callEx('timerBig.setTimer', [makeString('#ingame_gui:timer/started')])
  623.                     self.__callEx('timerBig.hide')
  624.                     if not self.__playersPanelStateChanged:
  625.                         userState = AccountSettings.getSettings('players_panel')['state']
  626.                         self.call('players_panel.setState', ['none'])
  627.                         self.call('players_panel.setState', [userState])
  628.                 elif period == constants.ARENA_PERIOD.AFTERBATTLE:
  629.                     self.__hideTimer()
  630.                     self.consumablesPanel._isOptDeviceEnabled = False
  631.             if replayCtrl.isPlaying:
  632.                 self.__timerCallBackId = BigWorld.callback(0.0, self.__setArenaTime)
  633.             elif arenaLengthExact > 1:
  634.                 self.__timerCallBackId = BigWorld.callback(1.0, self.__setArenaTime)
  635.             else:
  636.                 self.__timerCallBackId = BigWorld.callback(0.0, self.__setArenaTime)
  637.             return
  638.  
  639.     def __onRecreateDevice(self):
  640.         self.call('Stage.Update', list(GUI.screenResolution()))
  641.  
  642.     def __callEx(self, funcName, args = None):
  643.         self.call('battle.' + funcName, args)
  644.  
  645.     def __initMemoryCriticalHandlers(self):
  646.         for message in g_critMemHandler.messages:
  647.             self.__onMemoryCritical(message)
  648.  
  649.         g_critMemHandler.onMemCrit += self.__onMemoryCritical
  650.  
  651.     def __destroyMemoryCriticalHandlers(self):
  652.         g_critMemHandler.onMemCrit -= self.__onMemoryCritical
  653.  
  654.     def __onMemoryCritical(self, message):
  655.         self.__vMsgsPanel.showMessage(message[1])
  656.  
  657.     def __accs_onSettingsChanged(self, diff):
  658.         self.colorManager.update()
  659.         if 'isColorBlind' in diff:
  660.             isColorBlind = diff['isColorBlind']
  661.             self.__vErrorsPanel.defineColorFlags(isColorBlind=isColorBlind)
  662.             self.__vMsgsPanel.defineColorFlags(isColorBlind=isColorBlind)
  663.             self.__pMsgsPanel.defineColorFlags(isColorBlind=isColorBlind)
  664.             self.__leftPlayersPanel.defineColorFlags(isColorBlind=isColorBlind)
  665.             self.__rightPlayersPanel.defineColorFlags(isColorBlind=isColorBlind)
  666.             self.updateFlagsColor()
  667.             self.__vMarkersManager.updateMarkers()
  668.             self.__minimap.updateEntries()
  669.         if 'enemy' in diff or 'dead' in diff or 'ally' in diff:
  670.             markers = {'enemy': g_settingsCore.getSetting('enemy'),
  671.              'dead': g_settingsCore.getSetting('dead'),
  672.              'ally': g_settingsCore.getSetting('ally')}
  673.             self.vMarkersManager.setMarkerSettings(markers)
  674.             self.__vMarkersManager.updateMarkerSettings()
  675.         if 'showVehiclesCounter' in diff:
  676.             self.isVehicleCountersVisible = diff['showVehiclesCounter']
  677.             self.__fragCorrelation.showVehiclesCounter(self.isVehicleCountersVisible)
  678.         self.__arenaCtrl.invalidateGUI()
  679.         self.__arenaCtrl.invalidateArenaInfo()
  680.  
  681.     def __getEntityUserString(self, entityName):
  682.         player = BigWorld.player()
  683.         if player and player.isVehicleAlive:
  684.             extra = player.vehicleTypeDescriptor.extrasDict.get(entityName + 'Health')
  685.             if extra is None:
  686.                 return entityName
  687.             return extra.deviceUserString
  688.         else:
  689.             return
  690.  
  691.     def _showTankmanIsSafeMessage(self, entityName):
  692.         if not self.__consumablesPanel.hasMedkit():
  693.             return
  694.         tankman = self.__getEntityUserString(entityName)
  695.         if tankman:
  696.             self.__vErrorsPanel.showMessage('medkitTankmanIsSafe', {'entity': tankman})
  697.  
  698.     def _showDeviceIsNotDamagedMessage(self, entityName):
  699.         if not self.__consumablesPanel.hasRepairkit():
  700.             return
  701.         if entityName == 'chassis':
  702.             device = i18n.makeString('#ingame_gui:devices/chassis')
  703.         else:
  704.             device = self.__getEntityUserString(entityName)
  705.         if device:
  706.             self.__vErrorsPanel.showMessage('repairkitDeviceIsNotDamaged', {'entity': device})
  707.  
  708.  
  709. class TeamBasesPanel(object):
  710.     __settings = {0: {'weight': 2,
  711.          'color': 'red',
  712.          'capturing': i18n.makeString('#ingame_gui:player_messages/ally_base_captured_by_notification'),
  713.          'captured': i18n.makeString('#ingame_gui:player_messages/ally_base_captured_notification')},
  714.      3: {'weight': 1,
  715.          'color': 'green',
  716.          'capturing': i18n.makeString('#ingame_gui:player_messages/enemy_base_captured_by_notification'),
  717.          'captured': i18n.makeString('#ingame_gui:player_messages/enemy_base_captured_notification')},
  718.      'controlPoint': {'weight': {0: 4,
  719.                                  3: 3},
  720.                       'color': {0: 'red',
  721.                                 3: 'green'},
  722.                       'capturing': i18n.makeString('#ingame_gui:player_messages/base_captured_by_notification'),
  723.                       'captured': i18n.makeString('#ingame_gui:player_messages/base_captured_notification')}}
  724.  
  725.     def __init__(self, parentUI):
  726.         self.__ui = parentUI
  727.         self.__captureSounds = {}
  728.         self.__baseIds = set()
  729.         self.__capturePoints = {}
  730.         self.__updatePointsWorkers = {}
  731.  
  732.     def start(self):
  733.         LOG_DEBUG('TeamBasesPanel.start')
  734.         arena = BigWorld.player().arena
  735.         arena.onTeamBasePointsUpdate += self.__onTeamBasePointsUpdate
  736.         arena.onTeamBaseCaptured += self.__onTeamBaseCaptured
  737.         arena.onPeriodChange += self.__onPeriodChange
  738.  
  739.     def destroy(self):
  740.         LOG_DEBUG('TeamBasesPanel.destroy')
  741.         self.__clearUpdateCallbacks()
  742.         arena = getattr(BigWorld.player(), 'arena', None)
  743.         if arena is not None:
  744.             arena.onTeamBasePointsUpdate -= self.__onTeamBasePointsUpdate
  745.             arena.onTeamBaseCaptured -= self.__onTeamBaseCaptured
  746.             arena.onPeriodChange -= self.__onPeriodChange
  747.         self.__stopCaptureSound()
  748.         return
  749.  
  750.     def _getID(self, team, baseID):
  751.         if baseID is None:
  752.             baseID = 0
  753.         return (int(baseID) << 2) + team
  754.  
  755.     def _hasBaseId(self, team, exclude = -1):
  756.         return len(filter(lambda i: i & team != 0 and i != exclude, self.__baseIds)) > 0
  757.  
  758.     def __onTeamBasePointsUpdate(self, team, baseID, points, capturingStopped):
  759.         if team not in (1, 2):
  760.             return
  761.         else:
  762.             id = self._getID(team, baseID)
  763.             if not points:
  764.                 if id in self.__baseIds:
  765.                     self.__clearUpdateCallback(id)
  766.                     self.__baseIds.remove(id)
  767.                     self.__callFlash('remove', [id])
  768.                     if not self._hasBaseId(team) or team ^ BigWorld.player().team:
  769.                         self.__stopCaptureSound(team)
  770.             else:
  771.                 if id in self.__baseIds:
  772.                     self.__capturePoints[id] = points
  773.                     if capturingStopped:
  774.                         self.__callFlash('stop', [id, points])
  775.                 else:
  776.                     self.__baseIds.add(id)
  777.                     key = team ^ BigWorld.player().team
  778.                     if isControlPointExists(BigWorld.player().arenaTypeID):
  779.                         settings = self.__settings.get('controlPoint', {})
  780.                         color = settings.get('color', {}).get(key, 'green')
  781.                         weight = settings.get('weight', {}).get(key, 0)
  782.                     else:
  783.                         settings = self.__settings.get(key, {})
  784.                         color = settings.get('color', 'green')
  785.                         weight = settings.get('weight', 0)
  786.                     capturingString = settings.get('capturing', '') % getBattleSubTypeBaseNumder(BigWorld.player().arenaTypeID, team, baseID)
  787.                     rate = 1
  788.                     replayCtrl = BattleReplay.g_replayCtrl
  789.                     if replayCtrl.isPlaying and replayCtrl.playbackSpeed is not None:
  790.                         rate = replayCtrl.playbackSpeed
  791.                     self.__callFlash('add', [id,
  792.                      weight,
  793.                      color,
  794.                      capturingString,
  795.                      points,
  796.                      rate])
  797.                     if capturingStopped:
  798.                         self.__callFlash('stop', [id, points])
  799.                     self.__capturePoints[id] = points
  800.                     self.__loadUpdateCallback(id)
  801.                 if not capturingStopped:
  802.                     self.__playCaptureSound(team)
  803.                 elif not self._hasBaseId(team, exclude=id) or team ^ BigWorld.player().team:
  804.                     self.__stopCaptureSound(team)
  805.             return
  806.  
  807.     def __onTeamBaseCaptured(self, team, baseID):
  808.         if team not in (1, 2):
  809.             return
  810.         id = self._getID(team, baseID)
  811.         if isControlPointExists(BigWorld.player().arenaTypeID):
  812.             settings = self.__settings.get('controlPoint', {})
  813.             color = settings.get('color', {}).get(team ^ BigWorld.player().team, 'green')
  814.         else:
  815.             settings = self.__settings.get(team ^ BigWorld.player().team, {})
  816.             color = settings.get('color', 'green')
  817.         if id in self.__baseIds:
  818.             self.__callFlash('setCaptured', [id, settings.get('captured', '') % getBattleSubTypeBaseNumder(BigWorld.player().arenaTypeID, team, baseID)])
  819.         else:
  820.             self.__baseIds.add(id)
  821.             self.__callFlash('add', [id,
  822.              color,
  823.              settings.get('weight', 0),
  824.              settings.get('captured', '') % getBattleSubTypeBaseNumder(BigWorld.player().arenaTypeID, team, baseID),
  825.              100])
  826.         self.__stopCaptureSound(team)
  827.  
  828.     def __onPeriodChange(self, period, *args):
  829.         if period != constants.ARENA_PERIOD.AFTERBATTLE:
  830.             return
  831.         self.__callFlash('clear', [])
  832.         self.__stopCaptureSound()
  833.  
  834.     def __callFlash(self, funcName, args):
  835.         self.__ui.call('battle.teamBasesPanel.{0:>s}'.format(funcName), args)
  836.  
  837.     def __playCaptureSound(self, team):
  838.         arena = getattr(BigWorld.player(), 'arena', None)
  839.         if arena is not None and arena.period == constants.ARENA_PERIOD.AFTERBATTLE:
  840.             return
  841.         else:
  842.             snd = self.__captureSounds.get(team)
  843.             if snd is None:
  844.                 try:
  845.                     isAllyTeam = True if team == BigWorld.player().team else False
  846.                     if isAllyTeam:
  847.                         snd = FMOD.playSound(_BASE_CAPTURE_SOUND_NAME_ALLY)
  848.                         self.__captureSounds[team] = snd
  849.                 except Exception:
  850.                     LOG_CURRENT_EXCEPTION()
  851.  
  852.             return
  853.  
  854.     def __stopCaptureSound(self, team = None):
  855.         if team is None:
  856.             for t in self.__captureSounds.keys():
  857.                 self.__stopCaptureSound(t)
  858.  
  859.         else:
  860.             snd = self.__captureSounds.get(team)
  861.             if snd is not None:
  862.                 try:
  863.                     snd.stop()
  864.                 except Exception:
  865.                     LOG_CURRENT_EXCEPTION()
  866.  
  867.                 del self.__captureSounds[team]
  868.         return
  869.  
  870.     def __updatePoints(self, baseId):
  871.         if baseId in self.__baseIds:
  872.             rate = 1
  873.             replayCtrl = BattleReplay.g_replayCtrl
  874.             if replayCtrl.isPlaying and replayCtrl.playbackSpeed is not None:
  875.                 rate = replayCtrl.playbackSpeed
  876.             points = self.__capturePoints[baseId]
  877.             LOG_DEBUG('Update points called for base with points', baseId, points, rate)
  878.             self.__callFlash('updatePoints', [baseId, points, rate])
  879.             self.__loadUpdateCallback(baseId)
  880.         return
  881.  
  882.     def __loadUpdateCallback(self, baseId):
  883.         self.__clearUpdateCallback(baseId)
  884.         self.__updatePointsWorkers[baseId] = BigWorld.callback(1, lambda : self.__updatePoints(baseId))
  885.  
  886.     def __clearUpdateCallback(self, baseId):
  887.         invalidateCbID = self.__updatePointsWorkers.get(baseId)
  888.         if invalidateCbID is not None:
  889.             BigWorld.cancelCallback(invalidateCbID)
  890.             del self.__updatePointsWorkers[baseId]
  891.         return
  892.  
  893.     def __clearUpdateCallbacks(self):
  894.         for baseId, cbId in self.__updatePointsWorkers.items():
  895.             BigWorld.cancelCallback(cbId)
  896.  
  897.         self.__updatePointsWorkers = {}
  898.  
  899.  
  900. class VehicleDamageInfoPanel(object):
  901.  
  902.     def __init__(self, parent):
  903.         self.parent = parent
  904.         self.isShown = False
  905.  
  906.     def show(self, vehicleID, damagedExtras = [], destroyedExtras = []):
  907.         if vehicleID not in BigWorld.player().arena.vehicles or not BigWorld.player().arena.vehicles[vehicleID].has_key('vehicleType'):
  908.             return
  909.         extras = BigWorld.player().arena.vehicles[vehicleID]['vehicleType'].extras
  910.         isFire = False
  911.         itemsList = []
  912.         for i, id in enumerate(damagedExtras):
  913.             if extras[id].name == 'fire':
  914.                 isFire = True
  915.                 continue
  916.             itemsList.append({'name': extras[id].name,
  917.              'userName': extras[id].deviceUserString,
  918.              'state': 'damaged'})
  919.  
  920.         for i, id in enumerate(destroyedExtras):
  921.             itemsList.append({'name': extras[id].name,
  922.              'userName': extras[id].deviceUserString,
  923.              'state': 'destroyed'})
  924.  
  925.         self.parent.movie.showDamageInfoPanel(vehicleID, itemsList, isFire)
  926.         self.isShown = True
  927.  
  928.     def hide(self):
  929.         if not self.isShown:
  930.             return
  931.         self.parent.movie.hideDamageInfoPanel()
  932.         self.isShown = False
  933.  
  934.  
  935. class FragCorrelationPanel(object):
  936.  
  937.     def __init__(self, parentUI):
  938.         self.__ui = parentUI
  939.         playerTeamIdx = BigWorld.player().team
  940.         _alliedTeamName = g_battleContext.getTeamName(playerTeamIdx, True)
  941.         _enemyTeamName = g_battleContext.getTeamName(playerTeamIdx, False)
  942.         self.clear()
  943.         self.__callFlash('setTeamNames', [_alliedTeamName, _enemyTeamName])
  944.         self.showVehiclesCounter(AccountSettings.getSettings('showVehiclesCounter'))
  945.  
  946.     def clear(self, team = None):
  947.         if team is None:
  948.             self.__teamsFrags = [0, 0]
  949.             self.__teamsShortLists = {1: [],
  950.              2: []}
  951.         else:
  952.             self.__teamsShortLists[team] = []
  953.             oppositeTeamsIndexes = (1, 0)
  954.             self.__teamsFrags[oppositeTeamsIndexes[team - 1]] = 0
  955.         return
  956.  
  957.     def addKilled(self, team):
  958.         oppositeTeamsIndexes = (1, 0)
  959.         self.__teamsFrags[oppositeTeamsIndexes[team - 1]] += 1
  960.  
  961.     def addVehicle(self, team, vehicleID, vClassName, isAlive):
  962.         self.__teamsShortLists[team].append([vehicleID, vClassName, isAlive])
  963.  
  964.     def updateFrags(self, playerTeam):
  965.         teamIndex = playerTeam - 1
  966.         enemyIndex = 1 - teamIndex
  967.         self.__callFlash('updateFrags', [self.__teamsFrags[teamIndex], self.__teamsFrags[enemyIndex]])
  968.  
  969.     def updateTeam(self, isEnemy, team):
  970.         sortedList = sorted(self.__teamsShortLists[team], cmp=_markerComparator)
  971.         team = [ pos for item in sortedList for pos in item ]
  972.         if isEnemy:
  973.             self.__callFlash('updateEnemyTeam', team)
  974.         else:
  975.             self.__callFlash('updatePlayerTeam', team)
  976.  
  977.     def showVehiclesCounter(self, isShown):
  978.         self.__callFlash('showVehiclesCounter', [isShown])
  979.  
  980.     def __callFlash(self, funcName, args):
  981.         self.__ui.call('battle.fragCorrelationBar.' + funcName, args)
  982.  
  983.  
  984. class DebugPanel(UIInterface):
  985.     __UPDATE_INTERVAL = 0.01
  986.  
  987.     def __init__(self, parentUI):
  988.         UIInterface.__init__(self)
  989.         self.__ui = parentUI
  990.         self.__timeInterval = None
  991.         self.__performanceStats = _PerformanceStats()
  992.         self.__performanceStats.populateUI(parentUI)
  993.         return
  994.  
  995.     def start(self):
  996.         self.__timeInterval = _TimeInterval(self.__UPDATE_INTERVAL, '_DebugPanel__update', weakref.proxy(self))
  997.         self.__timeInterval.start()
  998.         self.__update()
  999.  
  1000.     def destroy(self):
  1001.         self.__performanceStats.disposeUI()
  1002.         self.__performanceStats = None
  1003.         self.__timeInterval.stop()
  1004.         return
  1005.  
  1006.     def __update(self):
  1007.         player = BigWorld.player()
  1008.         if player is None or not hasattr(player, 'playerVehicleID'):
  1009.             return
  1010.         else:
  1011.             fps = 0
  1012.             recordedFps = -1
  1013.             ping = 0
  1014.             isLaggingNow = False
  1015.             replayCtrl = BattleReplay.g_replayCtrl
  1016.             if replayCtrl.isPlaying and replayCtrl.fps > 0:
  1017.                 fps = BigWorld.getFPS()[1]
  1018.                 recordedFps = replayCtrl.fps
  1019.                 ping = replayCtrl.ping
  1020.                 isLaggingNow = replayCtrl.isLaggingNow
  1021.             else:
  1022.                 isLaggingNow = player.filter.isLaggingNow
  1023.                 if not isLaggingNow:
  1024.                     for v in BigWorld.entities.values():
  1025.                         if isinstance(v, Vehicle.Vehicle):
  1026.                             if not v.isPlayer:
  1027.                                 if v.isAlive() and isinstance(v.filter, BigWorld.WGVehicleFilter) and v.filter.isLaggingNow:
  1028.                                     isLaggingNow = True
  1029.                                     break
  1030.  
  1031.                 ping = min(BigWorld.LatencyInfo().value[3] * 1000, 999)
  1032.                 if ping < 999:
  1033.                     ping = max(1, ping - 500.0 * constants.SERVER_TICK_LENGTH)
  1034.                 fpsInfo = BigWorld.getFPS()
  1035.                 from helpers.statistics import g_statistics
  1036.                 g_statistics.update(fpsInfo, ping, isLaggingNow)
  1037.                 fps = fpsInfo[1]
  1038.                 if replayCtrl.isRecording:
  1039.                     replayCtrl.setFpsPingLag(fps, ping, isLaggingNow)
  1040.             try:
  1041.                 self.__performanceStats.updateDebugInfo(int(fps), int(ping), isLaggingNow, int(recordedFps))
  1042.             except:
  1043.                 pass
  1044.  
  1045.             return
  1046.  
  1047.  
  1048. class _PerformanceStats(UIInterface):
  1049.  
  1050.     def __init__(self):
  1051.         UIInterface.__init__(self)
  1052.         self.flashObject = None
  1053.         return
  1054.  
  1055.     def populateUI(self, proxy):
  1056.         UIInterface.populateUI(self, proxy)
  1057.         self.flashObject = self.uiHolder.getMember('_level0.debugPanel')
  1058.         self.flashObject.script = self
  1059.  
  1060.     def updateDebugInfo(self, fps, ping, lag, fpsReplay):
  1061.         if fpsReplay != 0 and fpsReplay != -1:
  1062.             fps = '{0}({1})'.format(fpsReplay, fps)
  1063.         else:
  1064.             fps = str(fps)
  1065.         ping = str(ping)
  1066.         self.flashObject.as_updateDebugInfo(fps, ping, lag)
  1067.  
  1068.     def disposeUI(self):
  1069.         self.flashObject.script = None
  1070.         self.flashObject = None
  1071.         return
  1072.  
  1073.  
  1074. class ConsumablesPanel(object):
  1075.     __supportedTags = {'medkit',
  1076.      'repairkit',
  1077.      'stimulator',
  1078.      'trigger',
  1079.      'fuel',
  1080.      'extinguisher'}
  1081.     __orderSets = {'medkit': TANKMEN_ROLES_ORDER_DICT['enum'],
  1082.      'repairkit': ('engine', 'ammoBay', 'gun', 'turretRotator', 'chassis', 'surveyingDevice', 'radio', 'fuelTank')}
  1083.     __mergedEntities = {'chassis': ('leftTrack', 'rightTrack')}
  1084.     _SHELL_ICON_PATH = '../maps/icons/ammopanel/ammo/%s'
  1085.     _NO_SHELL_ICON_PATH = '../maps/icons/ammopanel/ammo/NO_%s'
  1086.     _COMMAND_MAPPING_KEY_MASK = 'CMD_AMMO_CHOICE_%d'
  1087.     _START_EQUIPMENT_SLOT_IDX = 3
  1088.  
  1089.     def __init__(self, parentUI):
  1090.         self.__ui = parentUI
  1091.         self.__ui.addExternalCallbacks({'battle.consumablesPanel.onClickToSlot': self.onClickToSlot,
  1092.          'battle.consumablesPanel.onCollapseEquipment': self.onCollapseEquipment})
  1093.         self.__shellKCMap = {}
  1094.         self.__equipmentKCMap = {}
  1095.         self.__equipmentTagsByIdx = {}
  1096.         self.__entitiesKCMap = {}
  1097.         self.__expandEquipmentIdx = None
  1098.         self.__processedInfo = None
  1099.         self.__emptyEquipmentSlotCount = 0
  1100.         self._isOptDeviceEnabled = False
  1101.         self.__disableTurretRotator = not vehicleHasTurretRotator(BigWorld.player().vehicleTypeDescriptor)
  1102.         return
  1103.  
  1104.     def start(self):
  1105.         self._isOptDeviceEnabled = True
  1106.         replayCtrl = BattleReplay.g_replayCtrl
  1107.         if replayCtrl.isPlaying and replayCtrl.replayContainsGunReloads:
  1108.             self.__cbIdSetCooldown = BigWorld.callback(0.0, self.setCooldownFromReplay)
  1109.         else:
  1110.             self.__cbIdSetCooldown = None
  1111.         return
  1112.  
  1113.     def destroy(self):
  1114.         self._isOptDeviceEnabled = False
  1115.         if self.__cbIdSetCooldown is not None:
  1116.             BigWorld.cancelCallback(self.__cbIdSetCooldown)
  1117.             self.__cbIdSetCooldown = None
  1118.         self.__ui = None
  1119.         return
  1120.  
  1121.     def setItemQuantityInSlot(self, idx, quantity):
  1122.         if self.__equipmentTagsByIdx.has_key(idx):
  1123.             self.__equipmentTagsByIdx[idx][1] = quantity
  1124.         self.__callFlash('setItemQuantityInSlot', [idx, quantity])
  1125.  
  1126.     def setCoolDownTime(self, idx, timeRemaining):
  1127.         replayCtrl = BattleReplay.g_replayCtrl
  1128.         if replayCtrl.isRecording and idx is not None:
  1129.             replayCtrl.setActiveConsumableSlot(idx)
  1130.         elif replayCtrl.isPlaying and idx <= 2 and replayCtrl.replayContainsGunReloads:
  1131.             return
  1132.         self.__callFlash('setCoolDownTime', [idx, timeRemaining])
  1133.         return
  1134.  
  1135.     def setCoolDownPosAsPercent(self, idx, percent):
  1136.         self.__callFlash('setCoolDownPosAsPercent', [idx, percent])
  1137.  
  1138.     def setCooldownFromReplay(self):
  1139.         player = BigWorld.player()
  1140.         if isPlayerAvatar():
  1141.             for idx in xrange(0, 3):
  1142.                 self.setCoolDownPosAsPercent(idx, 100.0 * BattleReplay.g_replayCtrl.getConsumableSlotCooldownAmount(idx))
  1143.  
  1144.         self.__cbIdSetCooldown = BigWorld.callback(0.0, self.setCooldownFromReplay)
  1145.  
  1146.     def setDisabled(self, currentShellIdx):
  1147.         self.setCoolDownTime(currentShellIdx, 0)
  1148.         self.setCurrentShell(-1)
  1149.         self.setNextShell(-1)
  1150.         if self.__expandEquipmentIdx is not None:
  1151.             self.collapseEquipmentSlot(self.__expandEquipmentIdx)
  1152.         return
  1153.  
  1154.     def __getKey(self, idx):
  1155.         if not -1 < idx < 10:
  1156.             raise AssertionError
  1157.             cmdMappingKey = self._COMMAND_MAPPING_KEY_MASK % (idx + 1) if idx < 9 else 0
  1158.             keyCode = CommandMapping.g_instance.get(cmdMappingKey)
  1159.             keyChr = ''
  1160.             keyChr = keyCode is not None and keyCode != 0 and getScaleformKey(keyCode)
  1161.         else:
  1162.             keyCode = -idx
  1163.         return (keyCode, keyChr)
  1164.  
  1165.     def bindCommands(self):
  1166.         shellKCMap = {}
  1167.         for idx in self.__shellKCMap.values():
  1168.             keyCode, keyChr = self.__getKey(idx)
  1169.             shellKCMap[keyCode] = idx
  1170.             self.__callFlash('setKeyToSlot', [idx, keyCode, keyChr])
  1171.  
  1172.         self.__shellKCMap = shellKCMap
  1173.         equipmentKCMap = {}
  1174.         for idx in self.__equipmentKCMap.values():
  1175.             keyCode, keyChr = self.__getKey(idx)
  1176.             equipmentKCMap[keyCode] = idx
  1177.             self.__callFlash('setKeyToSlot', [idx, keyCode, keyChr])
  1178.  
  1179.         self.__equipmentKCMap = equipmentKCMap
  1180.  
  1181.     def setShellQuantityInSlot(self, idx, quantity, quantityInClip):
  1182.         if self.__equipmentTagsByIdx.has_key(idx):
  1183.             self.__equipmentTagsByIdx[idx][1] = quantity
  1184.         self.__callFlash('setShellQuantityInSlot', [idx, quantity, quantityInClip])
  1185.  
  1186.     def addShellSlot(self, idx, quantity, quantityInClip, clipCapacity, shellDescr, piercingPower):
  1187.         kind = shellDescr['kind']
  1188.         icon = shellDescr['icon'][0]
  1189.         toolTip = i18n.convert(i18n.makeString('#ingame_gui:shells_kinds/{0:>s}'.format(kind), caliber=shellDescr['caliber'], userString=shellDescr['userString'], damage=str(int(shellDescr['damage'][0])), piercingPower=str(int(piercingPower[0]))))
  1190.         shellIconPath = self._SHELL_ICON_PATH % icon
  1191.         noShellIconPath = self._NO_SHELL_ICON_PATH % icon
  1192.         keyCode, keyChr = self.__getKey(idx)
  1193.         self.__shellKCMap[keyCode] = idx
  1194.         self.__callFlash('addShellSlot', [idx,
  1195.          keyCode,
  1196.          keyChr,
  1197.          quantity,
  1198.          quantityInClip,
  1199.          clipCapacity,
  1200.          shellIconPath,
  1201.          noShellIconPath,
  1202.          toolTip])
  1203.  
  1204.     def setCurrentShell(self, idx):
  1205.         self.__callFlash('setCurrentShell', [idx])
  1206.  
  1207.     def setNextShell(self, idx):
  1208.         self.__callFlash('setNextShell', [idx])
  1209.  
  1210.     def hasMedkit(self):
  1211.         for tagName, quantity in self.__equipmentTagsByIdx.values():
  1212.             if tagName == 'medkit':
  1213.                 return quantity > 0
  1214.  
  1215.         return False
  1216.  
  1217.     def hasRepairkit(self):
  1218.         for tagName, quantity in self.__equipmentTagsByIdx.values():
  1219.             if tagName == 'repairkit':
  1220.                 return quantity > 0
  1221.  
  1222.         return False
  1223.  
  1224.     def checkEquipmentSlotIdx(self, idx):
  1225.         return max(self._START_EQUIPMENT_SLOT_IDX, idx)
  1226.  
  1227.     def addEquipmentSlot(self, idx, quantity, equipmentDescr):
  1228.         tags = self.__supportedTags & equipmentDescr.tags
  1229.         tagName = None
  1230.         if len(tags) == 1:
  1231.             tagName = tags.pop()
  1232.         iconPath = equipmentDescr.icon[0]
  1233.         toolTip = '{0:>s}\n{1:>s}'.format(equipmentDescr.userString, equipmentDescr.description)
  1234.         keyCode, keyChr = (None, None)
  1235.         if tagName:
  1236.             keyCode, keyChr = self.__getKey(idx)
  1237.             self.__equipmentKCMap[keyCode] = idx
  1238.             self.__equipmentTagsByIdx[idx] = [tagName, quantity]
  1239.         self.__callFlash('addEquipmentSlot', [idx,
  1240.          keyCode,
  1241.          keyChr,
  1242.          tagName,
  1243.          quantity,
  1244.          iconPath,
  1245.          toolTip])
  1246.         return
  1247.  
  1248.     def addEmptyEquipmentSlot(self, idx):
  1249.         self.__emptyEquipmentSlotCount += 1
  1250.         toolTip = i18n.makeString('#ingame_gui:consumables_panel/equipment/tooltip/empty')
  1251.         self.__callFlash('addEquipmentSlot', [idx,
  1252.          None,
  1253.          None,
  1254.          None,
  1255.          0,
  1256.          None,
  1257.          toolTip])
  1258.         if self.__emptyEquipmentSlotCount == NUM_EQUIPMENT_SLOTS:
  1259.             self.__callFlash('showEquipmentSlots', [False])
  1260.         return
  1261.  
  1262.     def expandEquipmentSlot(self, idx, tagName, entityStates):
  1263.         orderSet = self.__orderSets.get(tagName)
  1264.         if orderSet is None:
  1265.             if constants.IS_DEVELOPMENT:
  1266.                 LOG_ERROR('Order set not determine for tag %s' % tagName)
  1267.             return
  1268.         else:
  1269.             self.__expandEquipmentIdx = idx
  1270.             self.__processedInfo = (tagName, entityStates)
  1271.             args = self.__buildEntitiesInfoList(idx, tagName, entityStates, orderSet)
  1272.             self.__callFlash('expandEquipmentSlot', args)
  1273.             return
  1274.  
  1275.     def updateExpandedEquipmentSlot(self, entityName, entityState):
  1276.         if self.__expandEquipmentIdx and self.__processedInfo:
  1277.             tagName, entityStates = self.__processedInfo
  1278.             if entityStates.has_key(entityName):
  1279.                 entityStates[entityName] = entityState if entityState != 'repaired' else 'critical'
  1280.                 self.__processedInfo = (tagName, entityStates)
  1281.                 idx = self.__expandEquipmentIdx
  1282.                 orderSet = self.__orderSets[tagName]
  1283.                 args = self.__buildEntitiesInfoList(idx, tagName, entityStates, orderSet)
  1284.                 self.__callFlash('updateExpandedEquipmentSlot', args)
  1285.  
  1286.     def collapseEquipmentSlot(self, idx):
  1287.         self.__callFlash('collapseEquipmentSlot', [idx])
  1288.  
  1289.     def __buildEntitiesInfoList(self, idx, tagName, entityStates, orderSet):
  1290.         args = [idx, tagName]
  1291.         for entityIdx, entityName in enumerate(orderSet):
  1292.             entityState, disabled = None, True
  1293.             keyCode, keyChr = self.__getKey(entityIdx)
  1294.             if self.__mergedEntities.has_key(entityName):
  1295.                 realName = None
  1296.                 for name in self.__mergedEntities[entityName]:
  1297.                     state = entityStates.get(name, None)
  1298.                     disabled &= not entityStates.has_key(name)
  1299.                     if realName is None and state == 'critical':
  1300.                         realName = name
  1301.                         entityState = 'critical'
  1302.                     elif state == 'destroyed':
  1303.                         realName = name
  1304.                         entityState = 'destroyed'
  1305.                         break
  1306.  
  1307.                 if realName is not None:
  1308.                     self.__entitiesKCMap[keyCode] = (realName, False)
  1309.                 else:
  1310.                     self.__entitiesKCMap[keyCode] = (entityName, True)
  1311.             elif entityStates.has_key(entityName):
  1312.                 entityState = entityStates[entityName]
  1313.                 disabled = entityName == 'turretRotator' and self.__disableTurretRotator
  1314.                 if not disabled:
  1315.                     self.__entitiesKCMap[keyCode] = (entityName, entityState not in ('destroyed', 'critical'))
  1316.             args.extend([keyCode,
  1317.              keyChr,
  1318.              entityName,
  1319.              entityState,
  1320.              disabled])
  1321.  
  1322.         return args
  1323.  
  1324.     def __removeExpandEquipment(self, idx):
  1325.         if idx == self.__expandEquipmentIdx:
  1326.             self.__expandEquipmentIdx = None
  1327.             self.__processedInfo = None
  1328.             self.__entitiesKCMap.clear()
  1329.         return
  1330.  
  1331.     def addOptionalDevice(self, idx, deviceDescr):
  1332.         iconPath = deviceDescr.icon[0]
  1333.         toolTip = '{0:>s}\n{1:>s}'.format(deviceDescr.userString, deviceDescr.description)
  1334.         self.__callFlash('addOptionalDeviceSlot', [idx, iconPath, toolTip])
  1335.  
  1336.     def setOptionalDeviceState(self, idx, isOn):
  1337.         if self._isOptDeviceEnabled:
  1338.             self.setCoolDownTime(idx, -1 if isOn else 0)
  1339.  
  1340.     def handleKey(self, key):
  1341.         replayCtrl = BattleReplay.g_replayCtrl
  1342.         if replayCtrl.isPlaying:
  1343.             return
  1344.         elif self.__expandEquipmentIdx is not None:
  1345.             if key in self.__entitiesKCMap.keys():
  1346.                 slotIdx = self.__expandEquipmentIdx
  1347.                 devName, isNormal = self.__entitiesKCMap[key]
  1348.                 if not isNormal:
  1349.                     self.collapseEquipmentSlot(slotIdx)
  1350.                     BigWorld.player().onEquipmentButtonPressed(slotIdx, deviceName=devName)
  1351.                 else:
  1352.                     if self.__processedInfo is None:
  1353.                         LOG_ERROR("Can't determine equipment tag", slotIdx, devName)
  1354.                         return
  1355.                     tagName, _ = self.__processedInfo
  1356.                     if tagName == 'medkit':
  1357.                         self.__ui._showTankmanIsSafeMessage(devName)
  1358.                     elif tagName == 'repairkit':
  1359.                         self.__ui._showDeviceIsNotDamagedMessage(devName)
  1360.                     else:
  1361.                         LOG_ERROR("Can't determine message for tag", tagName)
  1362.             return
  1363.         else:
  1364.             if key in self.__shellKCMap.keys():
  1365.                 BigWorld.player().onAmmoButtonPressed(self.__shellKCMap[key])
  1366.             elif key in self.__equipmentKCMap.keys():
  1367.                 BigWorld.player().onEquipmentButtonPressed(self.__equipmentKCMap[key])
  1368.             return
  1369.  
  1370.     def onClickToSlot(self, _, keyCode):
  1371.         self.handleKey(int(keyCode))
  1372.  
  1373.     def onCollapseEquipment(self, _, idx):
  1374.         self.__removeExpandEquipment(int(idx))
  1375.  
  1376.     def __callFlash(self, funcName, args = None):
  1377.         self.__ui.call('battle.consumablesPanel.%s' % funcName, args)
  1378.  
  1379.  
  1380. class DamagePanel():
  1381.     _WAITING_INTERVAL = 0.05
  1382.     _UPDATING_INTERVAL = 0.03
  1383.  
  1384.     def __init__(self, parentUI):
  1385.         self.__ui = parentUI
  1386.         self.__hasYawLimits = False
  1387.         self.__vID = 0
  1388.         self.__speed = 0.0
  1389.         self.__health = 0
  1390.         self.__isRqToSwitch = False
  1391.         self.__waitingTI = _TimeInterval(self._WAITING_INTERVAL, '_waiting', weakref.proxy(self))
  1392.         self.__updateTI = _TimeInterval(self._UPDATING_INTERVAL, '_updateSelf', weakref.proxy(self))
  1393.         self.__tankIndicator = _TankIndicatorCtrl(self.__ui)
  1394.         self.__otherVehiclesModules = {'critical': {},
  1395.          'destroyed': {}}
  1396.         self.__ui.addExternalCallbacks({'battle.damagePanel.onClickToDeviceIcon': self.__onClickToDeviceIcon,
  1397.          'battle.damagePanel.onClickToTankmenIcon': self.__onClickToTankmenIcon,
  1398.          'battle.damagePanel.onClickToFireIcon': self.__onClickToFireIcon})
  1399.  
  1400.     def start(self):
  1401.         self.__tankIndicator.start()
  1402.         self.__vID = BigWorld.player().playerVehicleID
  1403.         self.__waitingTI.start()
  1404.  
  1405.     def destroy(self):
  1406.         self.__waitingTI.stop()
  1407.         self.__waitingTI = None
  1408.         self.__updateTI.stop()
  1409.         self.__updateTI = None
  1410.         self.__tankIndicator.destroy()
  1411.         self.__tankIndicator = None
  1412.         self.__hasYawLimits = False
  1413.         self.__ui = None
  1414.         self.__otherVehiclesModules = None
  1415.         return
  1416.  
  1417.     def updateHealth(self, health):
  1418.         if self.__health is not health:
  1419.             self.__health = health
  1420.             self.__callFlash('updateHealth', [health])
  1421.  
  1422.     def updateModuleRepair(self, module, percents, seconds):
  1423.         self.__callFlash('updateModuleRepair', [module, percents, seconds])
  1424.  
  1425.     def setModuleRepairPosition(self, entityName, position):
  1426.         self.__callFlash('setModuleRepairPosition', [entityName, position])
  1427.  
  1428.     def updateSpeed(self, speed):
  1429.         if self.__speed is not speed:
  1430.             self.__speed = speed
  1431.             self.__callFlash('updateSpeed', [speed])
  1432.  
  1433.     def setCruiseMode(self, mode):
  1434.         if BattleReplay.g_replayCtrl.isRecording:
  1435.             BattleReplay.g_replayCtrl.onSetCruiseMode(mode)
  1436.         self.__callFlash('setCruiseMode', [mode])
  1437.  
  1438.     def switchToVehicle(self, vID):
  1439.         if self.__vID is vID or vID is None:
  1440.             return
  1441.         else:
  1442.             self._reset()
  1443.             self.__waitingTI.stop()
  1444.             self.__updateTI.stop()
  1445.             self.__vID = vID
  1446.             self.__isRqToSwitch = True
  1447.             self.__waitingTI.start()
  1448.             return
  1449.  
  1450.     def _reset(self):
  1451.         self.__vID = 0
  1452.         self.__speed = 0.0
  1453.         self.__health = 0
  1454.         self.__hasYawLimits = False
  1455.         self.__isRqToSwitch = False
  1456.         self.__callFlash('reset')
  1457.  
  1458.     def _waiting(self):
  1459.         vehicle = BigWorld.entity(self.__vID)
  1460.         if vehicle is not None:
  1461.             self.__waitingTI.stop()
  1462.             self._setup(vehicle)
  1463.         return
  1464.  
  1465.     def _setup(self, vehicle):
  1466.         vTypeDesc = vehicle.typeDescriptor
  1467.         vType = vTypeDesc.type
  1468.         yawLimits = vTypeDesc.gun['turretYawLimits']
  1469.         if self.__isRqToSwitch:
  1470.             nationID = vType.id[0]
  1471.             BigWorld.player().soundNotifications.clear()
  1472.             SoundGroups.g_instance.soundModes.setCurrentNation(nations.NAMES[nationID])
  1473.         self.__tankIndicator._setup(vehicle)
  1474.         self.__hasYawLimits = yawLimits is not None
  1475.         modulesLayout = vehicleHasTurretRotator(vTypeDesc)
  1476.         crewLayout = [ elem[0] for elem in vType.crewRoles ]
  1477.         order = TANKMEN_ROLES_ORDER_DICT['plain']
  1478.         lastIdx = len(order)
  1479.  
  1480.         def comparator(item, other):
  1481.             itemIdx = order.index(item) if item in order else lastIdx
  1482.             otherIdx = order.index(other) if other in order else lastIdx
  1483.             return cmp(itemIdx, otherIdx)
  1484.  
  1485.         crewLayout = sorted(crewLayout, cmp=comparator)
  1486.         self.__callFlash('setIconsLayout', crewLayout + [modulesLayout])
  1487.         self.__callFlash('setMaxHealth', [vTypeDesc.maxHealth])
  1488.         self.__callFlash('updateHealth', [vehicle.health])
  1489.         if vehicle.isPlayer and self.__hasYawLimits:
  1490.             aih = BigWorld.player().inputHandler
  1491.             auto = False
  1492.             if aih is not None:
  1493.                 auto = aih.getAutorotation()
  1494.             self.onVehicleAutorotationEnabled(auto)
  1495.         if not vehicle.isAlive():
  1496.             self.onVehicleDestroyed()
  1497.             return
  1498.         else:
  1499.             self.__updateTI = None
  1500.             self.__updateTI = _TimeInterval(0.03, '_updateSelf' if vehicle.isPlayer else '_updateOther', weakref.proxy(self))
  1501.             self.__updateTI.start()
  1502.             return
  1503.  
  1504.     def _updateSelf(self):
  1505.         player = BigWorld.player()
  1506.         if player is None:
  1507.             return
  1508.         else:
  1509.             vehicle = BigWorld.entity(self.__vID)
  1510.             if vehicle is not None and vehicle.isStarted:
  1511.                 speed, _ = player.getOwnVehicleSpeeds()
  1512.                 self.updateSpeed(int(speed * 3.6))
  1513.             return
  1514.  
  1515.     def _updateOther(self):
  1516.         vehicle = BigWorld.entity(self.__vID)
  1517.         if vehicle is not None:
  1518.             self.updateHealth(vehicle.health)
  1519.             if vehicle.isStarted:
  1520.                 try:
  1521.                     speed = vehicle.filter.speedInfo.value[0]
  1522.                     fwdSpeedLimit, bckwdSpeedLimit = vehicle.typeDescriptor.physics['speedLimits']
  1523.                     speed = max(min(speed, fwdSpeedLimit), -bckwdSpeedLimit)
  1524.                     self.updateSpeed(int(speed * 3.6))
  1525.                 except (AttributeError, IndexError, ValueError):
  1526.                     LOG_CURRENT_EXCEPTION()
  1527.                     LOG_ERROR('Can not update speed. Stop')
  1528.                     self.__updateTI.stop()
  1529.  
  1530.             if not vehicle.isAlive():
  1531.                 self.onVehicleDestroyed()
  1532.                 self.__updateTI.stop()
  1533.         return
  1534.  
  1535.     def showAll(self, isShow):
  1536.         self.__callFlash('showAll', [isShow])
  1537.  
  1538.     def __getExtraName(self, extra):
  1539.         if extra.name == 'fire':
  1540.             return extra.name
  1541.         return extra.name[:-len('Health')]
  1542.  
  1543.     def updateExtras(self, vehicleID, damagedExtras, destroyedExtras):
  1544.         prevDamagedExtras = self.__otherVehiclesModules['critical'].setdefault(vehicleID, [])
  1545.         prevDestroyedExtras = self.__otherVehiclesModules['destroyed'].setdefault(vehicleID, [])
  1546.         vData = BigWorld.player().arena.vehicles.get(vehicleID)
  1547.         if vData is not None:
  1548.             for extraIdx in prevDestroyedExtras:
  1549.                 if extraIdx not in destroyedExtras:
  1550.                     extraName = self.__getExtraName(vData['vehicleType'].extras[extraIdx])
  1551.                     self.updateState(extraName, 'repaired' if extraIdx in damagedExtras else 'normal')
  1552.  
  1553.             for extraIdx in prevDamagedExtras:
  1554.                 if extraIdx not in damagedExtras:
  1555.                     extraName = self.__getExtraName(vData['vehicleType'].extras[extraIdx])
  1556.                     if extraName == 'fire':
  1557.                         self.onFireInVehicle(False)
  1558.                     else:
  1559.                         self.updateState(extraName, 'normal')
  1560.  
  1561.             for extraIdx in destroyedExtras:
  1562.                 extraName = self.__getExtraName(vData['vehicleType'].extras[extraIdx])
  1563.                 self.updateState(extraName, 'destroyed')
  1564.  
  1565.             for extraIdx in damagedExtras:
  1566.                 extraName = self.__getExtraName(vData['vehicleType'].extras[extraIdx])
  1567.                 if extraName == 'fire':
  1568.                     self.onFireInVehicle(True)
  1569.                 else:
  1570.                     self.updateState(extraName, 'critical')
  1571.  
  1572.         self.__otherVehiclesModules['critical'][vehicleID] = damagedExtras
  1573.         self.__otherVehiclesModules['destroyed'][vehicleID] = destroyedExtras
  1574.         return
  1575.  
  1576.     def updateState(self, type, state):
  1577.         LOG_DEBUG('[DamagePanel.updateState] type = %s state = %s' % (type, state))
  1578.         self.__callFlash('updateState', [type, state])
  1579.  
  1580.     def onVehicleDestroyed(self):
  1581.         self.__updateTI.stop()
  1582.         self.__callFlash('onVehicleDestroyed')
  1583.         self.__callFlash('onCrewDeactivated')
  1584.  
  1585.     def onCrewDeactivated(self):
  1586.         self.__callFlash('onCrewDeactivated')
  1587.  
  1588.     def onFireInVehicle(self, bool):
  1589.         self.__callFlash('onFireInVehicle', [bool])
  1590.  
  1591.     def onVehicleAutorotationEnabled(self, value):
  1592.         if self.__hasYawLimits:
  1593.             self.__callFlash('onVehicleAutorotationEnabled', [value])
  1594.  
  1595.     def __onClickToTankmenIcon(self, _, entityName, entityState):
  1596.         if BattleReplay.g_replayCtrl.isPlaying:
  1597.             return
  1598.         if entityState == 'normal':
  1599.             self.__ui._showTankmanIsSafeMessage(entityName)
  1600.             return
  1601.         BigWorld.player().onDamageIconButtonPressed('medkit', entityName)
  1602.  
  1603.     def __onClickToDeviceIcon(self, _, entityName, entityState):
  1604.         if BattleReplay.g_replayCtrl.isPlaying:
  1605.             return
  1606.         if entityState == 'normal':
  1607.             self.__ui._showDeviceIsNotDamagedMessage(entityName)
  1608.             return
  1609.         BigWorld.player().onDamageIconButtonPressed('repairkit', entityName)
  1610.  
  1611.     def __onClickToFireIcon(self, _):
  1612.         if BattleReplay.g_replayCtrl.isPlaying:
  1613.             return
  1614.         else:
  1615.             BigWorld.player().onDamageIconButtonPressed('extinguisher', None)
  1616.             return
  1617.  
  1618.     def __callFlash(self, funcName, args = None):
  1619.         self.__ui.call('battle.damagePanel.' + funcName, args)
  1620.  
  1621.  
  1622. class _TankIndicatorCtrl():
  1623.  
  1624.     def __init__(self, parentUI):
  1625.         self.__ui = parentUI
  1626.  
  1627.     def __del__(self):
  1628.         LOG_DEBUG('_TankIndicatorCtrl deleted')
  1629.  
  1630.     def start(self):
  1631.         self._define()
  1632.  
  1633.     def destroy(self):
  1634.         setattr(self.__ui.component, 'tankIndicator', None)
  1635.         self.__ui = None
  1636.         return
  1637.  
  1638.     def _define(self):
  1639.         mc = GUI.WGTankIndicatorFlash(self.__ui.movie, '_root.damagePanel.componentsContainer.tankIndicator')
  1640.         mc.wg_inputKeyMode = 2
  1641.         self.__ui.component.addChild(mc, 'tankIndicator')
  1642.  
  1643.     def _setup(self, vehicle):
  1644.         vTypeDesc = vehicle.typeDescriptor
  1645.         vTags = vTypeDesc.type.tags
  1646.         yawLimits = vTypeDesc.gun['turretYawLimits']
  1647.         if 'SPG' in vTags:
  1648.             type = 'SPG'
  1649.         elif 'AT-SPG' in vTags:
  1650.             type = 'AT-SPG'
  1651.         else:
  1652.             type = 'Tank'
  1653.         hasYawLimits = yawLimits is not None
  1654.         if type in ('SPG', 'AT-SPG') and vehicleHasTurretRotator(vTypeDesc):
  1655.             type = 'Tank'
  1656.         self.__flashCall('setType', [type])
  1657.         if hasYawLimits:
  1658.             args = [math.degrees(-yawLimits[0]), math.degrees(yawLimits[1]), True]
  1659.         else:
  1660.             args = [0, 0, False]
  1661.         self.__flashCall('setGunConstraints', args)
  1662.         if vehicle.isPlayer:
  1663.             hullMat = BigWorld.player().getOwnVehicleMatrix()
  1664.         else:
  1665.             hullMat = vehicle.matrix
  1666.         turretMat = vehicle.appearance.turretMatrix
  1667.         tankIndicator = self.__ui.component.tankIndicator
  1668.         tankIndicator.wg_turretYawConstraints = yawLimits if hasYawLimits else Math.Vector2(0.0, 0.0)
  1669.         tankIndicator.wg_hullMatProv = hullMat
  1670.         tankIndicator.wg_turretMatProv = turretMat
  1671.         return
  1672.  
  1673.     def __flashCall(self, funcName, args = None):
  1674.         if self.__ui:
  1675.             self.__ui.call('battle.tankIndicator.{0:>s}'.format(funcName), args)
  1676.  
  1677.  
  1678. class VehicleMarkersManager(Flash):
  1679.     __SWF_FILE_NAME = 'VehicleMarkersManager.swf'
  1680.     ATTACK_REASONS = ['attack',
  1681.      'fire',
  1682.      'ramming',
  1683.      'world_collision',
  1684.      'death_zone',
  1685.      'drowning']
  1686.  
  1687.     class DAMAGE_TYPE:
  1688.         FROM_UNKNOWN = 0
  1689.         FROM_ALLY = 1
  1690.         FROM_ENEMY = 2
  1691.         FROM_SQUAD = 3
  1692.         FROM_PLAYER = 4
  1693.  
  1694.     def __init__(self, parentUI):
  1695.         Flash.__init__(self, self.__SWF_FILE_NAME)
  1696.         self.component.wg_inputKeyMode = 2
  1697.         self.component.position.z = DEPTH_OF_VehicleMarker
  1698.         self.component.drawWithRestrictedViewPort = False
  1699.         self.movie.backgroundAlpha = 0
  1700.         self.colorManager = ColorSchemeManager._ColorSchemeManager()
  1701.         self.colorManager.populateUI(weakref.proxy(self))
  1702.         self.__ownUI = None
  1703.         self.__parentUI = parentUI
  1704.         self.__markers = dict()
  1705.         return
  1706.  
  1707.     def showExtendedInfo(self, value):
  1708.         self.__invokeCanvas('setShowExInfoFlag', [value])
  1709.         for handle in self.__markers.iterkeys():
  1710.             self.invokeMarker(handle, 'showExInfo', [value])
  1711.  
  1712.     def setScaleProps(self, minScale = 40, maxScale = 100, defScale = 100, speed = 3.0):
  1713.         if constants.IS_DEVELOPMENT:
  1714.             self.__ownUI.scaleProperties = (minScale,
  1715.              maxScale,
  1716.              defScale,
  1717.              speed)
  1718.  
  1719.     def setAlphaProps(self, minAlpha = 40, maxAlpha = 100, defAlpha = 100, speed = 3.0):
  1720.         if constants.IS_DEVELOPMENT:
  1721.             self.__ownUI.alphaProperties = (minAlpha,
  1722.              maxAlpha,
  1723.              defAlpha,
  1724.              speed)
  1725.  
  1726.     def start(self):
  1727.         self.active(True)
  1728.         self.__ownUI = GUI.WGVehicleMarkersCanvasFlash(self.movie)
  1729.         self.__ownUI.wg_inputKeyMode = 2
  1730.         self.__ownUI.scaleProperties = GUI_SETTINGS.markerScaleSettings
  1731.         self.__ownUI.alphaProperties = GUI_SETTINGS.markerBgSettings
  1732.         self.__ownUIProxy = weakref.proxy(self.__ownUI)
  1733.         self.__parentUI.component.addChild(self.__ownUI, 'vehicleMarkersManager')
  1734.         self.__markersCanvasUI = self.getMember('vehicleMarkersCanvas')
  1735.  
  1736.     def destroy(self):
  1737.         if self.__parentUI is not None:
  1738.             setattr(self.__parentUI.component, 'vehicleMarkersManager', None)
  1739.         self.__parentUI = None
  1740.         self.__ownUI = None
  1741.         self.__markersCanvasUI = None
  1742.         self.colorManager.dispossessUI()
  1743.         self.close()
  1744.         return
  1745.  
  1746.     def createMarker(self, vProxy):
  1747.         vInfo = dict(vProxy.publicInfo)
  1748.         if g_battleContext.isObserver(vProxy.id):
  1749.             return -1
  1750.         isFriend = vInfo['team'] == BigWorld.player().team
  1751.         vehicles = BigWorld.player().arena.vehicles
  1752.         vInfoEx = vehicles.get(vProxy.id, {})
  1753.         vTypeDescr = vProxy.typeDescriptor
  1754.         maxHealth = vTypeDescr.maxHealth
  1755.         mProv = vProxy.model.node('HP_gui')
  1756.         tags = set(vTypeDescr.type.tags & VEHICLE_CLASS_TAGS)
  1757.         vClass = tags.pop() if len(tags) > 0 else ''
  1758.         vType = vTypeDescr.type
  1759.         vIconSource = _CONTOUR_ICONS_MASK % {'unicName': vType.name.replace(':', '-')}
  1760.         entityName = g_battleContext.getPlayerEntityName(vProxy.id, vInfoEx)
  1761.         entityType = 'ally' if BigWorld.player().team == vInfoEx.get('team') else 'enemy'
  1762.         speaking = False
  1763.         if GUI_SETTINGS.voiceChat:
  1764.             speaking = VoiceChatInterface.g_instance.isPlayerSpeaking(vInfoEx.get('accountDBID', 0))
  1765.         hunting = VehicleActions.isHunting(vInfoEx.get('events', {}))
  1766.         handle = self.__ownUI.addMarker(mProv, 'VehicleMarkerAlly' if isFriend else 'VehicleMarkerEnemy')
  1767.         self.__markers[handle] = _VehicleMarker(vProxy, self.__ownUIProxy, handle)
  1768.         fullName, pName, clanAbbrev, regionCode, vehShortName = g_battleContext.getFullPlayerNameWithParts(vInfoEx, showVehShortName=False)
  1769.         self.invokeMarker(handle, 'init', [vClass,
  1770.          vIconSource,
  1771.          vType.shortUserString,
  1772.          vType.level,
  1773.          fullName,
  1774.          pName,
  1775.          clanAbbrev,
  1776.          regionCode,
  1777.          vProxy.health,
  1778.          maxHealth,
  1779.          entityName.name(),
  1780.          speaking,
  1781.          hunting,
  1782.          entityType])
  1783.         self.__parentUI.call('minimap.entryInited', [])
  1784.         return handle
  1785.  
  1786.     def destroyMarker(self, handle):
  1787.         if self.__markers.has_key(handle):
  1788.             del self.__markers[handle]
  1789.             self.__ownUI.delMarker(handle)
  1790.  
  1791.     def createStaticMarker(self, pos, symbol):
  1792.         mProv = Math.Matrix()
  1793.         mProv.translation = pos
  1794.         handle = self.__ownUI.addMarker(mProv, symbol)
  1795.         return (mProv, handle)
  1796.  
  1797.     def destroyStaticMarker(self, handle):
  1798.         if self.__ownUI:
  1799.             self.__ownUI.delMarker(handle)
  1800.  
  1801.     def updateMarkerState(self, handle, newState, isImmediate = False):
  1802.         self.invokeMarker(handle, 'updateState', [newState, isImmediate])
  1803.  
  1804.     def showActionMarker(self, handle, newState):
  1805.         self.invokeMarker(handle, 'showActionMarker', [newState])
  1806.  
  1807.     def __getVehicleDamageType(self, attackerID):
  1808.         if not attackerID:
  1809.             return VehicleMarkersManager.DAMAGE_TYPE.FROM_UNKNOWN
  1810.         if attackerID == BigWorld.player().playerVehicleID:
  1811.             return VehicleMarkersManager.DAMAGE_TYPE.FROM_PLAYER
  1812.         entityName = g_battleContext.getPlayerEntityName(attackerID, BigWorld.player().arena.vehicles.get(attackerID, dict()))
  1813.         if entityName == PLAYER_ENTITY_NAME.squadman:
  1814.             return VehicleMarkersManager.DAMAGE_TYPE.FROM_SQUAD
  1815.         if entityName == PLAYER_ENTITY_NAME.ally:
  1816.             return VehicleMarkersManager.DAMAGE_TYPE.FROM_ALLY
  1817.         if entityName == PLAYER_ENTITY_NAME.enemy:
  1818.             return VehicleMarkersManager.DAMAGE_TYPE.FROM_ENEMY
  1819.         return VehicleMarkersManager.DAMAGE_TYPE.FROM_UNKNOWN
  1820.  
  1821.     def onVehicleHealthChanged(self, handle, curHealth, attackerID = -1, attackReasonID = 0):
  1822.         self.invokeMarker(handle, 'updateHealth', [curHealth, self.__getVehicleDamageType(attackerID), VehicleMarkersManager.ATTACK_REASONS[attackReasonID]])
  1823.  
  1824.     def showDynamic(self, vID, flag):
  1825.         handle = getattr(BigWorld.entity(vID), 'marker', None)
  1826.         if handle is not None and GUI_SETTINGS.voiceChat:
  1827.             self.invokeMarker(handle, 'setSpeaking', [flag])
  1828.         return
  1829.  
  1830.     def setTeamKiller(self, vID):
  1831.         if not g_battleContext.isTeamKiller(vID=vID):
  1832.             return
  1833.         else:
  1834.             handle = getattr(BigWorld.entity(vID), 'marker', None)
  1835.             if handle is not None:
  1836.                 self.invokeMarker(handle, 'setEntityName', [PLAYER_ENTITY_NAME.teamKiller.name()])
  1837.             return
  1838.  
  1839.     def invokeMarker(self, handle, function, args = None):
  1840.         if handle == -1:
  1841.             return
  1842.         else:
  1843.             if args is None:
  1844.                 args = []
  1845.             self.__ownUI.markerInvoke(handle, (function, args))
  1846.             return
  1847.  
  1848.     def __invokeCanvas(self, function, args = None):
  1849.         if args is None:
  1850.             args = []
  1851.         self.call('battle.vehicleMarkersCanvas.' + function, args)
  1852.         return
  1853.  
  1854.     def setMarkerSettings(self, settings):
  1855.         if self.__markersCanvasUI:
  1856.             self.__markersCanvasUI.setMarkerSettings(settings)
  1857.  
  1858.     def setMarkerDuration(self, value):
  1859.         self.__invokeCanvas('setMarkerDuration', [value])
  1860.  
  1861.     def updateMarkers(self):
  1862.         self.colorManager.update()
  1863.         for handle in self.__markers.iterkeys():
  1864.             self.invokeMarker(handle, 'update', [])
  1865.  
  1866.     def updateMarkerSettings(self):
  1867.         for handle in self.__markers.iterkeys():
  1868.             self.invokeMarker(handle, 'updateMarkerSettings', [])
  1869.  
  1870.  
  1871. class _VehicleMarker():
  1872.  
  1873.     def __init__(self, vProxy, uiProxy, handle):
  1874.         self.vProxy = vProxy
  1875.         self.uiProxy = uiProxy
  1876.         self.handle = handle
  1877.         self.vProxy.appearance.onModelChanged += self.__onModelChanged
  1878.  
  1879.     def destroy(self):
  1880.         self.vProxy.appearance.onModelChanged -= self.__onModelChanged
  1881.         self.vProxy = None
  1882.         self.uiProxy = None
  1883.         self.handle = -1
  1884.         return
  1885.  
  1886.     def __onModelChanged(self):
  1887.         self.uiProxy.markerSetMatrix(self.handle, self.vProxy.model.node('HP_gui'))
  1888.  
  1889.  
  1890. class FadingMessagesPanel(object):
  1891.     __settings = []
  1892.     __messageDict = {}
  1893.     _EXTRA_COLOR_FORMAT = '<font color="#{0:02X}{1:02X}{2:02X}">{3:>s}</font>'
  1894.  
  1895.     def __init__(self, parentUI, name, cfgFileName, isColorBlind = False):
  1896.         self.__ui = parentUI
  1897.         self.__name = name
  1898.         self.__pathPrefix = 'battle.' + name + '.' + '%s'
  1899.         self.__readConfig(cfgFileName)
  1900.         self.__ui.addExternalCallbacks({'battle.%s.PopulateUI' % name: self.__onPopulateUI})
  1901.         self.defineColorFlags(isColorBlind=isColorBlind)
  1902.         self.__isPopulated = False
  1903.         self.__pendingMessages = []
  1904.  
  1905.     def start(self):
  1906.         self.__callFlash('RefreshUI')
  1907.  
  1908.     def destroy(self):
  1909.         self.__ui = None
  1910.         self.__isPopulated = False
  1911.         self.__pendingMessages = []
  1912.         return
  1913.  
  1914.     def clear(self):
  1915.         self.__callFlash('Clear')
  1916.  
  1917.     def defineColorFlags(self, isColorBlind = False):
  1918.         self.__colorGroup = 'color_blind' if isColorBlind else 'default'
  1919.  
  1920.     def showMessage(self, key, args = None, extra = None, postfix = ''):
  1921.         replayCtrl = BattleReplay.g_replayCtrl
  1922.         if replayCtrl.isPlaying and replayCtrl.isTimeWarpInProgress:
  1923.             return
  1924.         else:
  1925.             extKey = '%s_%s' % (key, postfix)
  1926.             if extKey in self.__messageDict:
  1927.                 key = extKey
  1928.             msgText, colors = self.__messageDict.get(key, (None, ''))
  1929.             if msgText is None:
  1930.                 return
  1931.             if args is not None:
  1932.                 self.__formatEntitiesEx(args, extra=extra)
  1933.                 try:
  1934.                     msgText = msgText % args
  1935.                 except TypeError:
  1936.                     LOG_CURRENT_EXCEPTION()
  1937.  
  1938.             color = colors.get(self.__colorGroup if self.__colorGroup in colors else 'default')
  1939.             if self.__isPopulated:
  1940.                 self.__showMessage(key, msgText, color)
  1941.             else:
  1942.                 self.__pendingMessages.append([key, msgText, color])
  1943.             return
  1944.  
  1945.     def __showMessage(self, key, msgText, color):
  1946.         LOG_DEBUG('%s: show message with key = %s' % (self.__name, key))
  1947.         self.__callFlash('ShowMessage', [key, msgText, color])
  1948.  
  1949.     def __formatEntitiesEx(self, args, extra = None):
  1950.         if extra is None:
  1951.             extra = ()
  1952.         csManager = self.__ui.colorManager
  1953.         for argName, vID in extra:
  1954.             arg = args.get(argName)
  1955.             rgba = None
  1956.             if g_battleContext.isTeamKiller(vID=vID):
  1957.                 rgba = csManager.getScheme('teamkiller').get(self.__colorGroup, {}).get('rgba')
  1958.             elif g_battleContext.isSquadMan(vID=vID):
  1959.                 rgba = csManager.getScheme('squad').get(self.__colorGroup, {}).get('rgba')
  1960.             if arg and rgba:
  1961.                 args[argName] = self._EXTRA_COLOR_FORMAT.format(int(rgba[0]), int(rgba[1]), int(rgba[2]), arg)
  1962.  
  1963.         return
  1964.  
  1965.     def __readConfig(self, cfgFileName):
  1966.         self.__settings = []
  1967.         import ResMgr
  1968.         sec = ResMgr.openSection(cfgFileName)
  1969.         if sec is None:
  1970.             raise Exception, "can not open '%s'" % cfgFileName
  1971.         self.__settings.append(sec.readInt('maxLinesCount', -1))
  1972.         direction = sec.readString('direction')
  1973.         if direction not in ('up', 'down'):
  1974.             raise Exception, 'Wrong direction value in %s' % cfgFileName
  1975.         self.__settings.append(direction)
  1976.         self.__settings.append(sec.readFloat('lifeTime'))
  1977.         self.__settings.append(sec.readFloat('alphaSpeed'))
  1978.         self.__settings.append(sec.readBool('showUniqueOnly', False))
  1979.         self.__messageDict = dict()
  1980.         for mTag, mSec in sec['messages'].items():
  1981.             text = mSec.readString('text')
  1982.             text = html.translation(text)
  1983.             aliasesSec = mSec['colorAlias']
  1984.             aliases = aliasesSec.items()
  1985.             if len(aliases):
  1986.                 groups = dict(((key, section.asString) for key, section in aliases))
  1987.             else:
  1988.                 groups = {'default': aliasesSec.asString}
  1989.             self.__messageDict[mTag] = (text, groups)
  1990.  
  1991.         return
  1992.  
  1993.     def __callFlash(self, funcName, args = None):
  1994.         self.__ui.call(self.__pathPrefix % funcName, args)
  1995.  
  1996.     def __onPopulateUI(self, requestId):
  1997.         args = [requestId]
  1998.         args.extend(self.__settings)
  1999.         self.__ui.respond(args)
  2000.         self.__isPopulated = True
  2001.         while len(self.__pendingMessages):
  2002.             self.__showMessage(*self.__pendingMessages.pop())
  2003.  
  2004.  
  2005. def _markerComparator(x1, x2):
  2006.     INDEX_IS_ALIVE = 2
  2007.     INDEX_VEHICLE_CLASS = 1
  2008.     if x1[INDEX_IS_ALIVE] < x2[INDEX_IS_ALIVE]:
  2009.         return 1
  2010.     if x1[INDEX_IS_ALIVE] > x2[INDEX_IS_ALIVE]:
  2011.         return -1
  2012.     x1Index = VEHICLE_BATTLE_TYPES_ORDER_INDICES.get(x1[INDEX_VEHICLE_CLASS], 100)
  2013.     x2Index = VEHICLE_BATTLE_TYPES_ORDER_INDICES.get(x2[INDEX_VEHICLE_CLASS], 100)
  2014.     if x1Index < x2Index:
  2015.         return -1
  2016.     if x1Index > x2Index:
  2017.         return 1
  2018.     return 0
  2019.  
  2020.  
  2021. class _TimeInterval():
  2022.  
  2023.     def __init__(self, interval, funcName, scopeProxy = None):
  2024.         self.__cbId = None
  2025.         self.__interval = interval
  2026.         self.__funcName = funcName
  2027.         self.__scopeProxy = scopeProxy
  2028.         return
  2029.  
  2030.     def start(self):
  2031.         if self.__cbId is not None:
  2032.             LOG_ERROR('To start a new time interval You should before stop already the running time interval.')
  2033.             return
  2034.         else:
  2035.             self.__cbId = BigWorld.callback(self.__interval, self.__update)
  2036.             return
  2037.  
  2038.     def stop(self):
  2039.         if self.__cbId is not None:
  2040.             BigWorld.cancelCallback(self.__cbId)
  2041.             self.__cbId = None
  2042.         return
  2043.  
  2044.     def __update(self):
  2045.         self.__cbId = None
  2046.         self.__cbId = BigWorld.callback(self.__interval, self.__update)
  2047.         if self.__scopeProxy is not None:
  2048.             funcObj = getattr(self.__scopeProxy, self.__funcName, None)
  2049.             if funcObj is not None:
  2050.                 funcObj()
  2051.         return
  2052.  
  2053.  
  2054. def vehicleHasTurretRotator(vTypeDesc):
  2055.     result = True
  2056.     tags = vTypeDesc.type.tags
  2057.     if tags & set(['SPG', 'AT-SPG']) and vTypeDesc.gun['turretYawLimits'] is not None:
  2058.         if len(vTypeDesc.hull.get('fakeTurrets', {}).get('battle', ())) > 0:
  2059.             result = False
  2060.     return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement