Advertisement
Mr_A

Avatar.py mod with logging

Nov 5th, 2013
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 110.85 KB | None | 0 0
  1. # Embedded file name: scripts/client/Avatar.py
  2. import cPickle
  3. import zlib
  4. from functools import partial
  5. import math
  6. import Account
  7. import BigWorld
  8. import Keys
  9. import Math
  10. import Vehicle
  11. import ClientArena
  12. import AvatarInputHandler
  13. import ProjectileMover
  14. import Settings
  15. import VehicleGunRotator
  16. import constants
  17. import Event
  18. import AreaDestructibles
  19. import CommandMapping
  20. import Weather
  21. import MusicController
  22. import SoundGroups
  23. import AvatarPositionControl
  24. import ResMgr
  25. import TriggersManager
  26. import AccountCommands
  27. from TriggersManager import TRIGGER_TYPE
  28. from debug_utils import LOG_ERROR, LOG_DEBUG
  29. from OfflineMapCreator import g_offlineMapCreator
  30. from gui.BattleContext import g_battleContext
  31. from constants import ARENA_PERIOD, AIMING_MODE, VEHICLE_SETTING, DEVELOPMENT_INFO
  32. from constants import SERVER_TICK_LENGTH, VEHICLE_MISC_STATUS, VEHICLE_HIT_FLAGS
  33. from constants import SCOUT_EVENT_TYPE, DROWN_WARNING_LEVEL
  34. from items import ITEM_TYPE_INDICES, getTypeOfCompactDescr, vehicles
  35. from messenger import MessengerEntry
  36. from messenger.proto.bw import battle_chat_cmd
  37. from messenger.proto.events import g_messengerEvents
  38. from messenger.storage import storage_getter
  39. from streamIDs import RangeStreamIDCallbacks, STREAM_ID_CHAT_MAX, STREAM_ID_CHAT_MIN, STREAM_ID_AVATAR_BATTLE_RESULS
  40. from PlayerEvents import g_playerEvents
  41. from ClientChat import ClientChat
  42. from ChatManager import chatManager
  43. from VehicleAppearance import StippleManager
  44. from helpers import bound_effects
  45. from helpers import DecalMap
  46. from gui import PlayerBonusesPanel
  47. from gui import IngameSoundNotifications
  48. from gui.Scaleform.BattleDamageMessages import BattleDamageMessages
  49. from gui.WindowsManager import g_windowsManager
  50. from chat_shared import CHAT_ACTIONS, CHAT_COMMANDS
  51. from debug_utils import *
  52. from material_kinds import EFFECT_MATERIALS
  53. from post_processing import g_postProcessing
  54. from Vibroeffects.Controllers.ReloadController import ReloadController as VibroReloadController
  55. from LightFx import LightManager
  56. import AuxiliaryFx
  57. from account_helpers.AccountSettings import AccountSettings
  58. from account_helpers import BattleResultsCache
  59. from avatar_helpers import AvatarSyncData
  60. import physics_shared
  61. import BattleReplay
  62. import HornCooldown
  63. import MapActivities
  64. from physics_shared import computeBarrelLocalPoint
  65. from AvatarInputHandler.control_modes import ArcadeControlMode, VideoCameraControlMode
  66. from AvatarInputHandler import cameras
  67. import VOIP
  68. import material_kinds
  69. import functools
  70.  
  71. class _CRUISE_CONTROL_MODE():
  72.     NONE = 0
  73.     FWD25 = 1
  74.     FWD50 = 2
  75.     FWD100 = 3
  76.     BCKW50 = -1
  77.     BCKW100 = -2
  78.  
  79.  
  80. _SHOT_WAITING_MAX_TIMEOUT = 0.2
  81. _SHOT_WAITING_MIN_TIMEOUT = 0.12
  82.  
  83. class PlayerAvatar(BigWorld.Entity, ClientChat):
  84.     __onStreamCompletePredef = {STREAM_ID_AVATAR_BATTLE_RESULS: 'receiveBattleResults'}
  85.     isOnArena = property(lambda self: self.__isOnArena)
  86.     isVehicleAlive = property(lambda self: self.__isVehicleAlive)
  87.     isWaitingForShot = property(lambda self: self.__shotWaitingTimerID is not None)
  88.     autoAimVehicle = property(lambda self: BigWorld.entities.get(self.__autoAimVehID, None))
  89.     deviceStates = property(lambda self: self.__deviceStates)
  90.  
  91.     def __init__(self):
  92.         LOG_DEBUG('client Avatar.init')
  93.         ClientChat.__init__(self)
  94.         if not BattleReplay.isPlaying():
  95.             self.intUserSettings = Account.g_accountRepository.intUserSettings
  96.             self.syncData = AvatarSyncData.AvatarSyncData()
  97.             self.syncData.setAvatar(self)
  98.             self.intUserSettings.setProxy(self, self.syncData)
  99.         self.__rangeStreamIDCallbacks = RangeStreamIDCallbacks()
  100.         self.__rangeStreamIDCallbacks.addRangeCallback((STREAM_ID_CHAT_MIN, STREAM_ID_CHAT_MAX), '_ClientChat__receiveStreamedData')
  101.         self.__onCmdResponse = {}
  102.         self.__requestID = AccountCommands.REQUEST_ID_UNRESERVED_MIN
  103.         self.__prevArenaPeriod = -1
  104.         self.__tryShootCallbackId = None
  105.         return
  106.  
  107.     def onBecomePlayer(self):
  108.         LOG_DEBUG('Avatar.onBecomePlayer()')
  109.         BigWorld.camera(BigWorld.CursorCamera())
  110.         from gui.shared.utils.HangarSpace import g_hangarSpace
  111.         if g_hangarSpace is not None:
  112.             g_hangarSpace.destroy()
  113.         chatManager.switchPlayerProxy(self)
  114.         g_playerEvents.isPlayerEntityChanging = False
  115.         self.arena = ClientArena.ClientArena(self.arenaUniqueID, self.arenaTypeID, self.arenaBonusType, self.arenaGuiType, self.arenaExtraData, self.weatherPresetID)
  116.         self.vehicleTypeDescriptor = None
  117.         self.terrainEffects = None
  118.         self.hitTesters = set()
  119.         self.filter = BigWorld.AvatarFilter()
  120.         self.onVehicleEnterWorld = Event.Event()
  121.         self.onVehicleLeaveWorld = Event.Event()
  122.         self.onGunShotChanged = Event.Event()
  123.         from account_helpers.SettingsCore import g_settingsCore
  124.         g_settingsCore.onSettingsChanged += self.__onSettingsChanged
  125.         self.invRotationOnBackMovement = g_settingsCore.getSetting('backDraftInvert')
  126.         self.__stepsTillInit = 4
  127.         self.__isSpaceInitialized = False
  128.         self.__isOnArena = False
  129.         self.__isVehicleAlive = True
  130.         self.__ownVehicleMProv = Math.WGAdaptiveMatrixProvider()
  131.         m = Math.Matrix()
  132.         m.setIdentity()
  133.         self.__ownVehicleMProv.setStaticTransform(m)
  134.         self.__lastVehicleSpeeds = (0.0, 0.0)
  135.         self.__setOwnVehicleMatrixTimerID = None
  136.         self.__aimingInfo = [0.0,
  137.          0.0,
  138.          1.0,
  139.          0.0,
  140.          0.0,
  141.          0.0,
  142.          1.0]
  143.         self.__ammo = {}
  144.         self.__currShellsIdx = None
  145.         self.__nextShellsIdx = None
  146.         self.__equipment = {}
  147.         self.__equipmentFlags = {}
  148.         self.__optionalDevices = {}
  149.         self.__nextCSlotIdx = 0
  150.         self.__fireInVehicle = False
  151.         self.__isForcedGuiControlMode = False
  152.         self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  153.         self.__stopUntilFire = False
  154.         self.__stopUntilFireStartTime = -1
  155.         self.__lastTimeOfKeyDown = -1
  156.         self.__lastKeyDown = Keys.KEY_NONE
  157.         self.__numSimilarKeyDowns = 0
  158.         self.__stippleMgr = StippleManager()
  159.         self.__autoAimVehID = 0
  160.         self.__shotWaitingTimerID = None
  161.         self.__gunReloadCommandWaitEndTime = 0.0
  162.         self.__prevGunReloadTimeLeft = -1.0
  163.         self.__frags = set()
  164.         self.__vehicleToVehicleCollisions = {}
  165.         self.__deviceStates = {}
  166.         self.__maySeeOtherVehicleDamagedDevices = False
  167.         cdWnd = vehicles.HORN_COOLDOWN.WINDOW + vehicles.HORN_COOLDOWN.CLIENT_WINDOW_EXPANSION
  168.         self.__hornCooldown = HornCooldown.HornCooldown(cdWnd, vehicles.HORN_COOLDOWN.MAX_SIGNALS)
  169.         BigWorld.wg_setBatchingEnabled(self.arena.arenaType.batchingEnabled)
  170.         if not BattleReplay.isPlaying():
  171.             self.intUserSettings.onProxyBecomePlayer()
  172.             self.syncData.onAvatarBecomePlayer()
  173.         g_playerEvents.onAvatarBecomePlayer()
  174.         MusicController.g_musicController.stopAmbient()
  175.         MusicController.g_musicController.play(MusicController.MUSIC_EVENT_COMBAT_LOADING)
  176.         BigWorld.wg_prefetchSpaceZip(self.arena.arenaType.geometryName)
  177.         self.__staticCollisionEffectID = None
  178.         self.__drownWarningLevel = DROWN_WARNING_LEVEL.SAFE
  179.         BigWorld.wg_clearDecals()
  180.         return
  181.  
  182.     def onBecomeNonPlayer(self):
  183.         LOG_DEBUG('Avatar.onBecomeNonPlayer()')
  184.         chatManager.switchPlayerProxy(None)
  185.         g_playerEvents.onAvatarBecomeNonPlayer()
  186.         self.onVehicleEnterWorld.clear()
  187.         self.onVehicleEnterWorld = None
  188.         self.onVehicleLeaveWorld.clear()
  189.         self.onVehicleLeaveWorld = None
  190.         from account_helpers.SettingsCore import g_settingsCore
  191.         g_settingsCore.onSettingsChanged -= self.__onSettingsChanged
  192.         self.__vehicleToVehicleCollisions = None
  193.         if not BattleReplay.isPlaying():
  194.             self.intUserSettings.onProxyBecomeNonPlayer()
  195.             self.syncData.onAvatarBecomeNonPlayer()
  196.             self.intUserSettings.setProxy(None, None)
  197.         return
  198.  
  199.     def onEnterWorld(self, prereqs):
  200.         LOG_DEBUG('Avatar.onEnterWorld()')
  201.         list = []
  202.         for p in set(self.__prereqs):
  203.             try:
  204.                 list.append(prereqs[p])
  205.             except Exception as e:
  206.                 LOG_WARNING('Resource is not found', p)
  207.  
  208.         self.__prereqs = list
  209.         self.gunRotator = VehicleGunRotator.VehicleGunRotator(self)
  210.         self.positionControl = AvatarPositionControl.AvatarPositionControl(self)
  211.         BigWorld.target.caps(1)
  212.         self.__onInitStepCompleted()
  213.         if self.playerVehicleID != 0:
  214.             self.set_playerVehicleID(0)
  215.         from helpers import EdgeDetectColorController
  216.         EdgeDetectColorController.g_instance.updateColors()
  217.         VOIP.getVOIPManager().setMicMute(True)
  218.  
  219.     def onLeaveWorld(self):
  220.         LOG_DEBUG('Avatar.onLeaveWorld()')
  221.         if self.__tryShootCallbackId:
  222.             BigWorld.cancelCallback(self.__tryShootCallbackId)
  223.             self.__tryShootCallbackId = None
  224.         MusicController.g_musicController.onLeaveArena()
  225.         TriggersManager.g_manager.enable(False)
  226.         BigWorld.wg_setEntityUnloadable(self.playerVehicleID, False)
  227.         BigWorld.worldDrawEnabled(False)
  228.         BigWorld.wg_enableSpaceBoundFog(False)
  229.         BigWorld.wg_setAmbientReverb('')
  230.         BigWorld.target.clear()
  231.         for v in BigWorld.entities.values():
  232.             if isinstance(v, Vehicle.Vehicle) and v.isStarted:
  233.                 self.onVehicleLeaveWorld(v)
  234.                 v.stopVisual()
  235.  
  236.         if self.__setOwnVehicleMatrixTimerID is not None:
  237.             BigWorld.cancelCallback(self.__setOwnVehicleMatrixTimerID)
  238.             self.__setOwnVehicleMatrixTimerID = None
  239.         if self.__shotWaitingTimerID is not None:
  240.             BigWorld.cancelCallback(self.__shotWaitingTimerID)
  241.             self.__shotWaitingTimerID = None
  242.         try:
  243.             self.__stippleMgr.destroy()
  244.             self.__stippleMgr = None
  245.         except Exception:
  246.             LOG_DEBUG('Avatar.__stippleMgr_EXC')
  247.             LOG_CURRENT_EXCEPTION()
  248.  
  249.         try:
  250.             self.gunRotator.destroy()
  251.             self.gunRotator = None
  252.         except Exception:
  253.             LOG_DEBUG('Avatar.gunRotator_EXC')
  254.             LOG_CURRENT_EXCEPTION()
  255.  
  256.         if self.__stepsTillInit == 0:
  257.             try:
  258.                 self.__destroyGUI()
  259.                 SoundGroups.g_instance.enableArenaSounds(False)
  260.             except Exception:
  261.                 LOG_DEBUG('Avatar.__destroyGUI_EXC')
  262.                 LOG_CURRENT_EXCEPTION()
  263.  
  264.         self.__stepsTillInit = None
  265.         try:
  266.             self.__projectileMover.destroy()
  267.             self.__projectileMover = None
  268.         except Exception:
  269.             LOG_DEBUG('Avatar.__projectileMover_EXC')
  270.             LOG_CURRENT_EXCEPTION()
  271.  
  272.         try:
  273.             self.terrainEffects.destroy()
  274.             self.terrainEffects = None
  275.         except Exception:
  276.             LOG_DEBUG('Avatar.terrainEffects_EXC')
  277.             LOG_CURRENT_EXCEPTION()
  278.  
  279.         try:
  280.             self.arena.destroy()
  281.             self.arena = None
  282.         except Exception:
  283.             LOG_DEBUG('Avatar.arena.destroy_EXC')
  284.             LOG_CURRENT_EXCEPTION()
  285.  
  286.         try:
  287.             self.positionControl.destroy()
  288.             self.positionControl = None
  289.         except:
  290.             LOG_DEBUG('Avatar.positionControl_EXC')
  291.             LOG_CURRENT_EXCEPTION()
  292.  
  293.         try:
  294.             for hitTester in self.hitTesters:
  295.                 hitTester.releaseBspModel()
  296.  
  297.         except Exception:
  298.             LOG_DEBUG('Avatar.any_EXC')
  299.             LOG_CURRENT_EXCEPTION()
  300.  
  301.         try:
  302.             vehicles.g_cache.clearPrereqs()
  303.         except Exception:
  304.             LOG_DEBUG('Avatar. vehicles.g_cache_EXC')
  305.             LOG_CURRENT_EXCEPTION()
  306.  
  307.         AreaDestructibles.clear()
  308.         self.__ownVehicleMProv.target = None
  309.         VOIP.getVOIPManager().setMicMute(True)
  310.         SoundGroups.g_instance.soundModes.setMode(SoundGroups.SoundModes.DEFAULT_MODE_NAME)
  311.         LOG_DEBUG('Avatar.allisOK')
  312.         return
  313.  
  314.     def onSpaceLoaded(self):
  315.         LOG_DEBUG('onSpaceLoaded()')
  316.         self.__onInitStepCompleted()
  317.  
  318.     def onStreamComplete(self, id, desc, data):
  319.         isCorrupted, origPacketLen, packetLen, origCrc32, crc32 = desc
  320.         if isCorrupted:
  321.             self.base.logStreamCorruption(id, origPacketLen, packetLen, origCrc32, crc32)
  322.         if BattleReplay.g_replayCtrl.isRecording:
  323.             if id >= STREAM_ID_CHAT_MIN and id <= STREAM_ID_CHAT_MAX:
  324.                 BattleReplay.g_replayCtrl.cancelSaveCurrMessage()
  325.         callback = self.__rangeStreamIDCallbacks.getCallbackForStreamID(id)
  326.         if callback is not None:
  327.             getattr(self, callback)(id, data)
  328.             return
  329.         else:
  330.             callback = self.__onStreamCompletePredef.get(id, None)
  331.             if callback is not None:
  332.                 getattr(self, callback)(True, data)
  333.                 return
  334.             return
  335.  
  336.     def onCmdResponse(self, requestID, resultID, errorStr):
  337.         LOG_DEBUG('onCmdResponse requestID=%s, resultID=%s, errorStr=%s' % (requestID, resultID, errorStr))
  338.         callback = self.__onCmdResponse.pop(requestID, None)
  339.         if callback is not None:
  340.             callback(requestID, resultID, errorStr)
  341.         return
  342.  
  343.     def onIGRTypeChanged(self, data):
  344.         try:
  345.             data = cPickle.loads(data)
  346.             g_playerEvents.onIGRTypeChanged(data.get('roomType'), data.get('igrXPFactor'))
  347.         except Exception:
  348.             LOG_ERROR('Error while unpickling igr data information', data)
  349.  
  350.     def handleKeyEvent(self, event):
  351.         return False
  352.  
  353.     def handleKey(self, isDown, key, mods):
  354.         if not self.userSeesWorld():
  355.             return False
  356.         time = BigWorld.time()
  357.         cmdMap = CommandMapping.g_instance
  358.         try:
  359.             isDoublePress = False
  360.             if isDown:
  361.                 if self.__lastTimeOfKeyDown == -1:
  362.                     self.__lastTimeOfKeyDown = 0
  363.                 if key == self.__lastKeyDown and time - self.__lastTimeOfKeyDown < 0.35:
  364.                     self.__numSimilarKeyDowns = self.__numSimilarKeyDowns + 1
  365.                     isDoublePress = True if self.__numSimilarKeyDowns == 2 else False
  366.                 else:
  367.                     self.__numSimilarKeyDowns = 1
  368.                 self.__lastKeyDown = key
  369.                 self.__lastTimeOfKeyDown = time
  370.             if BigWorld.isKeyDown(Keys.KEY_CAPSLOCK) and isDown and constants.IS_DEVELOPMENT:
  371.                 if key == Keys.KEY_ESCAPE:
  372.                     self.__setVisibleGUI(not self.__isGuiVisible)
  373.                     return True
  374.                 if key == Keys.KEY_1:
  375.                     self.base.setDevelopmentFeature('heal', 0)
  376.                     return True
  377.                 if key == Keys.KEY_2:
  378.                     self.base.setDevelopmentFeature('reload_gun', 0)
  379.                     return True
  380.                 if key == Keys.KEY_3:
  381.                     self.base.setDevelopmentFeature('start_fire', 0)
  382.                     return True
  383.                 if key == Keys.KEY_4:
  384.                     self.base.setDevelopmentFeature('explode', 0)
  385.                     return True
  386.                 if key == Keys.KEY_5:
  387.                     self.base.setDevelopmentFeature('break_left_track', 0)
  388.                     return True
  389.                 if key == Keys.KEY_6:
  390.                     self.base.setDevelopmentFeature('break_right_track', 0)
  391.                     return True
  392.                 if key == Keys.KEY_7:
  393.                     self.base.setDevelopmentFeature('destroy_self', True)
  394.                 if key == Keys.KEY_9:
  395.                     BigWorld.setWatcher('Render/Spots/draw', BigWorld.getWatcher('Render/Spots/draw') == 'false')
  396.                     return True
  397.                 if key == Keys.KEY_F:
  398.                     vehicle = BigWorld.entity(self.playerVehicleID)
  399.                     vehicle.filter.enableClientFilters = not vehicle.filter.enableClientFilters
  400.                     return True
  401.                 if key == Keys.KEY_G:
  402.                     self.moveVehicle(1, True)
  403.                     return True
  404.                 if key == Keys.KEY_R:
  405.                     self.base.setDevelopmentFeature('pickup', 0)
  406.                     return True
  407.                 if key == Keys.KEY_T:
  408.                     self.base.setDevelopmentFeature('log_tkill_ratings', 0)
  409.                     return True
  410.             if constants.IS_DEVELOPMENT and cmdMap.isFired(CommandMapping.CMD_SWITCH_SERVER_MARKER, key) and isDown:
  411.                 showServerMarker = not self.gunRotator.showServerMarker
  412.                 self.enableServerAim(showServerMarker)
  413.                 from account_helpers.SettingsCore import g_settingsCore
  414.                 g_settingsCore.serverSettings.setGameSettings({'useServerAim': showServerMarker})
  415.                 return True
  416.             if cmdMap.isFired(CommandMapping.CMD_TOGGLE_GUI, key) and isDown:
  417.                 self.__setVisibleGUI(not self.__isGuiVisible)
  418.             if constants.IS_DEVELOPMENT and isDown:
  419.                 if key == Keys.KEY_B and mods == 0:
  420.                     g_windowsManager.showBotsMenu()
  421.                     return True
  422.                 if key == Keys.KEY_H and mods != 0:
  423.                     import Cat
  424.                     Cat.Tasks.VehicleModels.VehicleModelsObject.switchVisualState()
  425.                     return True
  426.                 if key == Keys.KEY_I and mods == 0:
  427.                     import Cat
  428.                     if Cat.Tasks.ScreenInfo.ScreenInfoObject.getVisible():
  429.                         Cat.Tasks.ScreenInfo.ScreenInfoObject.setVisible(False)
  430.                     else:
  431.                         Cat.Tasks.ScreenInfo.ScreenInfoObject.setVisible(True)
  432.                     return True
  433.             if cmdMap.isFired(CommandMapping.CMD_INCREMENT_CRUISE_MODE, key) and isDown and not self.__isForcedGuiControlMode:
  434.                 if self.__stopUntilFire:
  435.                     self.__stopUntilFire = False
  436.                     self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  437.                 if isDoublePress:
  438.                     newMode = _CRUISE_CONTROL_MODE.FWD100
  439.                 else:
  440.                     newMode = self.__cruiseControlMode + 1
  441.                     newMode = min(newMode, _CRUISE_CONTROL_MODE.FWD100)
  442.                 if newMode != self.__cruiseControlMode:
  443.                     self.__cruiseControlMode = newMode
  444.                     if not cmdMap.isActiveList((CommandMapping.CMD_MOVE_FORWARD, CommandMapping.CMD_MOVE_FORWARD_SPEC, CommandMapping.CMD_MOVE_BACKWARD)):
  445.                         self.moveVehicle(self.makeVehicleMovementCommandByKeys(), isDown)
  446.                 self.__updateCruiseControlPanel()
  447.                 return True
  448.             if cmdMap.isFired(CommandMapping.CMD_DECREMENT_CRUISE_MODE, key) and isDown and not self.__isForcedGuiControlMode:
  449.                 if self.__stopUntilFire:
  450.                     self.__stopUntilFire = False
  451.                     self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  452.                 if isDoublePress:
  453.                     newMode = _CRUISE_CONTROL_MODE.BCKW100
  454.                 else:
  455.                     newMode = self.__cruiseControlMode - 1
  456.                     newMode = max(newMode, _CRUISE_CONTROL_MODE.BCKW100)
  457.                 if newMode != self.__cruiseControlMode:
  458.                     self.__cruiseControlMode = newMode
  459.                     if not cmdMap.isActiveList((CommandMapping.CMD_MOVE_FORWARD, CommandMapping.CMD_MOVE_FORWARD_SPEC, CommandMapping.CMD_MOVE_BACKWARD)):
  460.                         self.moveVehicle(self.makeVehicleMovementCommandByKeys(), isDown)
  461.                 self.__updateCruiseControlPanel()
  462.                 return True
  463.             if cmdMap.isFiredList((CommandMapping.CMD_MOVE_FORWARD, CommandMapping.CMD_MOVE_FORWARD_SPEC, CommandMapping.CMD_MOVE_BACKWARD), key) and isDown and not self.__isForcedGuiControlMode:
  464.                 self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  465.                 self.__updateCruiseControlPanel()
  466.             if cmdMap.isFired(CommandMapping.CMD_STOP_UNTIL_FIRE, key) and isDown and not self.__isForcedGuiControlMode:
  467.                 if not self.__stopUntilFire:
  468.                     self.__stopUntilFire = True
  469.                     self.__stopUntilFireStartTime = time
  470.                 else:
  471.                     self.__stopUntilFire = False
  472.                 self.moveVehicle(self.makeVehicleMovementCommandByKeys(), isDown)
  473.                 self.__updateCruiseControlPanel()
  474.             if cmdMap.isFiredList((CommandMapping.CMD_MOVE_FORWARD,
  475.              CommandMapping.CMD_MOVE_FORWARD_SPEC,
  476.              CommandMapping.CMD_MOVE_BACKWARD,
  477.              CommandMapping.CMD_ROTATE_LEFT,
  478.              CommandMapping.CMD_ROTATE_RIGHT), key):
  479.                 if self.__stopUntilFire and isDown and not self.__isForcedGuiControlMode:
  480.                     self.__stopUntilFire = False
  481.                     self.__updateCruiseControlPanel()
  482.                 if not self.__isForcedGuiControlMode:
  483.                     self.moveVehicle(self.makeVehicleMovementCommandByKeys(), isDown)
  484.                 return True
  485.             if not self.__isForcedGuiControlMode and cmdMap.isFiredList(xrange(CommandMapping.CMD_AMMO_CHOICE_1, CommandMapping.CMD_AMMO_CHOICE_0 + 1), key) and isDown and mods == 0:
  486.                 g_windowsManager.battleWindow.consumablesPanel.handleKey(key)
  487.                 return True
  488.             if cmdMap.isFiredList((CommandMapping.CMD_CHAT_SHORTCUT_ATTACK,
  489.              CommandMapping.CMD_CHAT_SHORTCUT_BACKTOBASE,
  490.              CommandMapping.CMD_CHAT_SHORTCUT_FOLLOWME,
  491.              CommandMapping.CMD_CHAT_SHORTCUT_POSITIVE,
  492.              CommandMapping.CMD_CHAT_SHORTCUT_NEGATIVE,
  493.              CommandMapping.CMD_CHAT_SHORTCUT_HELPME,
  494.              CommandMapping.CMD_CHAT_SHORTCUT_RELOAD,
  495.              CommandMapping.CMD_RADIAL_MENU_SHOW), key) and self.__isVehicleAlive:
  496.                 g_windowsManager.battleWindow.radialMenu.handleKey(key, isDown, self.inputHandler.aim.offset())
  497.                 return True
  498.             if cmdMap.isFired(CommandMapping.CMD_VEHICLE_MARKERS_SHOW_INFO, key):
  499.                 g_windowsManager.battleWindow.vMarkersManager.showExtendedInfo(isDown)
  500.                 return True
  501.             if key == Keys.KEY_F12 and isDown and mods == 0:
  502.                 self.__dumpVehicleState()
  503.                 return True
  504.             if key == Keys.KEY_F12 and isDown and mods == 2:
  505.                 self.__reportLag()
  506.                 return True
  507.             if cmdMap.isFired(CommandMapping.CMD_USE_HORN, key) and isDown:
  508.                 self.useHorn(True)
  509.                 return True
  510.             if self.isHornActive() and self.hornMode() != 'oneshot' and not cmdMap.isActive(CommandMapping.CMD_USE_HORN):
  511.                 self.useHorn(False)
  512.                 return True
  513.             if cmdMap.isFired(CommandMapping.CMD_VOICECHAT_MUTE, key):
  514.                 LOG_DEBUG('onVoiceChatPTT', isDown)
  515.                 if VOIP.getVOIPManager().channelsMgr.currentChannel:
  516.                     VOIP.getVOIPManager().setMicMute(not isDown)
  517.             if cmdMap.isFired(CommandMapping.CMD_LOGITECH_SWITCH_VIEW, key) and isDown:
  518.                 LOG_DEBUG('LOGITECH SWICH VIEW', isDown)
  519.                 from gui.Scaleform.LogitechMonitor import LogitechMonitor
  520.                 LogitechMonitor.onChangeView()
  521.             if cmdMap.isFiredList((CommandMapping.CMD_MINIMAP_SIZE_DOWN, CommandMapping.CMD_MINIMAP_SIZE_UP, CommandMapping.CMD_MINIMAP_VISIBLE), key) and isDown:
  522.                 g_windowsManager.battleWindow.minimap.handleKey(key)
  523.                 return True
  524.             if cmdMap.isFired(CommandMapping.CMD_RELOAD_PARTIAL_CLIP, key) and isDown:
  525.                 self.onReloadPartialClipKeyDown()
  526.                 return True
  527.         except Exception:
  528.             LOG_CURRENT_EXCEPTION()
  529.             return True
  530.  
  531.         return False
  532.  
  533.     def set_playerVehicleID(self, prev):
  534.         LOG_DEBUG('Avatar.set_playerVehicleID()', self.playerVehicleID)
  535.         BigWorld.wg_setEntityUnloadable(self.playerVehicleID, True)
  536.         self.__onInitStepCompleted()
  537.         ownVehicle = BigWorld.entity(self.playerVehicleID)
  538.         if ownVehicle is not None and ownVehicle.inWorld and not ownVehicle.isPlayer:
  539.             ownVehicle.isPlayer = True
  540.             self.vehicleTypeDescriptor = ownVehicle.typeDescriptor
  541.             self.__onInitStepCompleted()
  542.         return
  543.  
  544.     def set_isGunLocked(self, prev):
  545.         if self.isGunLocked:
  546.             self.gunRotator.lock(True)
  547.             if not isinstance(self.inputHandler.ctrl, ArcadeControlMode) and not isinstance(self.inputHandler.ctrl, VideoCameraControlMode):
  548.                 self.inputHandler.setAimingMode(False, AIMING_MODE.USER_DISABLED)
  549.                 self.inputHandler.onControlModeChanged('arcade', preferredPos=self.inputHandler.getDesiredShotPoint())
  550.         else:
  551.             self.gunRotator.lock(False)
  552.  
  553.     def set_isOwnVehicleContactingWorld(self, prev):
  554.         pass
  555.  
  556.     def targetBlur(self, prevEntity):
  557.         if not isinstance(prevEntity, Vehicle.Vehicle):
  558.             return
  559.         if self.inputHandler.aim:
  560.             self.inputHandler.aim.clearTarget()
  561.         TriggersManager.g_manager.deactivateTrigger(TRIGGER_TYPE.AIM_AT_VEHICLE)
  562.         BigWorld.wgDelEdgeDetectEntity(prevEntity)
  563.         if self.__maySeeOtherVehicleDamagedDevices:
  564.             self.cell.monitorVehicleDamagedDevices(0)
  565.             g_windowsManager.battleWindow.damageInfoPanel.hide()
  566.  
  567.     def targetFocus(self, entity):
  568.         if not isinstance(entity, Vehicle.Vehicle):
  569.             return
  570.         if self.inputHandler.aim:
  571.             self.inputHandler.aim.setTarget(entity)
  572.         if self.__isGuiVisible and entity.isAlive():
  573.             TriggersManager.g_manager.activateTrigger(TRIGGER_TYPE.AIM_AT_VEHICLE, vehicleId=entity.id)
  574.             if self.team == entity.publicInfo['team']:
  575.                 BigWorld.wgAddEdgeDetectEntity(entity, 2)
  576.             else:
  577.                 BigWorld.wgAddEdgeDetectEntity(entity, 1)
  578.             if self.__maySeeOtherVehicleDamagedDevices:
  579.                 self.cell.monitorVehicleDamagedDevices(entity.id)
  580.  
  581.     def reload(self):
  582.         self.__reloadGUI()
  583.         self.inputHandler.setReloading(0.0)
  584.  
  585.     def vehicle_onEnterWorld(self, vehicle):
  586.         self.__stippleMgr.hideIfExistFor(vehicle)
  587.         if vehicle.id != self.playerVehicleID:
  588.             vehicle.targetCaps = [1]
  589.         else:
  590.             LOG_DEBUG('Avatar.vehicle_onEnterWorld(): own vehicle', vehicle.id)
  591.             vehicle.isPlayer = True
  592.             if self.__stepsTillInit != 0:
  593.                 self.vehicleTypeDescriptor = vehicle.typeDescriptor
  594.                 if isinstance(vehicle.filter, BigWorld.WGVehicleFilter):
  595.                     m = vehicle.filter.bodyMatrix
  596.                 else:
  597.                     m = vehicle.matrix
  598.                 self.__ownVehicleMProv.setStaticTransform(Math.Matrix(m))
  599.                 self.__onInitStepCompleted()
  600.             else:
  601.                 vehicle.typeDescriptor.activeGunShotIndex = self.vehicleTypeDescriptor.activeGunShotIndex
  602.                 if self.inputHandler.aim:
  603.                     self.inputHandler.aim.resetVehicleMatrix()
  604.         if self.__stepsTillInit == 0 and not vehicle.isStarted:
  605.             vehicle.startVisual()
  606.             self.onVehicleEnterWorld(vehicle)
  607.  
  608.     def vehicle_onLeaveWorld(self, vehicle):
  609.         if not vehicle.isStarted:
  610.             return
  611.         else:
  612.             self.onVehicleLeaveWorld(vehicle)
  613.             vehicle.stopVisual()
  614.             model = vehicle.model
  615.             vehicle.model = None
  616.             self.__stippleMgr.showFor(vehicle, model)
  617.             return
  618.  
  619.     def bbfog(self, enable, distance):
  620.         BigWorld.wg_enableSpaceBoundFog(enable, _boundingBoxAsVector4(self.arena.arenaType.boundingBox), distance)
  621.  
  622.     def prerequisites(self):
  623.         if hasattr(self, '_PlayerAvatar__prereqs'):
  624.             return ()
  625.         SoundGroups.g_instance.enableArenaSounds(False)
  626.         self.__prereqs = []
  627.         self.__fakeModelName = Settings.g_instance.scriptConfig.readString(Settings.KEY_FAKE_MODEL)
  628.         if self.__fakeModelName:
  629.             self.__prereqs.append(self.__fakeModelName)
  630.         else:
  631.             LOG_ERROR("The '%s' is missing or empty in '%s'" % (Settings.KEY_FAKE_MODEL, Settings.g_instance.scriptConfig.name))
  632.         self.terrainEffects = bound_effects.StaticSceneBoundEffects()
  633.         self.__projectileMover = ProjectileMover.ProjectileMover()
  634.         self.__prereqs += self.__initGUI()
  635.         self.__prereqs += g_postProcessing.prerequisites()
  636.         return self.__prereqs
  637.  
  638.     def initSpace(self):
  639.         if not self.__isSpaceInitialized:
  640.             self.__applyTimeAndWeatherSettings()
  641.             self.__isSpaceInitialized = True
  642.  
  643.     def userSeesWorld(self):
  644.         return self.__stepsTillInit == 0
  645.  
  646.     def newFakeModel(self):
  647.         return BigWorld.Model(self.__fakeModelName)
  648.  
  649.     def requestChatToken(self, requestID):
  650.         self.base.requestChatToken(requestID)
  651.  
  652.     def onChatTokenReceived(self, data):
  653.         Account.g_accountRepository.onChatTokenReceived(data)
  654.  
  655.     def onKickedFromServer(self, reason, isBan, expiryTime):
  656.         LOG_MX('onKickedFromServer', reason, isBan, expiryTime)
  657.         from gui import DialogsInterface
  658.         DialogsInterface.showDisconnect(reason, isBan, expiryTime)
  659.  
  660.     def onAutoAimVehicleLost(self):
  661.         autoAimVehID = self.__autoAimVehID
  662.         self.__autoAimVehID = 0
  663.         self.inputHandler.setAimingMode(False, AIMING_MODE.TARGET_LOCK)
  664.         self.gunRotator.clientMode = True
  665.         if autoAimVehID and autoAimVehID not in self.__frags:
  666.             self.soundNotifications.play('target_lost')
  667.  
  668.     def updateVehicleHealth(self, health, isCrewActive):
  669.         rawHealth = health
  670.         health = max(0, health)
  671.         if health > 0:
  672.             isAlive = isCrewActive
  673.             wasAlive = self.__isVehicleAlive
  674.             self.__isVehicleAlive = isAlive
  675.             damagePanel = g_windowsManager.battleWindow.damagePanel
  676.             damagePanel.updateHealth(health)
  677.             if self.inputHandler.aim:
  678.                 self.inputHandler.aim.setHealth(health)
  679.             if not isAlive and wasAlive:
  680.                 self.gunRotator.stop()
  681.                 if health > 0 and not isCrewActive:
  682.                     damagePanel.onCrewDeactivated()
  683.                     self.soundNotifications.play('crew_deactivated')
  684.                     self.__deviceStates = {'crew': 'destroyed'}
  685.                 elif not g_battleContext.isObserver(self.playerVehicleID):
  686.                     damagePanel.onVehicleDestroyed()
  687.                     self.soundNotifications.play('vehicle_destroyed')
  688.                     self.__deviceStates = {'vehicle': 'destroyed'}
  689.                 battleWindow = g_windowsManager.battleWindow
  690.                 battleWindow.consumablesPanel.setDisabled(self.__currShellsIdx)
  691.                 g_windowsManager.showPostMortem()
  692.                 self.inputHandler.activatePostmortem()
  693.                 self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  694.                 self.__updateCruiseControlPanel()
  695.                 self.__stopUntilFire = False
  696.                 if rawHealth <= 0:
  697.                     vehicle = BigWorld.entities.get(self.playerVehicleID)
  698.                     prevHealth = vehicle is not None and vehicle.health
  699.                     vehicle.health = rawHealth
  700.                     vehicle.set_health(prevHealth)
  701.         return
  702.  
  703.     def updateVehicleGunReloadTime(self, vehicleID, timeLeft, baseTime):
  704.         LOG_DEBUG_DEV('updateVehicleGunReloadTime()', vehicleID, timeLeft, baseTime)
  705.         if vehicleID != self.playerVehicleID:
  706.             if not self.__isVehicleAlive and vehicleID == self.inputHandler.ctrl.curVehicleID:
  707.                 aim = self.inputHandler.aim
  708.                 if aim is not None:
  709.                     aim.updateAmmoState(timeLeft != -2)
  710.             return
  711.         else:
  712.             self.__gunReloadCommandWaitEndTime = 0.0
  713.             if self.__prevGunReloadTimeLeft != timeLeft and timeLeft == 0.0:
  714.                 self.soundNotifications.play('gun_reloaded')
  715.                 VibroReloadController()
  716.             self.__prevGunReloadTimeLeft = timeLeft
  717.             if timeLeft < 0.0:
  718.                 timeLeft = -1
  719.             clipParams = self.vehicleTypeDescriptor.gun['clip']
  720.             clipOneShotReloadingTime = clipParams[1]
  721.             if clipOneShotReloadingTime > 0:
  722.                 if self.__ammo[self.__currShellsIdx][2] != 1:
  723.                     baseTime = clipOneShotReloadingTime
  724.             self.inputHandler.setReloading(timeLeft, None, baseTime)
  725.             g_windowsManager.battleWindow.consumablesPanel.setCoolDownTime(self.__currShellsIdx, timeLeft)
  726.             return
  727.  
  728.     def updateVehicleAmmo(self, compactDescr, quantity, quantityInClip, timeRemaining):
  729.         if not compactDescr:
  730.             self.__processEmptyVehicleEquipment()
  731.             return
  732.         itemTypeIdx = getTypeOfCompactDescr(compactDescr)
  733.         processor = self.__updateConsumablesProcessors.get(itemTypeIdx)
  734.         if processor:
  735.             getattr(self, processor)(compactDescr, quantity, quantityInClip, timeRemaining)
  736.         else:
  737.             LOG_WARNING('Not supported item type index', itemTypeIdx)
  738.  
  739.     __updateConsumablesProcessors = {ITEM_TYPE_INDICES['shell']: '_PlayerAvatar__processVehicleAmmo',
  740.      ITEM_TYPE_INDICES['equipment']: '_PlayerAvatar__processVehicleEquipments'}
  741.  
  742.     def updateVehicleOptionalDeviceStatus(self, deviceID, isOn):
  743.         self.__processVehicleOptionalDevices(deviceID, isOn)
  744.  
  745.     def updateVehicleMiscStatus(self, vehicleID, code, intArg, floatArg):
  746.         if vehicleID != self.playerVehicleID and (self.__isVehicleAlive or vehicleID != self.inputHandler.ctrl.curVehicleID):
  747.             return
  748.         else:
  749.             STATUS = VEHICLE_MISC_STATUS
  750.             if code == STATUS.DESTROYED_DEVICE_IS_REPAIRING:
  751.                 extraIndex = intArg & 255
  752.                 progress = (intArg & 65280) >> 8
  753.                 LOG_DEBUG_DEV('DESTROYED_DEVICE_IS_REPAIRING (%s): %s%%, %s sec' % (self.vehicleTypeDescriptor.extras[extraIndex].name, progress, floatArg))
  754.                 if g_windowsManager.battleWindow is not None:
  755.                     damagePanel = g_windowsManager.battleWindow.damagePanel
  756.                     damagePanel.updateModuleRepair(self.vehicleTypeDescriptor.extras[extraIndex].name[:-len('Health')], progress, floatArg)
  757.             elif code == STATUS.OTHER_VEHICLE_DAMAGED_DEVICES_VISIBLE:
  758.                 prevVal = self.__maySeeOtherVehicleDamagedDevices
  759.                 newVal = bool(intArg)
  760.                 self.__maySeeOtherVehicleDamagedDevices = newVal
  761.                 if not prevVal and newVal:
  762.                     target = BigWorld.target()
  763.                     if target is not None and isinstance(target, Vehicle.Vehicle):
  764.                         self.cell.monitorVehicleDamagedDevices(target.id)
  765.             elif code == STATUS.VEHICLE_IS_OVERTURNED:
  766.                 self.updateVehicleDestroyTimer(code, floatArg)
  767.             elif code == STATUS.IN_DEATH_ZONE:
  768.                 self.updateVehicleDestroyTimer(code, floatArg)
  769.             elif code == STATUS.VEHICLE_DROWN_WARNING:
  770.                 self.updateVehicleDestroyTimer(code, floatArg, intArg)
  771.             elif code == STATUS.IS_OBSERVED_BY_ENEMY:
  772.                 if g_windowsManager.battleWindow is not None:
  773.                     g_windowsManager.battleWindow.showSixthSenseIndicator(True)
  774.             elif code == STATUS.LOADER_INTUITION_WAS_USED:
  775.                 self.soundNotifications.play('gun_intuition')
  776.                 if g_windowsManager.battleWindow is not None:
  777.                     g_windowsManager.battleWindow.vMsgsPanel.showMessage('LOADER_INTUITION_WAS_USED')
  778.                 aim = self.inputHandler.aim
  779.                 if aim is not None:
  780.                     cd, quantity, _ = self.__ammo[self.__currShellsIdx]
  781.                     clipCapacity, _ = self.vehicleTypeDescriptor.gun['clip']
  782.                     if clipCapacity > 0 and not aim.isGunReload():
  783.                         for idx, (_cd, _quantity, _) in self.__ammo.iteritems():
  784.                             self.__ammo[idx] = (_cd, _quantity, 0)
  785.  
  786.                         quantityInClip = clipCapacity if quantity >= clipCapacity else quantity
  787.                         self.__ammo[self.__currShellsIdx] = (cd, quantity, quantityInClip)
  788.                         aim.setAmmoStock(*self.__ammo[self.__currShellsIdx][1:3])
  789.             elif code == STATUS.HORN_BANNED:
  790.                 self.__hornCooldown.ban(floatArg)
  791.             return
  792.  
  793.     def updateVehicleSetting(self, code, value):
  794.         consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  795.         if code == VEHICLE_SETTING.CURRENT_SHELLS:
  796.             idx = self.__findIndexInAmmo(value)
  797.             if idx is None:
  798.                 LOG_CODEPOINT_WARNING(code, value)
  799.                 return
  800.             if idx == self.__currShellsIdx:
  801.                 return
  802.             consumablesPanel.setCurrentShell(idx)
  803.             self.__currShellsIdx = idx
  804.             shellDescr = vehicles.getDictDescr(value)
  805.             for shotIdx, descr in enumerate(self.vehicleTypeDescriptor.gun['shots']):
  806.                 if descr['shell']['id'] == shellDescr['id']:
  807.                     self.vehicleTypeDescriptor.activeGunShotIndex = shotIdx
  808.                     vehicle = BigWorld.entity(self.playerVehicleID)
  809.                     if vehicle is not None:
  810.                         vehicle.typeDescriptor.activeGunShotIndex = shotIdx
  811.                     self.onGunShotChanged()
  812.                     break
  813.  
  814.             aim = self.inputHandler.aim
  815.             if aim is not None:
  816.                 aim.setAmmoStock(*self.__ammo[idx][1:3])
  817.             return
  818.         elif code == VEHICLE_SETTING.NEXT_SHELLS:
  819.             idx = self.__findIndexInAmmo(value)
  820.             if idx is None:
  821.                 LOG_CODEPOINT_WARNING(code, value)
  822.                 return
  823.             if idx == self.__nextShellsIdx:
  824.                 return
  825.             consumablesPanel.setNextShell(idx)
  826.             self.__nextShellsIdx = idx
  827.             return
  828.         else:
  829.             LOG_CODEPOINT_WARNING(code, value)
  830.             return
  831.  
  832.     def updateTargetingInfo(self, turretYaw, gunPitch, maxTurretRotationSpeed, maxGunRotationSpeed, shotDispMultiplierFactor, gunShotDispersionFactorsTurretRotation, chassisShotDispersionFactorsMovement, chassisShotDispersionFactorsRotation, aimingTime):
  833.         aimingInfo = self.__aimingInfo
  834.         aimingInfo[2] = shotDispMultiplierFactor
  835.         aimingInfo[3] = gunShotDispersionFactorsTurretRotation
  836.         aimingInfo[4] = chassisShotDispersionFactorsMovement
  837.         aimingInfo[5] = chassisShotDispersionFactorsRotation
  838.         aimingInfo[6] = aimingTime
  839.         self.gunRotator.update(turretYaw, gunPitch, maxTurretRotationSpeed, maxGunRotationSpeed)
  840.         self.getOwnVehicleShotDispersionAngle(self.gunRotator.turretRotationSpeed)
  841.  
  842.     def updateGunMarker(self, shotPos, shotVec, dispersionAngle):
  843.         self.gunRotator.setShotPosition(shotPos, shotVec, dispersionAngle)
  844.  
  845.     def updateOwnVehiclePosition(self, position, direction, speed, rspeed):
  846.         if self.__setOwnVehicleMatrixTimerID is not None:
  847.             BigWorld.cancelCallback(self.__setOwnVehicleMatrixTimerID)
  848.             self.__setOwnVehicleMatrixTimerID = None
  849.         m = Math.Matrix()
  850.         m.setRotateYPR(direction)
  851.         m.translation = position
  852.         self.__ownVehicleMProv.setStaticTransform(m)
  853.         self.__lastVehicleSpeeds = (speed, rspeed)
  854.         BigWorld.wg_setOutAoIEntityParams(self.playerVehicleID, position, direction)
  855.         self.__ownVehicleMProv.target = None
  856.         self.__setOwnVehicleMatrixTimerID = BigWorld.callback(SERVER_TICK_LENGTH, self.__setOwnVehicleMatrixCallback)
  857.         return
  858.  
  859.     def updateVehicleDestroyTimer(self, code, time, warnLvl = None):
  860.         if g_windowsManager.battleWindow is not None:
  861.             if warnLvl is None:
  862.                 if time > 0:
  863.                     g_windowsManager.battleWindow.showVehicleTimer(code, time)
  864.                 else:
  865.                     g_windowsManager.battleWindow.hideVehicleTimer(code)
  866.             elif warnLvl == DROWN_WARNING_LEVEL.DANGER:
  867.                 g_windowsManager.battleWindow.showVehicleTimer(code, time, 'critical')
  868.             elif warnLvl == DROWN_WARNING_LEVEL.CAUTION:
  869.                 g_windowsManager.battleWindow.showVehicleTimer(code, 0, 'warning')
  870.             else:
  871.                 g_windowsManager.battleWindow.hideVehicleTimer(code)
  872.         return
  873.  
  874.     def showOwnVehicleHitDirection(self, hitDirYaw, isDamage):
  875.         if self.inputHandler.aim is not None:
  876.             self.inputHandler.aim.showHit(hitDirYaw, isDamage)
  877.         return
  878.  
  879.     def showVehicleDamageInfo(self, vehicleID, damageIndex, extraIndex, entityID):
  880.         damageCode = constants.DAMAGE_INFO_CODES[damageIndex]
  881.         extra = self.vehicleTypeDescriptor.extras[extraIndex] if extraIndex != 0 else None
  882.         if vehicleID == self.playerVehicleID or not self.__isVehicleAlive and vehicleID == self.inputHandler.ctrl.curVehicleID:
  883.             self.__showDamageIconAndPlaySound(damageCode, extra)
  884.         if damageCode not in self.__damageInfoNoNotification:
  885.             self.battleMessages.showVehicleDamageInfo(damageCode, entityID, extra)
  886.         return
  887.  
  888.     def showShotResults(self, results):
  889.         arenaVehicles = self.arena.vehicles
  890.         VHF = VEHICLE_HIT_FLAGS
  891.         enemies = {}
  892.         burningEnemies = []
  893.         damagedAllies = []
  894.         hasKill = False
  895.         for r in results:
  896.             vehicleID = r & 4294967295L
  897.             flags = r >> 32 & 4294967295L
  898.             if flags & VHF.VEHICLE_WAS_DEAD_BEFORE_ATTACK:
  899.                 continue
  900.             if flags & VHF.VEHICLE_KILLED:
  901.                 hasKill = True
  902.                 continue
  903.             if self.team == arenaVehicles[vehicleID]['team'] and self.playerVehicleID != vehicleID:
  904.                 if flags & (VHF.IS_ANY_DAMAGE_MASK | VHF.ATTACK_IS_DIRECT_PROJECTILE):
  905.                     damagedAllies.append(vehicleID)
  906.             else:
  907.                 enemies[vehicleID] = enemies.get(vehicleID, 0) | flags
  908.                 if flags & VHF.FIRE_STARTED:
  909.                     burningEnemies.append(vehicleID)
  910.  
  911.         for vehicleID in damagedAllies:
  912.             g_windowsManager.battleWindow.pMsgsPanel.showMessage('ALLY_HIT', {'entity': g_battleContext.getFullPlayerName(vID=vehicleID)}, extra=(('entity', vehicleID),))
  913.  
  914.         if hasKill:
  915.             return
  916.         else:
  917.             bestSound = None
  918.             for vehicleID, flags in enemies.iteritems():
  919.                 if flags & VHF.IS_ANY_PIERCING_MASK:
  920.                     BigWorld.callback(0.5, lambda : self.__fireNonFatalDamageTrigger(vehicleID))
  921.                 sound = None
  922.                 if flags & VHF.ATTACK_IS_EXTERNAL_EXPLOSION:
  923.                     if flags & VHF.MATERIAL_WITH_POSITIVE_DF_PIERCED_BY_EXPLOSION:
  924.                         sound = 'enemy_hp_damaged_by_near_explosion_by_player'
  925.                     elif flags & VHF.IS_ANY_PIERCING_MASK:
  926.                         sound = 'enemy_no_hp_damage_by_near_explosion_by_player'
  927.                 else:
  928.                     raise flags & VHF.ATTACK_IS_DIRECT_PROJECTILE or AssertionError
  929.                     if flags & VHF.MATERIAL_WITH_POSITIVE_DF_PIERCED_BY_PROJECTILE:
  930.                         if flags & (VHF.GUN_DAMAGED_BY_PROJECTILE | VHF.GUN_DAMAGED_BY_EXPLOSION):
  931.                             sound = 'enemy_hp_damaged_by_projectile_and_gun_damaged_by_player'
  932.                         elif flags & (VHF.CHASSIS_DAMAGED_BY_PROJECTILE | VHF.CHASSIS_DAMAGED_BY_EXPLOSION):
  933.                             sound = 'enemy_hp_damaged_by_projectile_and_chassis_damaged_by_player'
  934.                         else:
  935.                             sound = 'enemy_hp_damaged_by_projectile_by_player'
  936.                     elif flags & VHF.MATERIAL_WITH_POSITIVE_DF_PIERCED_BY_EXPLOSION:
  937.                         sound = 'enemy_hp_damaged_by_explosion_at_direct_hit_by_player'
  938.                     elif flags & VHF.RICOCHET and not flags & VHF.DEVICE_PIERCED_BY_PROJECTILE:
  939.                         sound = 'enemy_ricochet_by_player'
  940.                         if len(enemies) == 1:
  941.                             TriggersManager.g_manager.fireTrigger(TRIGGER_TYPE.PLAYER_SHOT_RICOCHET, targetId=vehicleID)
  942.                     elif flags & VHF.MATERIAL_WITH_POSITIVE_DF_NOT_PIERCED_BY_PROJECTILE:
  943.                         if flags & (VHF.GUN_DAMAGED_BY_PROJECTILE | VHF.GUN_DAMAGED_BY_EXPLOSION):
  944.                             sound = 'enemy_no_hp_damage_at_attempt_and_gun_damaged_by_player'
  945.                         elif flags & (VHF.CHASSIS_DAMAGED_BY_PROJECTILE | VHF.CHASSIS_DAMAGED_BY_EXPLOSION):
  946.                             sound = 'enemy_no_hp_damage_at_attempt_and_chassis_damaged_by_player'
  947.                         else:
  948.                             sound = 'enemy_no_hp_damage_at_attempt_by_player'
  949.                             if len(enemies) == 1:
  950.                                 TriggersManager.g_manager.fireTrigger(TRIGGER_TYPE.PLAYER_SHOT_NOT_PIERCED, targetId=vehicleID)
  951.                     elif flags & (VHF.GUN_DAMAGED_BY_PROJECTILE | VHF.GUN_DAMAGED_BY_EXPLOSION):
  952.                         sound = 'enemy_no_hp_damage_at_no_attempt_and_gun_damaged_by_player'
  953.                     elif flags & (VHF.CHASSIS_DAMAGED_BY_PROJECTILE | VHF.CHASSIS_DAMAGED_BY_EXPLOSION):
  954.                         sound = 'enemy_no_hp_damage_at_no_attempt_and_chassis_damaged_by_player'
  955.                     else:
  956.                         if flags & VHF.IS_ANY_PIERCING_MASK:
  957.                             sound = 'enemy_no_hp_damage_at_no_attempt_by_player'
  958.                         else:
  959.                             sound = 'enemy_no_piercing_by_player'
  960.                         if len(enemies) == 1:
  961.                             TriggersManager.g_manager.fireTrigger(TRIGGER_TYPE.PLAYER_SHOT_NOT_PIERCED, targetId=vehicleID)
  962.                 if sound is not None:
  963.                     bestSound = _getBestShotResultSound(bestSound, sound, vehicleID)
  964.  
  965.             if bestSound is not None:
  966.                 self.soundNotifications.play(bestSound[0], bestSound[1])
  967.             for vehicleID in burningEnemies:
  968.                 self.soundNotifications.play('enemy_fire_started_by_player', vehicleID)
  969.  
  970.             return
  971.  
  972.     def showOtherVehicleDamagedDevices(self, vehicleID, damagedExtras, destroyedExtras):
  973.         target = BigWorld.target()
  974.         if target is None or not isinstance(target, Vehicle.Vehicle):
  975.             if self.__maySeeOtherVehicleDamagedDevices and vehicleID != 0:
  976.                 self.cell.monitorVehicleDamagedDevices(0)
  977.             return
  978.         elif target.id == vehicleID:
  979.             g_windowsManager.battleWindow.damageInfoPanel.show(vehicleID, damagedExtras, destroyedExtras)
  980.             return
  981.         else:
  982.             if self.__maySeeOtherVehicleDamagedDevices:
  983.                 self.cell.monitorVehicleDamagedDevices(target.id)
  984.             g_windowsManager.battleWindow.damageInfoPanel.hide()
  985.             return
  986.  
  987.     def showDevelopmentInfo(self, code, arg):
  988.         params = cPickle.loads(arg)
  989.         if code == DEVELOPMENT_INFO.BONUSES:
  990.             if constants.IS_DEVELOPMENT:
  991.                 if self.playerBonusesPanel is not None:
  992.                     self.playerBonusesPanel.setVisible(True)
  993.                     self.playerBonusesPanel.setContent(params)
  994.         elif code == DEVELOPMENT_INFO.VISIBILITY:
  995.             if constants.IS_DEVELOPMENT:
  996.                 import Cat
  997.                 Cat.Tasks.VisibilityTest.VisibilityTestObject.setContent(params)
  998.         elif code == DEVELOPMENT_INFO.VEHICLE_ATTRS:
  999.             if constants.IS_DEVELOPMENT:
  1000.                 attrs = cPickle.loads(arg)
  1001.                 LOG_DEBUG('circularVisionRadius: %s' % attrs['circularVisionRadius'])
  1002.         else:
  1003.             LOG_MX('showDevelopmentInfo', code, params)
  1004.         return
  1005.  
  1006.     def showTracer(self, shooterID, shotID, effectsIndex, refStartPoint, velocity, gravity):
  1007.         if not self.userSeesWorld():
  1008.             return
  1009.         else:
  1010.             startPoint = refStartPoint
  1011.             shooter = BigWorld.entity(shooterID)
  1012.             if shooter is not None and shooter.isStarted:
  1013.                 gunMatrix = Math.Matrix(shooter.appearance.modelsDesc['gun']['model'].node('HP_gunFire'))
  1014.                 gunFirePos = gunMatrix.translation
  1015.                 if cameras.isPointOnScreen(gunFirePos):
  1016.                     startPoint = gunFirePos
  1017.                     replayCtrl = BattleReplay.g_replayCtrl
  1018.                     if (gunFirePos - refStartPoint).length > 50.0 and (gunFirePos - BigWorld.camera().position).length < 50.0 and replayCtrl.isPlaying:
  1019.                         velocity = velocity.length * gunMatrix.applyVector((0, 0, 1))
  1020.             effectsDescr = vehicles.g_cache.shotEffects[effectsIndex]
  1021.             isOwnShoot = self.playerVehicleID == shooterID
  1022.             self.__projectileMover.add(shotID, effectsDescr, gravity, refStartPoint, velocity, startPoint, isOwnShoot, BigWorld.camera().position)
  1023.             return
  1024.  
  1025.     def stopTracer(self, shotID, endPoint):
  1026.         if self.userSeesWorld():
  1027.             self.__projectileMover.hide(shotID, endPoint)
  1028.  
  1029.     def explodeProjectile(self, shotID, effectsIndex, effectMaterialIndex, endPoint, velocityDir, damagedDestructibles):
  1030.         if self.userSeesWorld():
  1031.             effectsDescr = vehicles.g_cache.shotEffects[effectsIndex]
  1032.             effectMaterial = EFFECT_MATERIALS[effectMaterialIndex]
  1033.             self.__projectileMover.explode(shotID, effectsDescr, effectMaterial, endPoint, velocityDir)
  1034.  
  1035.     def onRoundFinished(self, winnerTeam, reason):
  1036.         LOG_MX('onRoundFinished', winnerTeam, reason)
  1037.  
  1038.     def onKickedFromArena(self, reasonCode):
  1039.         LOG_DEBUG('onKickedFromArena', reasonCode)
  1040.         g_playerEvents.onKickedFromArena(reasonCode)
  1041.  
  1042.     def onScoutEvent(self, eventType, reportedID):
  1043.         LOG_DEBUG('onScoutEvent, eventType = %s, reportedID = %s' % (eventType, reportedID))
  1044.         msgType = ''
  1045.         if eventType == SCOUT_EVENT_TYPE.SPOTTED:
  1046.             self.complexSoundNotifications.notifyEnemySpotted(reportedID == 0)
  1047.             msgType = 'ENEMY_SPOTTED'
  1048.         elif eventType == SCOUT_EVENT_TYPE.HIT_ASSIST:
  1049.             msgType = 'ENEMY_SPOTTED_HIT'
  1050.         elif eventType == SCOUT_EVENT_TYPE.KILL_ASSIST:
  1051.             self.soundNotifications.play('enemy_killed')
  1052.             msgType = 'ENEMY_SPOTTED_KILLED'
  1053.         additionalInfo = None
  1054.         extra = None
  1055.         if reportedID > 0:
  1056.             additionalInfo = {'entity': g_battleContext.getFullPlayerName(vID=reportedID)}
  1057.             extra = (('entity', reportedID),)
  1058.         else:
  1059.             msgType += '_PLURAL'
  1060.         g_windowsManager.battleWindow.pMsgsPanel.showMessage(msgType, additionalInfo, extra)
  1061.         return
  1062.  
  1063.     def updateArena(self, updateType, argStr):
  1064.         self.arena.update(updateType, argStr)
  1065.  
  1066.     def updatePositions(self, indices, positions):
  1067.         self.arena.updatePositions(indices, positions)
  1068.  
  1069.     def onMinimapCellClicked(self, cellIdx):
  1070.         if self.__isForcedGuiControlMode:
  1071.             channelID = chatManager.battleTeamChannelID
  1072.             if channelID != 0:
  1073.                 ClientChat.sendChannelChatCommand(self, chatManager.battleTeamChannelID, CHAT_COMMANDS.ATTENTIONTOCELL, int16Arg=cellIdx)
  1074.  
  1075.     def onAmmoButtonPressed(self, idx):
  1076.         if not self.__isVehicleAlive:
  1077.             return
  1078.         if idx == self.__currShellsIdx and idx == self.__nextShellsIdx:
  1079.             return
  1080.         if idx not in self.__ammo.keys():
  1081.             return
  1082.         replayCtrl = BattleReplay.g_replayCtrl
  1083.         if replayCtrl.isRecording:
  1084.             replayCtrl.onAmmoButtonPressed(idx)
  1085.         compactDescr, quantity, _ = self.__ammo[idx]
  1086.         if quantity <= 0:
  1087.             return
  1088.         if idx == self.__nextShellsIdx:
  1089.             code = VEHICLE_SETTING.CURRENT_SHELLS
  1090.         else:
  1091.             code = VEHICLE_SETTING.NEXT_SHELLS
  1092.         self.updateVehicleSetting(code, compactDescr)
  1093.         if self.__isOnArena:
  1094.             self.base.vehicle_changeSetting(code, compactDescr)
  1095.  
  1096.     def onEquipmentButtonPressed(self, idx, deviceName = None):
  1097.         if not self.__isOnArena or not self.__isVehicleAlive:
  1098.             return
  1099.         elif idx not in self.__equipment.keys():
  1100.             return
  1101.         else:
  1102.             compactDescr, quantity, time = self.__equipment[idx]
  1103.             if quantity <= 0 or compactDescr == 0 or time > 0:
  1104.                 return
  1105.             artefact = vehicles.getDictDescr(compactDescr)
  1106.             if not artefact.tags or artefact.tags & frozenset(('fuel', 'stimulator')):
  1107.                 return
  1108.             consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  1109.             param = 0
  1110.             if artefact.tags & frozenset(('medkit', 'repairkit')):
  1111.                 entitySuffix = 'Health'
  1112.                 if deviceName is not None:
  1113.                     extra = self.vehicleTypeDescriptor.extrasDict[deviceName + entitySuffix]
  1114.                     param = (extra.index << 16) + artefact.id[1]
  1115.                 elif artefact.repairAll:
  1116.                     if len(self.__deviceStates) > 0:
  1117.                         param = 65536 + artefact.id[1]
  1118.                     else:
  1119.                         self.__showPlayerError('medkitAllTankmenAreSafe' if 'medkit' in artefact.tags else 'repairkitAllDevicesAreNotDamaged')
  1120.                         return
  1121.                 else:
  1122.                     vTypeDescr = self.vehicleTypeDescriptor.type
  1123.                     if 'medkit' in artefact.tags:
  1124.                         tagName = 'medkit'
  1125.                         enumRoles = {'gunner': 1,
  1126.                          'loader': 1,
  1127.                          'radioman': 1}
  1128.                         tankmen = []
  1129.                         for roles in vTypeDescr.crewRoles:
  1130.                             mainRole = roles[0]
  1131.                             if mainRole in enumRoles.keys():
  1132.                                 tankmen.append(mainRole + str(enumRoles[mainRole]))
  1133.                                 enumRoles[mainRole] += 1
  1134.                             else:
  1135.                                 tankmen.append(mainRole)
  1136.  
  1137.                         entityStates = dict.fromkeys(tankmen)
  1138.                     else:
  1139.                         tagName = 'repairkit'
  1140.                         entityStates = dict.fromkeys(tuple((device.name[:-len(entitySuffix)] for device in vTypeDescr.devices)))
  1141.                     for eName in entityStates.keys():
  1142.                         state = self.__deviceStates.get(eName, None)
  1143.                         entityStates[eName] = state
  1144.  
  1145.                     consumablesPanel.expandEquipmentSlot(idx, tagName, entityStates)
  1146.                     return
  1147.             if artefact.tags & frozenset(('extinguisher',)):
  1148.                 if not self.__fireInVehicle:
  1149.                     self.__showPlayerError('extinguisherDoesNotActivated', args={'name': artefact.userString})
  1150.                     return
  1151.                 flag = self.__equipmentFlags.get(idx)
  1152.                 if flag == 1:
  1153.                     self.__showPlayerError('equipmentAlreadyActivated', args={'name': artefact.userString})
  1154.                     return
  1155.                 param = 65536 + artefact.id[1]
  1156.                 self.__equipmentFlags[idx] = 1
  1157.             if artefact.tags & frozenset(('trigger',)):
  1158.                 flag = self.__equipmentFlags.get(idx, 0)
  1159.                 flag ^= 1
  1160.                 param = (flag << 16) + artefact.id[1]
  1161.                 self.__equipmentFlags[idx] = flag
  1162.             self.base.vehicle_changeSetting(VEHICLE_SETTING.ACTIVATE_EQUIPMENT, param)
  1163.             return
  1164.  
  1165.     def onDamageIconButtonPressed(self, tag, deviceName):
  1166.         for idx, (compactDescr, _, _) in self.__equipment.iteritems():
  1167.             if compactDescr == 0:
  1168.                 continue
  1169.             eDescr = vehicles.getDictDescr(compactDescr)
  1170.             if eDescr.tags & frozenset((tag,)):
  1171.                 self.onEquipmentButtonPressed(idx, deviceName=deviceName)
  1172.                 return
  1173.  
  1174.     def onReloadPartialClipKeyDown(self):
  1175.         clipCapacity, _ = self.vehicleTypeDescriptor.gun['clip']
  1176.         if clipCapacity > 1 and self.__currShellsIdx < len(self.__ammo):
  1177.             _, quantity, quantityInClip = self.__ammo[self.__currShellsIdx]
  1178.             if quantity != 0 and quantityInClip < clipCapacity:
  1179.                 self.base.vehicle_changeSetting(VEHICLE_SETTING.RELOAD_PARTIAL_CLIP, 0)
  1180.  
  1181.     def receiveHorn(self, vehicleID, hornID, start):
  1182.         vInfo = self.arena.vehicles.get(vehicleID, {})
  1183.         user = storage_getter('users')().getUser(vInfo.get('accountDBID', 0))
  1184.         if user and user.isIgnored() and start:
  1185.             return
  1186.         else:
  1187.             vehicle = BigWorld.entities.get(vehicleID)
  1188.             if vehicle is not None:
  1189.                 if start:
  1190.                     vehicle.playHornSound(hornID)
  1191.                 else:
  1192.                     vehicle.stopHornSound()
  1193.             return
  1194.  
  1195.     def useHorn(self, start):
  1196.         if not self.__isVehicleAlive or not self.__isOnArena:
  1197.             return
  1198.         elif self.vehicleTypeDescriptor is None or self.vehicleTypeDescriptor.hornID is None:
  1199.             return
  1200.         elif start and not self.__hornCooldown.ask():
  1201.             g_windowsManager.battleWindow.vMsgsPanel.showMessage('HORN_IS_BLOCKED', max(1.0, self.__hornCooldown.banTime()))
  1202.             return
  1203.         else:
  1204.             playerVehicle = BigWorld.entities.get(self.playerVehicleID)
  1205.             if playerVehicle is not None:
  1206.                 if start:
  1207.                     playerVehicle.playHornSound(playerVehicle.typeDescriptor.hornID)
  1208.                 else:
  1209.                     playerVehicle.stopHornSound()
  1210.             self.base.vehicle_useHorn(start)
  1211.             return
  1212.  
  1213.     def isHornActive(self):
  1214.         playerVehicle = BigWorld.entities.get(self.playerVehicleID)
  1215.         if playerVehicle is not None:
  1216.             return playerVehicle.isHornActive()
  1217.         else:
  1218.             return False
  1219.             return
  1220.  
  1221.     def hornMode(self):
  1222.         playerVehicle = BigWorld.entities.get(self.playerVehicleID)
  1223.         if playerVehicle is not None:
  1224.             return playerVehicle.hornMode
  1225.         else:
  1226.             return ''
  1227.             return
  1228.  
  1229.     def makeDenunciation(self, violatorID, topicID, violatorKind):
  1230.         if self.denunciationsLeft <= 0:
  1231.             return
  1232.         self.denunciationsLeft -= 1
  1233.         self.base.makeDenunciation(violatorID, topicID, violatorKind)
  1234.  
  1235.     def banUnbanUser(self, accountDBID, restrType, banPeriod, reason, isBan):
  1236.         reason = reason.encode('utf8')
  1237.         self.base.banUnbanUser(accountDBID, restrType, banPeriod, reason, isBan)
  1238.  
  1239.     def receiveAccountStats(self, requestID, stats):
  1240.         callback = self.__onCmdResponse.pop(requestID, None)
  1241.         if callback is None:
  1242.             return
  1243.         else:
  1244.             try:
  1245.                 stats = cPickle.loads(stats)
  1246.             except:
  1247.                 LOG_CURRENT_EXCEPTION()
  1248.  
  1249.             callback(stats)
  1250.             return
  1251.  
  1252.     def requestAccountStats(self, names, callback):
  1253.         requestID = self.__getRequestID()
  1254.         self.__onCmdResponse[requestID] = callback
  1255.         self.base.sendAccountStats(requestID, names)
  1256.  
  1257.     def storeClientCtx(self, clientCtx):
  1258.         self.clientCtx = clientCtx
  1259.         self.base.setClientCtx(clientCtx)
  1260.  
  1261.     def teleportVehicle(self, position, yaw):
  1262.         self.base.vehicle_teleport(position, yaw)
  1263.  
  1264.     def replenishAmmo(self):
  1265.         self.base.vehicle_replenishAmmo()
  1266.  
  1267.     def moveVehicleByCurrentKeys(self, isKeyDown, forceFlags = 204, forceMask = 0):
  1268.         moveFlags = self.makeVehicleMovementCommandByKeys(forceFlags, forceMask)
  1269.         self.moveVehicle(moveFlags, isKeyDown)
  1270.  
  1271.     def makeVehicleMovementCommandByKeys(self, forceFlags = 204, forceMask = 0):
  1272.         cmdMap = CommandMapping.g_instance
  1273.         flags = 0
  1274.         if self.__stopUntilFire:
  1275.             return flags
  1276.         if cmdMap.isActiveList((CommandMapping.CMD_MOVE_FORWARD, CommandMapping.CMD_MOVE_FORWARD_SPEC)):
  1277.             flags = 1
  1278.         elif cmdMap.isActive(CommandMapping.CMD_MOVE_BACKWARD):
  1279.             flags = 2
  1280.         else:
  1281.             if self.__cruiseControlMode >= _CRUISE_CONTROL_MODE.FWD25:
  1282.                 flags = 1
  1283.             elif self.__cruiseControlMode <= _CRUISE_CONTROL_MODE.BCKW50:
  1284.                 flags = 2
  1285.             if not self.__cruiseControlMode == _CRUISE_CONTROL_MODE.FWD50:
  1286.                 isOn = True
  1287.             else:
  1288.                 isOn = self.__cruiseControlMode == _CRUISE_CONTROL_MODE.BCKW50
  1289.             if isOn:
  1290.                 flags = flags | 16
  1291.             elif self.__cruiseControlMode == _CRUISE_CONTROL_MODE.FWD25:
  1292.                 flags = flags | 32
  1293.         rotateLeftFlag = 4
  1294.         rotateRightFlag = 8
  1295.         if self.invRotationOnBackMovement and flags & 2 != 0:
  1296.             rotateLeftFlag, rotateRightFlag = rotateRightFlag, rotateLeftFlag
  1297.         if cmdMap.isActive(CommandMapping.CMD_ROTATE_LEFT):
  1298.             flags = flags | rotateLeftFlag
  1299.         if cmdMap.isActive(CommandMapping.CMD_ROTATE_RIGHT):
  1300.             flags = flags | rotateRightFlag
  1301.         flags = (flags | forceMask) & forceFlags
  1302.         flags &= ~forceMask | forceFlags
  1303.         return flags
  1304.  
  1305.     def moveVehicle(self, flags, isKeyDown):
  1306.         if not self.__isOnArena:
  1307.             return
  1308.         else:
  1309.             cantMove = False
  1310.             if self.inputHandler.ctrl.isSelfVehicle():
  1311.                 for deviceName, stateName in self.__deviceStates.iteritems():
  1312.                     msgName = self.__cantMoveCriticals.get(deviceName + '_' + stateName)
  1313.                     if msgName is not None:
  1314.                         cantMove = True
  1315.                         if isKeyDown:
  1316.                             self.__showPlayerError(msgName)
  1317.                         break
  1318.  
  1319.             if not cantMove:
  1320.                 vehicle = BigWorld.entity(self.playerVehicleID)
  1321.                 if vehicle is not None and vehicle.isStarted:
  1322.                     vehicle.showPlayerMovementCommand(flags)
  1323.                     rotationDir = -1 if flags & 4 else (1 if flags & 8 else 0)
  1324.                     movementDir = -1 if flags & 2 else (1 if flags & 1 else 0)
  1325.                     vehicle.filter.notifyInputKeysDown(movementDir, rotationDir)
  1326.                     if isKeyDown:
  1327.                         self.inputHandler.setAutorotation(True)
  1328.             self.base.vehicle_moveWith(flags)
  1329.             return
  1330.  
  1331.     def enableOwnVehicleAutorotation(self, enable):
  1332.         battleWindow = g_windowsManager.battleWindow
  1333.         if battleWindow is not None:
  1334.             battleWindow.damagePanel.onVehicleAutorotationEnabled(enable)
  1335.         self.base.vehicle_changeSetting(VEHICLE_SETTING.AUTOROTATION_ENABLED, enable)
  1336.         return
  1337.  
  1338.     def enableServerAim(self, enable):
  1339.         self.base.setDevelopmentFeature('server_marker', enable)
  1340.  
  1341.     def autoAim(self, target):
  1342.         if target is None:
  1343.             vehID = 0
  1344.         elif not isinstance(target, Vehicle.Vehicle):
  1345.             vehID = 0
  1346.         elif target.id == self.__autoAimVehID:
  1347.             vehID = 0
  1348.         elif target.publicInfo['team'] == self.team:
  1349.             vehID = 0
  1350.         elif not target.isAlive():
  1351.             vehID = 0
  1352.         else:
  1353.             vehID = target.id
  1354.         if self.__autoAimVehID != vehID:
  1355.             self.__autoAimVehID = vehID
  1356.             self.cell.autoAim(vehID)
  1357.             if vehID != 0:
  1358.                 self.inputHandler.setAimingMode(True, AIMING_MODE.TARGET_LOCK)
  1359.                 self.gunRotator.clientMode = False
  1360.                 self.soundNotifications.play('target_captured')
  1361.                 TriggersManager.g_manager.activateTrigger(TRIGGER_TYPE.AUTO_AIM_AT_VEHICLE, vehicleId=vehID)
  1362.             else:
  1363.                 self.inputHandler.setAimingMode(False, AIMING_MODE.TARGET_LOCK)
  1364.                 self.gunRotator.clientMode = True
  1365.                 self.__aimingInfo[0] = BigWorld.time()
  1366.                 minShotDisp = self.vehicleTypeDescriptor.gun['shotDispersionAngle']
  1367.                 self.__aimingInfo[1] = self.gunRotator.dispersionAngle / minShotDisp
  1368.                 self.soundNotifications.play('target_unlocked')
  1369.                 TriggersManager.g_manager.deactivateTrigger(TRIGGER_TYPE.AUTO_AIM_AT_VEHICLE)
  1370.         return
  1371.  
  1372.     def shoot(self, isRepeat = False):
  1373.         if self.__tryShootCallbackId is None:
  1374.             self.__tryShootCallbackId = BigWorld.callback(0.0, self.__tryShootCallback)
  1375.         if not self.__isOnArena:
  1376.             return
  1377.         else:
  1378.             for deviceName, stateName in self.__deviceStates.iteritems():
  1379.                 msgName = self.__cantShootCriticals.get(deviceName + '_' + stateName)
  1380.                 if msgName is not None:
  1381.                     self.__showPlayerError(msgName)
  1382.                     return
  1383.  
  1384.             if self.__currShellsIdx is None:
  1385.                 return
  1386.             if self.__ammo[self.__currShellsIdx][1] == 0:
  1387.                 if not isRepeat:
  1388.                     self.__showPlayerError(self.__cantShootCriticals['no_ammo'])
  1389.                 return
  1390.             if self.inputHandler.aim and self.inputHandler.aim.isGunReload():
  1391.                 if not isRepeat:
  1392.                     self.__showPlayerError(self.__cantShootCriticals['gun_reload'])
  1393.                 return
  1394.             if self.__gunReloadCommandWaitEndTime > BigWorld.time():
  1395.                 return
  1396.             if self.__shotWaitingTimerID is not None:
  1397.                 return
  1398.             if self.isGunLocked or self.__isOwnBarrelUnderWater():
  1399.                 if not isRepeat:
  1400.                     self.__showPlayerError(self.__cantShootCriticals['gun_locked'])
  1401.                 return
  1402.             self.base.vehicle_shoot()
  1403.             self.__startWaitingForShot()
  1404.             if self.__stopUntilFire:
  1405.                 self.__stopUntilFire = False
  1406.                 if BigWorld.time() - self.__stopUntilFireStartTime > 60.0:
  1407.                     self.__cruiseControlMode = _CRUISE_CONTROL_MODE.NONE
  1408.                 self.__updateCruiseControlPanel()
  1409.                 self.moveVehicle(self.makeVehicleMovementCommandByKeys(), True)
  1410.             return
  1411.  
  1412.     def __tryShootCallback(self):
  1413.         self.__tryShootCallbackId = None
  1414.         if CommandMapping.g_instance.isActive(CommandMapping.CMD_CM_SHOOT):
  1415.             self.shoot(isRepeat=True)
  1416.         return
  1417.  
  1418.     def cancelWaitingForShot(self):
  1419.         if self.__shotWaitingTimerID is not None:
  1420.             BigWorld.cancelCallback(self.__shotWaitingTimerID)
  1421.             self.__shotWaitingTimerID = None
  1422.             self.inputHandler.setAimingMode(False, AIMING_MODE.SHOOTING)
  1423.             self.gunRotator.targetLastShotPoint = False
  1424.         return
  1425.  
  1426.     def selectPlayer(self, vehId):
  1427.         if self.__isForcedGuiControlMode:
  1428.             vehicleDesc = self.arena.vehicles.get(vehId)
  1429.             if vehicleDesc['isAlive'] and vehicleDesc['team'] == self.team:
  1430.                 self.inputHandler.selectPlayer(vehId)
  1431.  
  1432.     def leaveArena(self):
  1433.         LOG_DEBUG('Avatar.leaveArena')
  1434.         replayCtrl = BattleReplay.g_replayCtrl
  1435.         if replayCtrl.isRecording or replayCtrl.isPlaying:
  1436.             replayCtrl.stop()
  1437.         g_playerEvents.isPlayerEntityChanging = True
  1438.         g_playerEvents.onPlayerEntityChanging()
  1439.         self.__setIsOnArena(False)
  1440.         self.base.leaveArena()
  1441.  
  1442.     def addBotToArena(self, vehicleTypeName, team):
  1443.         compactDescr = vehicles.VehicleDescr(typeName=vehicleTypeName).makeCompactDescr()
  1444.         self.base.addBotToArena(compactDescr, team, self.name)
  1445.  
  1446.     def controlAnotherVehicle(self, vehicleID, callback = None):
  1447.         BigWorld.entity(self.playerVehicleID).isPlayer = False
  1448.         self.base.controlAnotherVehicle(vehicleID, 1)
  1449.         if vehicleID not in BigWorld.entities.keys():
  1450.             BigWorld.callback(0.1, partial(self.__controlAnotherVehicleWait, vehicleID, callback, 50))
  1451.             return
  1452.         BigWorld.callback(1.0, partial(self.__controlAnotherVehicleAfteraction, vehicleID, callback))
  1453.  
  1454.     def setForcedGuiControlMode(self, value, stopVehicle = True, enableAiming = True):
  1455.         if self.__stepsTillInit == 0:
  1456.             if self.__isForcedGuiControlMode ^ value:
  1457.                 self.__doSetForcedGuiControlMode(value, enableAiming)
  1458.                 if not value:
  1459.                     flags = self.makeVehicleMovementCommandByKeys()
  1460.                     self.moveVehicle(flags, False)
  1461.             if value and stopVehicle:
  1462.                 self.moveVehicle(0, False)
  1463.         self.__isForcedGuiControlMode = value
  1464.  
  1465.     def getOwnVehiclePosition(self):
  1466.         return Math.Matrix(self.__ownVehicleMProv).translation
  1467.  
  1468.     def getOwnVehicleMatrix(self):
  1469.         return self.__ownVehicleMProv
  1470.  
  1471.     def getOwnVehicleSpeeds(self, getInstantaneous = False):
  1472.         if self.__ownVehicleMProv.target is None:
  1473.             return self.__lastVehicleSpeeds
  1474.         else:
  1475.             vehicle = BigWorld.entity(self.playerVehicleID)
  1476.             if vehicle is None or not vehicle.isStarted:
  1477.                 return self.__lastVehicleSpeeds
  1478.             speedInfo = vehicle.filter.speedInfo.value
  1479.             if getInstantaneous:
  1480.                 speed = speedInfo[2]
  1481.                 rspeed = speedInfo[3]
  1482.             else:
  1483.                 speed = speedInfo[0]
  1484.                 rspeed = speedInfo[1]
  1485.             fwdSpeedLimit, bckwdSpeedLimit = vehicle.typeDescriptor.physics['speedLimits']
  1486.             MAX_SPEED_MULTIPLIER = 1.5
  1487.             fwdSpeedLimit *= MAX_SPEED_MULTIPLIER
  1488.             bckwdSpeedLimit *= MAX_SPEED_MULTIPLIER
  1489.             if speed > fwdSpeedLimit:
  1490.                 speed = fwdSpeedLimit
  1491.             elif speed < -bckwdSpeedLimit:
  1492.                 speed = -bckwdSpeedLimit
  1493.             rspeedLimit = vehicle.typeDescriptor.physics['rotationSpeedLimit']
  1494.             if rspeed > rspeedLimit:
  1495.                 rspeed = rspeedLimit
  1496.             elif rspeed < -rspeedLimit:
  1497.                 rspeed = -rspeedLimit
  1498.             return (speed, rspeed)
  1499.  
  1500.     def getOwnVehicleShotDispersionAngle(self, turretRotationSpeed, withShot = 0):
  1501.         descr = self.vehicleTypeDescriptor
  1502.         aimingStartTime, aimingStartFactor, multFactor, gunShotDispersionFactorsTurretRotation, chassisShotDispersionFactorsMovement, chassisShotDispersionFactorsRotation, aimingTime = self.__aimingInfo
  1503.         vehicleSpeed, vehicleRSpeed = self.getOwnVehicleSpeeds(True)
  1504.         vehicleMovementFactor = vehicleSpeed * chassisShotDispersionFactorsMovement
  1505.         vehicleMovementFactor *= vehicleMovementFactor
  1506.         vehicleRotationFactor = vehicleRSpeed * chassisShotDispersionFactorsRotation
  1507.         vehicleRotationFactor *= vehicleRotationFactor
  1508.         turretRotationFactor = turretRotationSpeed * gunShotDispersionFactorsTurretRotation
  1509.         turretRotationFactor *= turretRotationFactor
  1510.         if withShot == 0:
  1511.             shotFactor = 0.0
  1512.         elif withShot == 1:
  1513.             shotFactor = descr.gun['shotDispersionFactors']['afterShot']
  1514.         else:
  1515.             shotFactor = descr.gun['shotDispersionFactors']['afterShotInBurst']
  1516.         shotFactor *= shotFactor
  1517.         idealFactor = vehicleMovementFactor + vehicleRotationFactor + turretRotationFactor + shotFactor
  1518.         idealFactor *= descr.miscAttrs['additiveShotDispersionFactor'] ** 2
  1519.         idealFactor = multFactor * math.sqrt(1.0 + idealFactor)
  1520.         currTime = BigWorld.time()
  1521.         aimingFactor = aimingStartFactor * math.exp((aimingStartTime - currTime) / aimingTime)
  1522.         aim = self.inputHandler.aim
  1523.         isGunReload = False
  1524.         if aim is not None:
  1525.             isGunReload = aim.isGunReload()
  1526.         if aimingFactor < idealFactor:
  1527.             aimingFactor = idealFactor
  1528.             self.__aimingInfo[0] = currTime
  1529.             self.__aimingInfo[1] = aimingFactor
  1530.             if abs(idealFactor - multFactor) < 0.001:
  1531.                 self.complexSoundNotifications.setAimingEnded(True, isGunReload)
  1532.             elif idealFactor / multFactor > 1.1:
  1533.                 self.complexSoundNotifications.setAimingEnded(False, isGunReload)
  1534.         elif aimingFactor / multFactor > 1.1:
  1535.             self.complexSoundNotifications.setAimingEnded(False, isGunReload)
  1536.         return descr.gun['shotDispersionAngle'] * aimingFactor
  1537.  
  1538.     def handleVehicleCollidedVehicle(self, vehA, vehB, hitPt, time):
  1539.         if self.__vehicleToVehicleCollisions is None:
  1540.             return
  1541.         else:
  1542.             lastCollisionTime = 0
  1543.             key = (vehA, vehB)
  1544.             if not self.__vehicleToVehicleCollisions.has_key(key):
  1545.                 key = (vehB, vehA)
  1546.             if self.__vehicleToVehicleCollisions.has_key(key):
  1547.                 lastCollisionTime = self.__vehicleToVehicleCollisions[key]
  1548.             if time - lastCollisionTime < 0.2:
  1549.                 return
  1550.             self.__vehicleToVehicleCollisions[key] = time
  1551.             vehA.showVehicleCollisionEffect(hitPt)
  1552.             vehSpeedSum = (vehA.filter.velocity - vehB.filter.velocity).length
  1553.             self.inputHandler.onVehicleCollision(vehA, vehSpeedSum)
  1554.             self.inputHandler.onVehicleCollision(vehB, vehSpeedSum)
  1555.             return
  1556.  
  1557.     def getVehicleAttached(self):
  1558.         vehicle = self.vehicle
  1559.         if vehicle is None:
  1560.             vehicle = BigWorld.entity(self.playerVehicleID)
  1561.         if vehicle is None or not vehicle.inWorld or not vehicle.isStarted or vehicle.isDestroyed:
  1562.             return
  1563.         else:
  1564.             return vehicle
  1565.  
  1566.     def receiveBattleResults(self, isSuccess, data):
  1567.         LOG_MX('receiveBattleResults', isSuccess)
  1568.         if not isSuccess:
  1569.             return
  1570.         try:
  1571.             results = cPickle.loads(zlib.decompress(data))
  1572.             BattleResultsCache.save(self.name, results)
  1573.             g_playerEvents.onBattleResultsReceived(True, self.__convertBattleResultsToOldStyle(results))
  1574.             self.base.confirmBattleResultsReceiving()
  1575.         except:
  1576.             LOG_CURRENT_EXCEPTION()
  1577.  
  1578.     def __convertBattleResultsToOldStyle(self, results):
  1579.         from battle_results_shared import VEH_FULL_RESULTS_INDICES, COMMON_RESULTS_INDICES, VEH_PUBLIC_RESULTS_INDICES, VehicleInteractionDetails
  1580.         from dossiers2.custom.records import RECORD_DB_IDS
  1581.         arenaUniqueID, private, pickled = results
  1582.         oldStyle = {}
  1583.         for rec in ('repair', 'credits', 'xp', 'damageDealt', 'shots', 'hits', 'shotsReceived', 'damageReceived', 'capturePoints', 'droppedCapturePoints', 'killerID'):
  1584.             oldStyle[rec] = private[VEH_FULL_RESULTS_INDICES[rec]]
  1585.  
  1586.         common, players, vehicles = cPickle.loads(pickled)
  1587.         for rec in ('arenaCreateTime', 'arenaTypeID'):
  1588.             oldStyle[rec] = common[COMMON_RESULTS_INDICES[rec]]
  1589.  
  1590.         heroVehicleIDs = []
  1591.         achieveIndices = []
  1592.         for vehID, vehRes in vehicles.iteritems():
  1593.             for achieveName in ('warrior', 'invader', 'sniper', 'defender', 'steelwall', 'supporter', 'scout', 'evileye'):
  1594.                 recordDBID = RECORD_DB_IDS['achievements', achieveName]
  1595.                 if recordDBID in vehRes[VEH_PUBLIC_RESULTS_INDICES['achievements']]:
  1596.                     heroVehicleIDs.append(vehID)
  1597.                     achieveIndices.append(recordDBID)
  1598.  
  1599.         oldStyle['heroVehicleIDs'] = heroVehicleIDs
  1600.         oldStyle['achieveIndices'] = achieveIndices
  1601.         if common[COMMON_RESULTS_INDICES['winnerTeam']] == private[VEH_FULL_RESULTS_INDICES['team']]:
  1602.             oldStyle['isWinner'] = 1
  1603.         elif common[COMMON_RESULTS_INDICES['winnerTeam']] == 0:
  1604.             oldStyle['isWinner'] = 0
  1605.         else:
  1606.             oldStyle['isWinner'] = -1
  1607.         oldStyle['factors'] = {'dailyXPFactor10': private[VEH_FULL_RESULTS_INDICES['dailyXPFactor10']],
  1608.          'aogasFactor10': private[VEH_FULL_RESULTS_INDICES['aogasFactor10']]}
  1609.         details = private[VEH_FULL_RESULTS_INDICES['details']]
  1610.         asDict = VehicleInteractionDetails.fromPacked(details).toDict()
  1611.         oldStyle['killed'] = [ vehID for vehID, details in asDict.iteritems() if details['deathReason'] != -1 ]
  1612.         oldStyle['spotted'] = [ vehID for vehID, details in asDict.iteritems() if details['spotted'] ]
  1613.         oldStyle['damaged'] = [ vehID for vehID, details in asDict.iteritems() if details['damageDealt'] ]
  1614.         return oldStyle
  1615.  
  1616.     def __onAction(self, action):
  1617.         self.onChatShortcut(action)
  1618.  
  1619.     __cantShootCriticals = {'gun_destroyed': 'cantShootGunDamaged',
  1620.      'vehicle_destroyed': 'cantShootVehicleDestroyed',
  1621.      'crew_destroyed': 'cantShootCrewInactive',
  1622.      'no_ammo': 'cantShootNoAmmo',
  1623.      'gun_reload': 'cantShootGunReloading',
  1624.      'gun_locked': 'cantShootGunLocked'}
  1625.  
  1626.     def __onInitStepCompleted(self):
  1627.         LOG_DEBUG('Avatar.__onInitStepCompleted()', self.__stepsTillInit)
  1628.         if constants.IS_CAT_LOADED:
  1629.             if self.__stepsTillInit == 0:
  1630.                 return
  1631.         if not self.__stepsTillInit > 0:
  1632.             raise AssertionError
  1633.             self.__stepsTillInit -= 1
  1634.             return self.__stepsTillInit != 0 and None
  1635.         else:
  1636.             self.initSpace()
  1637.             self.__startGUI()
  1638.             DecalMap.g_instance.initGroups(1.0)
  1639.             if self.__isForcedGuiControlMode:
  1640.                 self.__doSetForcedGuiControlMode(True, True)
  1641.             self.__setOwnVehicleMatrixCallback()
  1642.             for v in BigWorld.entities.values():
  1643.                 if v.inWorld and isinstance(v, Vehicle.Vehicle) and not v.isStarted:
  1644.                     v.startVisual()
  1645.                     self.onVehicleEnterWorld(v)
  1646.  
  1647.             SoundGroups.g_instance.enableArenaSounds(True)
  1648.             SoundGroups.g_instance.applyPreferences()
  1649.             MusicController.g_musicController.onEnterArena()
  1650.             TriggersManager.g_manager.enable(True)
  1651.             BigWorld.wg_setUmbraEnabled(self.arena.arenaType.umbraEnabled)
  1652.             BigWorld.wg_enableTreeHiding(False)
  1653.             BigWorld.wg_enableSpaceBoundFog(True, _boundingBoxAsVector4(self.arena.arenaType.boundingBox), 0.5)
  1654.             BigWorld.worldDrawEnabled(True)
  1655.             BigWorld.wg_setAmbientReverb(self.arena.arenaType.defaultReverbPreset)
  1656.             BigWorld.wg_setWaterTexScale(self.arena.arenaType.waterTexScale)
  1657.             BigWorld.wg_setWaterFreqX(self.arena.arenaType.waterFreqX)
  1658.             BigWorld.wg_setWaterFreqZ(self.arena.arenaType.waterFreqZ)
  1659.             BattleReplay.g_replayCtrl.onClientReady()
  1660.             self.base.setClientReady()
  1661.             if self.arena.period == ARENA_PERIOD.BATTLE:
  1662.                 self.__setIsOnArena(True)
  1663.             self.arena.onPeriodChange += self.__onArenaPeriodChange
  1664.             ownVehicle = BigWorld.entity(self.playerVehicleID)
  1665.             if ownVehicle is not None:
  1666.                 self.updateVehicleHealth(ownVehicle.health, ownVehicle.isCrewActive)
  1667.             self.cell.autoAim(0)
  1668.             g_playerEvents.onAvatarReady()
  1669.             return
  1670.  
  1671.     def __initGUIConfig(self):
  1672.         up = Settings.g_instance.userPrefs
  1673.         out = dict()
  1674.         out['showFPS'] = True
  1675.         out['showPlayerBonuses'] = True
  1676.         if up.has_key('showFPS'):
  1677.             out['showFPS'] = up.readBool('showFPS')
  1678.         else:
  1679.             up.writeBool('showFPS', True)
  1680.         return out
  1681.  
  1682.     def __initGUI(self):
  1683.         prereqs = []
  1684.         self.guiConfig = self.__initGUIConfig()
  1685.         if not g_offlineMapCreator.Active():
  1686.             self.inputHandler = AvatarInputHandler.AvatarInputHandler()
  1687.             prereqs += self.inputHandler.prerequisites()
  1688.         BigWorld.player().arena
  1689.         self.playerBonusesPanel = None
  1690.         if self.guiConfig['showPlayerBonuses']:
  1691.             self.playerBonusesPanel = PlayerBonusesPanel.PlayerBonusesPanel()
  1692.             prereqs += self.playerBonusesPanel.prerequisites()
  1693.         self.soundNotifications = IngameSoundNotifications.IngameSoundNotifications()
  1694.         self.complexSoundNotifications = IngameSoundNotifications.ComplexSoundNotifications(self.soundNotifications)
  1695.         self.battleMessages = BattleDamageMessages()
  1696.         return prereqs
  1697.  
  1698.     def __startGUI(self):
  1699.         self.inputHandler.start()
  1700.         self.inputHandler.setReloading(-1)
  1701.         if self.playerBonusesPanel is not None:
  1702.             self.playerBonusesPanel.start()
  1703.             self.playerBonusesPanel.setVisible(False)
  1704.         self.__isGuiVisible = True
  1705.         self.arena.onVehicleKilled += self.__onArenaVehicleKilled
  1706.         MessengerEntry.g_instance.onAvatarShowGUI()
  1707.         g_battleContext.init()
  1708.         battleWindow = g_windowsManager.startBattle()
  1709.         self.soundNotifications.start()
  1710.         self.subscribeChatAction(self.__onUserChatCommand, CHAT_ACTIONS.userChatCommand)
  1711.         return
  1712.  
  1713.     def __destroyGUI(self):
  1714.         g_battleContext.fini()
  1715.         g_windowsManager.destroyBattle()
  1716.         if self.playerBonusesPanel is not None:
  1717.             self.playerBonusesPanel.destroy()
  1718.             self.playerBonusesPanel = None
  1719.         self.arena.onVehicleKilled -= self.__onArenaVehicleKilled
  1720.         self.unsubscribeChatAction(self.__onUserChatCommand, CHAT_ACTIONS.userChatCommand)
  1721.         self.complexSoundNotifications.destroy()
  1722.         self.complexSoundNotifications = None
  1723.         self.soundNotifications.destroy()
  1724.         self.soundNotifications = None
  1725.         self.battleMessages.destroy()
  1726.         self.battleMessages = None
  1727.         self.inputHandler.stop()
  1728.         self.inputHandler = None
  1729.         return
  1730.  
  1731.     def __reloadGUI(self):
  1732.         self.__destroyGUI()
  1733.         self.__initGUI()
  1734.         self.__startGUI()
  1735.         self.setForcedGuiControlMode(True)
  1736.         self.setForcedGuiControlMode(False)
  1737.  
  1738.     def __setVisibleGUI(self, bool):
  1739.         self.__isGuiVisible = bool
  1740.         from gui.Scaleform.Battle import Battle
  1741.         if g_windowsManager.battleWindow is not None:
  1742.             g_windowsManager.battleWindow.showAll(bool)
  1743.         BigWorld.wg_enableTreeTransparency(bool)
  1744.         vehicle = BigWorld.entity(self.playerVehicleID)
  1745.         if vehicle is None:
  1746.             return
  1747.         else:
  1748.             if bool:
  1749.                 BigWorld.wgAddEdgeDetectEntity(vehicle, 0, True)
  1750.             else:
  1751.                 BigWorld.wgDelEdgeDetectEntity(vehicle)
  1752.             self.inputHandler.setGUIVisible(bool)
  1753.             return
  1754.  
  1755.     @property
  1756.     def isGuiVisible(self):
  1757.         return self.__isGuiVisible
  1758.  
  1759.     def __doSetForcedGuiControlMode(self, value, enableAiming):
  1760.         self.inputHandler.detachCursor(value, enableAiming)
  1761.  
  1762.     __cantMoveCriticals = {'engine_destroyed': 'cantMoveEngineDamaged',
  1763.      'leftTrack_destroyed': 'cantMoveChassisDamaged',
  1764.      'rightTrack_destroyed': 'cantMoveChassisDamaged',
  1765.      'vehicle_destroyed': 'cantMoveVehicleDestroyed',
  1766.      'crew_destroyed': 'cantMoveCrewInactive'}
  1767.  
  1768.     def __setIsOnArena(self, onArena):
  1769.         if self.__isOnArena == onArena:
  1770.             return
  1771.         self.__isOnArena = onArena
  1772.         if not onArena:
  1773.             self.gunRotator.stop()
  1774.         else:
  1775.             self.gunRotator.start()
  1776.             if not self.__isForcedGuiControlMode or MessengerEntry.g_instance.gui.isFocused():
  1777.                 self.moveVehicle(self.makeVehicleMovementCommandByKeys(), False)
  1778.             if self.__nextShellsIdx > 0 and self.__nextShellsIdx in self.__ammo:
  1779.                 self.base.vehicle_changeSetting(VEHICLE_SETTING.NEXT_SHELLS, self.__ammo[self.__nextShellsIdx][0])
  1780.             if self.__currShellsIdx > 0 and self.__currShellsIdx in self.__ammo:
  1781.                 self.base.vehicle_changeSetting(VEHICLE_SETTING.CURRENT_SHELLS, self.__ammo[self.__currShellsIdx][0])
  1782.  
  1783.     def __showPlayerError(self, msgName, args = None):
  1784.         g_windowsManager.battleWindow.vErrorsPanel.showMessage(msgName, args)
  1785.  
  1786.     def __showDamageIconAndPlaySound(self, damageCode, extra):
  1787.         damagePanel = g_windowsManager.battleWindow.damagePanel
  1788.         consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  1789.         deviceName = None
  1790.         deviceState = None
  1791.         soundType = None
  1792.         if damageCode in self.__damageInfoFire:
  1793.             extra = self.vehicleTypeDescriptor.extrasDict['fire']
  1794.             self.__fireInVehicle = damageCode != 'FIRE_STOPPED'
  1795.             soundType = 'critical' if self.__fireInVehicle else 'fixed'
  1796.             damagePanel.onFireInVehicle(self.__fireInVehicle)
  1797.         elif damageCode in self.__damageInfoCriticals:
  1798.             deviceName = extra.name[:-len('Health')]
  1799.             if damageCode == 'DEVICE_REPAIRED_TO_CRITICAL':
  1800.                 deviceState = 'repaired'
  1801.                 if 'functionalCanMove' in extra.sounds:
  1802.                     tracksToCheck = ['leftTrack', 'rightTrack']
  1803.                     if deviceName in tracksToCheck:
  1804.                         tracksToCheck.remove(deviceName)
  1805.                     canMove = True
  1806.                     for trackName in tracksToCheck:
  1807.                         if trackName in self.__deviceStates and self.__deviceStates[trackName] == 'destroyed':
  1808.                             canMove = False
  1809.                             break
  1810.  
  1811.                     soundType = 'functionalCanMove' if canMove else 'functional'
  1812.                 else:
  1813.                     soundType = 'functional'
  1814.             else:
  1815.                 deviceState = 'critical'
  1816.                 soundType = 'critical'
  1817.             self.__deviceStates[deviceName] = 'critical'
  1818.         elif damageCode in self.__damageInfoDestructions:
  1819.             deviceName = extra.name[:-len('Health')]
  1820.             deviceState = 'destroyed'
  1821.             soundType = 'destroyed'
  1822.             self.__deviceStates[deviceName] = 'destroyed'
  1823.             vehicle = self.vehicle
  1824.             if vehicle is not None and damageCode not in self.__damageInfoNoNotification:
  1825.                 vehicle.appearance.executeCriticalHitVibrations(vehicle, extra.name)
  1826.         elif damageCode in self.__damageInfoHealings:
  1827.             deviceName = extra.name[:-len('Health')]
  1828.             deviceState = 'normal'
  1829.             soundType = 'fixed'
  1830.             self.__deviceStates.pop(deviceName, None)
  1831.         if deviceState is not None:
  1832.             damagePanel.updateState(deviceName, deviceState)
  1833.             consumablesPanel.updateExpandedEquipmentSlot(deviceName, deviceState)
  1834.         if soundType is not None and damageCode not in self.__damageInfoNoNotification:
  1835.             sound = extra.sounds.get(soundType)
  1836.             if sound is not None:
  1837.                 self.soundNotifications.play(sound)
  1838.         return
  1839.  
  1840.     __damageInfoCriticals = ('DEVICE_CRITICAL',
  1841.      'DEVICE_REPAIRED_TO_CRITICAL',
  1842.      'DEVICE_CRITICAL_AT_SHOT',
  1843.      'DEVICE_CRITICAL_AT_RAMMING',
  1844.      'DEVICE_CRITICAL_AT_FIRE',
  1845.      'DEVICE_CRITICAL_AT_WORLD_COLLISION',
  1846.      'DEVICE_CRITICAL_AT_DROWNING',
  1847.      'ENGINE_CRITICAL_AT_UNLIMITED_RPM')
  1848.     __damageInfoDestructions = ('DEVICE_DESTROYED',
  1849.      'DEVICE_DESTROYED_AT_SHOT',
  1850.      'DEVICE_DESTROYED_AT_RAMMING',
  1851.      'DEVICE_DESTROYED_AT_FIRE',
  1852.      'DEVICE_DESTROYED_AT_WORLD_COLLISION',
  1853.      'DEVICE_DESTROYED_AT_DROWNING',
  1854.      'TANKMAN_HIT',
  1855.      'TANKMAN_HIT_AT_SHOT',
  1856.      'TANKMAN_HIT_AT_WORLD_COLLISION',
  1857.      'TANKMAN_HIT_AT_DROWNING',
  1858.      'ENGINE_DESTROYED_AT_UNLIMITED_RPM')
  1859.     __damageInfoHealings = ('DEVICE_REPAIRED', 'TANKMAN_RESTORED', 'FIRE_STOPPED')
  1860.     __damageInfoFire = ('FIRE',
  1861.      'DEVICE_STARTED_FIRE_AT_SHOT',
  1862.      'DEVICE_STARTED_FIRE_AT_RAMMING',
  1863.      'FIRE_STOPPED')
  1864.     __damageInfoNoNotification = ('DEVICE_CRITICAL',
  1865.      'DEVICE_DESTROYED',
  1866.      'TANKMAN_HIT',
  1867.      'FIRE',
  1868.      'DEVICE_CRITICAL_AT_DROWNING',
  1869.      'DEVICE_DESTROYED_AT_DROWNING',
  1870.      'TANKMAN_HIT_AT_DROWNING')
  1871.  
  1872.     def __setOwnVehicleMatrixCallback(self):
  1873.         self.__setOwnVehicleMatrixTimerID = None
  1874.         if not self.__ownVehicleMProv.target is None:
  1875.             raise AssertionError
  1876.             vehicle = self.vehicle
  1877.             if vehicle is not None and not vehicle.isDestroyed and vehicle.isStarted and vehicle.id == self.playerVehicleID:
  1878.                 self.__ownVehicleMProv.target = isinstance(vehicle.filter, BigWorld.WGVehicleFilter) and vehicle.filter.bodyMatrix
  1879.             else:
  1880.                 self.__ownVehicleMProv.target = vehicle.matrix
  1881.             return
  1882.         else:
  1883.             self.__setOwnVehicleMatrixTimerID = BigWorld.callback(SERVER_TICK_LENGTH, self.__setOwnVehicleMatrixCallback)
  1884.             return
  1885.  
  1886.     def __onArenaVehicleKilled(self, targetID, attackerID, reason):
  1887.         isMyVehicle = targetID == self.playerVehicleID
  1888.         if not self.__isVehicleAlive:
  1889.             isObservedVehicle = targetID == self.inputHandler.ctrl.curVehicleID
  1890.             if isMyVehicle or isObservedVehicle:
  1891.                 if g_windowsManager.battleWindow is not None:
  1892.                     g_windowsManager.battleWindow.hideVehicleTimer('ALL')
  1893.             targetID == self.playerVehicleID and self.inputHandler.setKillerVehicleID(attackerID)
  1894.             return
  1895.         else:
  1896.             if attackerID == self.playerVehicleID:
  1897.                 targetInfo = self.arena.vehicles.get(targetID)
  1898.                 if targetInfo is None:
  1899.                     LOG_CODEPOINT_WARNING()
  1900.                     return
  1901.                 self.__frags.add(targetID)
  1902.             self.battleMessages.onArenaVehicleKilled(targetID, attackerID, reason)
  1903.             return
  1904.  
  1905.     def __onArenaPeriodChange(self, period, periodEndTime, periodLength, periodAdditionalInfo):
  1906.         self.__setIsOnArena(period == ARENA_PERIOD.BATTLE)
  1907.         if period == ARENA_PERIOD.PREBATTLE and period > self.__prevArenaPeriod:
  1908.             LightManager.GameLights.startTicks()
  1909.             if AuxiliaryFx.g_instance is not None:
  1910.                 AuxiliaryFx.g_instance.execEffect('startTicksEffect')
  1911.         if period == ARENA_PERIOD.BATTLE and period > self.__prevArenaPeriod:
  1912.             self.soundNotifications.play('start_battle')
  1913.             LightManager.GameLights.roundStarted()
  1914.             if AuxiliaryFx.g_instance is not None:
  1915.                 AuxiliaryFx.g_instance.execEffect('roundStartedEffect')
  1916.         self.__prevArenaPeriod = period
  1917.         return
  1918.  
  1919.     def __onUserChatCommand(self, commandData):
  1920.         cmd = battle_chat_cmd.makeDecorator(commandData, self.playerVehicleID)
  1921.         if cmd.isIgnored():
  1922.             LOG_DEBUG('Chat command is ignored', cmd)
  1923.             return
  1924.         if cmd.getCommandIndex() == CHAT_COMMANDS.ATTENTIONTOCELL.index():
  1925.             cellIdx = cmd.getSecondTargetID()
  1926.             minimap = g_windowsManager.battleWindow.minimap
  1927.             minimap.markCell(cellIdx, 3.0)
  1928.             cmd.setCmdArgs(minimap.getCellName(cellIdx))
  1929.             g_messengerEvents.channels.onCommandReceived(cmd)
  1930.             return
  1931.         vmManager = g_windowsManager.battleWindow.vMarkersManager
  1932.         if cmd.isPrivate():
  1933.             self.__onSenderPrivateUserChatCmd(cmd, vmManager)
  1934.         else:
  1935.             self.soundNotifications.play(cmd.getSoundEventName())
  1936.             if cmd.isPublic():
  1937.                 self.__onSenderPublicUserChatCmd(cmd, vmManager)
  1938.             else:
  1939.                 self.__onDefaultChat(cmd, vmManager)
  1940.  
  1941.     def __onSenderPrivateUserChatCmd(self, cmd, vmManager):
  1942.         vehicle, senderVehID = self.__findNonPlayerVehicleByNameFromArena(cmd.getSenderID())
  1943.         if cmd.isReceiver() or cmd.isSender():
  1944.             self.soundNotifications.play(cmd.getSoundEventName())
  1945.             g_messengerEvents.channels.onCommandReceived(cmd)
  1946.             if vehicle is None:
  1947.                 vehicle, senderVehicleId = self.__findVehicleByVehId(self.playerVehicleID)
  1948.             vehMarker = cmd.getVehMarker(vehicle=vehicle)
  1949.             self.__showVehicleMarkerForVehId(vmManager, senderVehID, vehMarker)
  1950.             if vehMarker and senderVehID is not None:
  1951.                 g_windowsManager.battleWindow.minimap.showActionMarker(senderVehID, cmd.getVehMarker())
  1952.         return
  1953.  
  1954.     def __onSenderPublicUserChatCmd(self, cmd, vmManager):
  1955.         g_messengerEvents.channels.onCommandReceived(cmd)
  1956.         vehicle, senderVehID = self.__findNonPlayerVehicleByNameFromArena(cmd.getSenderID())
  1957.         if vehicle is None:
  1958.             vehicle, senderVehID = self.__findVehicleByVehId(self.playerVehicleID)
  1959.         showReceiver = cmd.showMarkerForReceiver()
  1960.         recvMarker, senderMarker = cmd.getVehMarkers(vehicle=vehicle)
  1961.         vehID = cmd.getFirstTargetID()
  1962.         minimap = g_windowsManager.battleWindow.minimap
  1963.         if showReceiver:
  1964.             minimap.showActionMarker(vehID, recvMarker)
  1965.             minimap.showActionMarker(senderVehID, senderMarker)
  1966.             self.__showVehicleMarkerForVehId(vmManager, senderVehID, senderMarker)
  1967.             self.__showVehicleMarkerForVehId(vmManager, vehID, recvMarker)
  1968.         else:
  1969.             if senderVehID:
  1970.                 minimap.showActionMarker(senderVehID, recvMarker)
  1971.             self.__showVehicleMarkerForVehId(vmManager, senderVehID, recvMarker)
  1972.         return
  1973.  
  1974.     def __onDefaultChat(self, cmd, vmManager):
  1975.         g_messengerEvents.channels.onCommandReceived(cmd)
  1976.         vMarker = cmd.getVehMarker()
  1977.         if vMarker:
  1978.             vehicle, vehicleID = self.__findNonPlayerVehicleByNameFromArena(cmd.getSenderID())
  1979.             if vehicle is not None:
  1980.                 vmManager.showActionMarker(vehicle.marker, vMarker)
  1981.             if vehicleID:
  1982.                 g_windowsManager.battleWindow.minimap.showActionMarker(vehicleID, vMarker)
  1983.         return
  1984.  
  1985.     def __onSettingsChanged(self, diff):
  1986.         if 'backDraftInvert' in diff:
  1987.             self.invRotationOnBackMovement = diff['backDraftInvert']
  1988.  
  1989.     def __showVehicleMarkerForVehId(self, vmManager, vehId, markerName):
  1990.         if vehId != self.playerVehicleID:
  1991.             vehicle = BigWorld.entity(vehId)
  1992.             if vehicle is not None and vehicle.isStarted:
  1993.                 vmManager.showActionMarker(vehicle.marker, markerName)
  1994.         return
  1995.  
  1996.     def __findNonPlayerVehicleByName(self, accDBID):
  1997.         result = (None, None)
  1998.         vehID = g_battleContext.getVehIDByAccDBID(accDBID)
  1999.         if vehID:
  2000.             vehicle = BigWorld.entities.get(vehID)
  2001.             if vehicle is not None and (not vehicle.isStarted or vehicle.isPlayer):
  2002.                 vehicle = None
  2003.             result = (vehicle, vehID)
  2004.         return result
  2005.  
  2006.     def __findNonPlayerVehicleByNameFromArena(self, accDBID):
  2007.         vehID = g_battleContext.getVehIDByAccDBID(accDBID)
  2008.         return self.__findVehicleByVehId(vehID)
  2009.  
  2010.     def __findVehicleByVehId(self, vehID):
  2011.         result = (None, None)
  2012.         arena = BigWorld.player().arena
  2013.         if vehID:
  2014.             if not g_battleContext.isObserver(vehID):
  2015.                 vehicle = arena.vehicles[vehID]
  2016.                 if vehicle is not None and vehicle['isAlive']:
  2017.                     result = (vehicle, vehID)
  2018.         return result
  2019.  
  2020.     def onChatShortcut(self, cmdName):
  2021.         if not self.__isVehicleAlive:
  2022.             return
  2023.         channelID = chatManager.battleTeamChannelID
  2024.         if channelID != 0:
  2025.             ClientChat.sendChannelChatCommand(self, chatManager.battleTeamChannelID, getattr(CHAT_COMMANDS, cmdName))
  2026.  
  2027.     def onChatShortcutTarget(self, cmdName, targetId):
  2028.         if not self.__isVehicleAlive:
  2029.             return
  2030.         elif targetId is None:
  2031.             return
  2032.         else:
  2033.             channelID = chatManager.battleTeamChannelID
  2034.             if channelID != 0:
  2035.                 ClientChat.sendChannelChatCommand(self, chatManager.battleTeamChannelID, getattr(CHAT_COMMANDS, cmdName), int64Arg=targetId)
  2036.             return
  2037.  
  2038.     def __startWaitingForShot(self):
  2039.         if self.__shotWaitingTimerID is not None:
  2040.             BigWorld.cancelCallback(self.__shotWaitingTimerID)
  2041.             self.__shotWaitingTimerID = None
  2042.         timeout = BigWorld.LatencyInfo().value[3] * 0.5
  2043.         timeout = min(_SHOT_WAITING_MAX_TIMEOUT, timeout)
  2044.         timeout = max(_SHOT_WAITING_MIN_TIMEOUT, timeout)
  2045.         self.__shotWaitingTimerID = BigWorld.callback(timeout, self.__showTimedOutShooting)
  2046.         self.inputHandler.setAimingMode(True, AIMING_MODE.SHOOTING)
  2047.         if not self.inputHandler.getAimingMode(AIMING_MODE.USER_DISABLED):
  2048.             self.gunRotator.targetLastShotPoint = True
  2049.         self.__gunReloadCommandWaitEndTime = BigWorld.time() + 2.0
  2050.         return
  2051.  
  2052.     def __showTimedOutShooting(self):
  2053.         self.__shotWaitingTimerID = None
  2054.         self.inputHandler.setAimingMode(False, AIMING_MODE.SHOOTING)
  2055.         self.gunRotator.targetLastShotPoint = False
  2056.         try:
  2057.             vehicle = BigWorld.entity(self.playerVehicleID)
  2058.             if vehicle is not None and vehicle.isStarted:
  2059.                 gunDescr = vehicle.typeDescriptor.gun
  2060.                 burstCount = gunDescr['burst'][0]
  2061.                 if self.__currShellsIdx is not None:
  2062.                     totalShots, shotsInClip = self.__ammo[self.__currShellsIdx][1:3]
  2063.                     if burstCount > totalShots > 0:
  2064.                         burstCount = totalShots
  2065.                     if gunDescr['clip'][0] > 1 and burstCount > shotsInClip > 0:
  2066.                         burstCount = shotsInClip
  2067.                 vehicle.showShooting(burstCount, True)
  2068.         except Exception:
  2069.             LOG_CURRENT_EXCEPTION()
  2070.  
  2071.         return
  2072.  
  2073.     def __findIndexInAmmo(self, compactDescr):
  2074.         for idx, (value, _, _) in self.__ammo.iteritems():
  2075.             if compactDescr == value:
  2076.                 return idx
  2077.  
  2078.         return None
  2079.  
  2080.     def __findIndexInEquipment(self, compactDescr):
  2081.         for idx, (value, _, _) in self.__equipment.iteritems():
  2082.             if compactDescr == value:
  2083.                 return idx
  2084.  
  2085.         return None
  2086.  
  2087.     def __controlAnotherVehicleWait(self, vehicleID, callback, waitCallsLeft):
  2088.         if vehicleID in BigWorld.entities.keys():
  2089.             BigWorld.callback(1.0, partial(self.__controlAnotherVehicleAfteraction, vehicleID, callback))
  2090.         else:
  2091.             if waitCallsLeft <= 1:
  2092.                 if callback is not None:
  2093.                     callback()
  2094.                 return
  2095.             BigWorld.callback(0.1, partial(self.__controlAnotherVehicleWait, vehicleID, callback, waitCallsLeft - 1))
  2096.         return
  2097.  
  2098.     def __controlAnotherVehicleAfteraction(self, vehicleID, callback):
  2099.         vehicle = BigWorld.entity(vehicleID)
  2100.         if vehicle is None:
  2101.             return
  2102.         else:
  2103.             vehicle.isPlayer = True
  2104.             self.__isVehicleAlive = True
  2105.             self.playerVehicleID = vehicleID
  2106.             self.vehicleTypeDescriptor = vehicle.typeDescriptor
  2107.             self.base.controlAnotherVehicle(vehicleID, 2)
  2108.             self.gunRotator.clientMode = False
  2109.             self.gunRotator.start()
  2110.             self.base.setDevelopmentFeature('server_marker', True)
  2111.             self.base.setDevelopmentFeature('heal', 0)
  2112.             self.base.setDevelopmentFeature('stop_bot', 0)
  2113.             self.inputHandler.setKillerVehicleID(None)
  2114.             self.inputHandler.onControlModeChanged('arcade')
  2115.             if callback is not None:
  2116.                 callback()
  2117.             return
  2118.  
  2119.     def __dumpVehicleState(self):
  2120.         matrix = Math.Matrix(self.getOwnVehicleMatrix())
  2121.         LOG_NOTE('Arena type: ', self.arena.arenaType.geometryName)
  2122.         LOG_NOTE('Vehicle position: ', matrix.translation)
  2123.         LOG_NOTE('Vehicle direction (y, p, r): ', (matrix.yaw, matrix.pitch, matrix.roll))
  2124.         LOG_NOTE('Vehicle speeds: ', self.getOwnVehicleSpeeds())
  2125.         if self.vehicleTypeDescriptor is not None:
  2126.             LOG_NOTE('Vehicle type: ', self.vehicleTypeDescriptor.type.name)
  2127.             LOG_NOTE('Vehicle turret: ', self.vehicleTypeDescriptor.turret['name'])
  2128.             LOG_NOTE('Vehicle gun: ', self.vehicleTypeDescriptor.gun['name'])
  2129.         LOG_NOTE('Shot point: ', self.gunRotator._VehicleGunRotator__lastShotPoint)
  2130.         return
  2131.  
  2132.     def __reportLag(self):
  2133.         msg = 'LAG REPORT\n'
  2134.         import time
  2135.         t = time.gmtime()
  2136.         msg += '\ttime: %d/%0d/%0d %0d:%0d:%0d UTC\n' % t[:6]
  2137.         msg += '\tAvatar.id: %d\n' % self.id
  2138.         ping = BigWorld.LatencyInfo().value[3] - 0.5 * constants.SERVER_TICK_LENGTH
  2139.         ping = max(1, ping * 1000)
  2140.         msg += '\tping: %d\n' % ping
  2141.         msg += '\tFPS: %d\n' % BigWorld.getFPS()[1]
  2142.         numVehs = 0
  2143.         numAreaDestrs = 0
  2144.         for e in BigWorld.entities.values():
  2145.             if type(e) is Vehicle.Vehicle:
  2146.                 numVehs += 1
  2147.             elif type(e) == AreaDestructibles.AreaDestructibles:
  2148.                 numAreaDestrs += 1
  2149.  
  2150.         msg += '\tnum Vehicle: %d\n\tnum AreaDestructibles: %d\n' % (numVehs, numAreaDestrs)
  2151.         msg += '\tarena: %s\n' % self.arena.arenaType.geometryName
  2152.         msg += '\tposition: ' + str(self.position)
  2153.         LOG_NOTE(msg)
  2154.         self.base.setDevelopmentFeature('log_lag', True)
  2155.  
  2156.     def __updateCruiseControlPanel(self):
  2157.         damagePanel = g_windowsManager.battleWindow.damagePanel
  2158.         if self.__stopUntilFire or not self.__isVehicleAlive:
  2159.             damagePanel.setCruiseMode(_CRUISE_CONTROL_MODE.NONE)
  2160.         else:
  2161.             damagePanel.setCruiseMode(self.__cruiseControlMode)
  2162.  
  2163.     def __applyTimeAndWeatherSettings(self, overridePresetID = None):
  2164.         presets = self.arena.arenaType.weatherPresets
  2165.         weather = Weather.weather()
  2166.         if len(presets) == 0 or presets[0].get('name') is None:
  2167.             weather.summon('Clear', immediate=True)
  2168.             return
  2169.         else:
  2170.             try:
  2171.                 presetID = overridePresetID if overridePresetID is not None else self.weatherPresetID
  2172.                 preset = presets[presetID]
  2173.                 weather.summon(preset['name'], immediate=True)
  2174.                 hour = preset.get('hour')
  2175.                 if hour is not None:
  2176.                     BigWorld.wg_setHourOfDay(float(hour))
  2177.                 fogDensity = preset.get('fogDensity')
  2178.                 if fogDensity is None:
  2179.                     fogDensity = weather.getFog()[3]
  2180.                 else:
  2181.                     fogDensity = float(fogDensity)
  2182.                 fogColor = preset.get('fogColor')
  2183.                 if fogColor is None:
  2184.                     fogColor = weather.getFog()
  2185.                 else:
  2186.                     fogColor = fogColor.split()
  2187.                     fogColor = (float(fogColor[0]), float(fogColor[1]), float(fogColor[2]))
  2188.                 weather.fog((fogColor[0],
  2189.                  fogColor[1],
  2190.                  fogColor[2],
  2191.                  fogDensity))
  2192.                 rain = preset.get('rain')
  2193.                 if rain is not None:
  2194.                     weather.rain(rain)
  2195.                 ambientLight = preset.get('ambientLight')
  2196.                 if ambientLight is not None:
  2197.                     ambientLight = ambientLight.split()
  2198.                     if len(ambientLight) == 1:
  2199.                         weather.ambient(Math.Vector4(float(ambientLight[0])))
  2200.                     elif len(ambientLight) >= 3:
  2201.                         weather.ambient(Math.Vector4(float(ambientLight[0]), float(ambientLight[1]), float(ambientLight[2]), 1.0))
  2202.                 sunLight = preset.get('sunLight')
  2203.                 if sunLight is not None:
  2204.                     sunLight = sunLight.split()
  2205.                     if len(sunLight) == 1:
  2206.                         weather.sun(Math.Vector4(float(sunLight[0])))
  2207.                     elif len(sunLight) >= 3:
  2208.                         weather.sun(Math.Vector4(float(sunLight[0]), float(sunLight[1]), float(sunLight[2]), 1.0))
  2209.             except Exception:
  2210.                 LOG_CURRENT_EXCEPTION()
  2211.                 LOG_DEBUG("Weather system's ID was:", self.weatherPresetID)
  2212.  
  2213.             return
  2214.  
  2215.     def __processVehicleAmmo(self, compactDescr, quantity, quantityInClip, _):
  2216.         if g_battleContext.isObserver(self.playerVehicleID):
  2217.             return
  2218.         else:
  2219.             consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  2220.             aim = self.inputHandler.aim
  2221.             idx = self.__findIndexInAmmo(compactDescr)
  2222.             if idx is not None:
  2223.                 prevAmmo = self.__ammo.get(idx)
  2224.                 self.__ammo[idx] = (compactDescr, quantity, quantityInClip)
  2225.                 consumablesPanel.setShellQuantityInSlot(idx, quantity, quantityInClip)
  2226.                 if idx == self.__currShellsIdx:
  2227.                     isCassetteReload = (False if prevAmmo is None else quantityInClip > 0 and prevAmmo[2] == 0) and quantity == prevAmmo[1]
  2228.                     if not isCassetteReload:
  2229.                         self.getOwnVehicleShotDispersionAngle(self.gunRotator.turretRotationSpeed, 1)
  2230.                     if aim is not None:
  2231.                         aim.setAmmoStock(quantity, quantityInClip, clipReloaded=isCassetteReload)
  2232.                 return
  2233.             idx = self.__nextCSlotIdx
  2234.             self.__nextCSlotIdx += 1
  2235.             self.__ammo[idx] = (compactDescr, quantity, quantityInClip)
  2236.             shellDescr = vehicles.getDictDescr(compactDescr)
  2237.             for _, shotDescr in enumerate(self.vehicleTypeDescriptor.gun['shots']):
  2238.                 if shotDescr['shell']['id'] == shellDescr['id']:
  2239.                     break
  2240.  
  2241.             clipCapacity, _ = self.vehicleTypeDescriptor.gun['clip']
  2242.             burst, _ = self.vehicleTypeDescriptor.gun['burst']
  2243.             if aim is not None:
  2244.                 aim.setClipParams(clipCapacity, burst)
  2245.             consumablesPanel.addShellSlot(idx, quantity, quantityInClip, clipCapacity, shellDescr, shotDescr['piercingPower'])
  2246.             return
  2247.  
  2248.     def __processVehicleEquipments(self, compactDescr, quantity, _, timeRemaining):
  2249.         consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  2250.         idx = self.__findIndexInEquipment(compactDescr)
  2251.         if idx is not None:
  2252.             self.__equipment[idx] = (compactDescr, quantity, timeRemaining)
  2253.             if not timeRemaining and quantity > 0 and idx in self.__equipmentFlags:
  2254.                 self.__equipmentFlags[idx] = 0
  2255.             consumablesPanel.setItemQuantityInSlot(idx, quantity)
  2256.             consumablesPanel.setCoolDownTime(idx, timeRemaining)
  2257.             return
  2258.         else:
  2259.             self.__nextCSlotIdx = consumablesPanel.checkEquipmentSlotIdx(self.__nextCSlotIdx)
  2260.             idx = self.__nextCSlotIdx
  2261.             self.__nextCSlotIdx += 1
  2262.             self.__equipment[idx] = (compactDescr, quantity, timeRemaining)
  2263.             eDescr = vehicles.getDictDescr(compactDescr)
  2264.             consumablesPanel.addEquipmentSlot(idx, quantity, eDescr)
  2265.             if timeRemaining:
  2266.                 consumablesPanel.setCoolDownTime(idx, timeRemaining)
  2267.                 if eDescr.tags & frozenset(('trigger', 'extinguisher')):
  2268.                     self.__equipmentFlags[idx] = 1
  2269.             return
  2270.  
  2271.     def __processEmptyVehicleEquipment(self):
  2272.         consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  2273.         self.__nextCSlotIdx = consumablesPanel.checkEquipmentSlotIdx(self.__nextCSlotIdx)
  2274.         idx = self.__nextCSlotIdx
  2275.         self.__nextCSlotIdx += 1
  2276.         self.__equipment[idx] = (0, 0, 0)
  2277.         consumablesPanel.addEmptyEquipmentSlot(idx)
  2278.  
  2279.     def __processVehicleOptionalDevices(self, deviceID, isOn):
  2280.         consumablesPanel = g_windowsManager.battleWindow.consumablesPanel
  2281.         idx = self.__optionalDevices.get(deviceID)
  2282.         if idx is None:
  2283.             idx = self.__nextCSlotIdx
  2284.             self.__nextCSlotIdx += 1
  2285.             self.__optionalDevices[deviceID] = idx
  2286.             consumablesPanel.addOptionalDevice(idx, vehicles.g_cache.optionalDevices()[deviceID])
  2287.         consumablesPanel.setOptionalDeviceState(idx, isOn)
  2288.         return
  2289.  
  2290.     def __isOwnBarrelUnderWater(self):
  2291.         if self.vehicle is None:
  2292.             return
  2293.         else:
  2294.             turretYaw = Math.Matrix(self.gunRotator.turretMatrix).yaw
  2295.             gunPitch = Math.Matrix(self.gunRotator.gunMatrix).pitch
  2296.             lp = computeBarrelLocalPoint(self.vehicleTypeDescriptor, turretYaw, gunPitch)
  2297.             wp = Math.Matrix(self.vehicle.matrix).applyPoint(lp)
  2298.             up = Math.Vector3((0.0, 0.1, 0.0))
  2299.             return BigWorld.wg_collideWater(wp, wp + up, False) != -1.0
  2300.  
  2301.     def __fireNonFatalDamageTrigger(self, targetId):
  2302.         vehicle = BigWorld.entities.get(targetId)
  2303.         if vehicle is not None:
  2304.             if not vehicle.isPlayer and vehicle.isAlive:
  2305.                 TriggersManager.g_manager.fireTrigger(TRIGGER_TYPE.PLAYER_SHOT_MADE_NONFATAL_DAMAGE, targetId=targetId)
  2306.         return
  2307.  
  2308.     def __getRequestID(self):
  2309.         self.__requestID += 1
  2310.         if self.__requestID >= AccountCommands.REQUEST_ID_UNRESERVED_MAX:
  2311.             self.__requestID = AccountCommands.REQUEST_ID_UNRESERVED_MIN
  2312.         return self.__requestID
  2313.  
  2314.     def __doCmd(self, doCmdMethod, cmd, callback, *args):
  2315.         if Account.g_accountRepository is None:
  2316.             return
  2317.         else:
  2318.             requestID = self.__getRequestID()
  2319.             if requestID is None:
  2320.                 return
  2321.             if callback is not None:
  2322.                 self.__onCmdResponse[requestID] = callback
  2323.             getattr(self.base, doCmdMethod)(requestID, cmd, *args)
  2324.             return
  2325.  
  2326.     def _doCmdStr(self, cmd, str, callback):
  2327.         self.__doCmd('doCmdStr', cmd, callback, str)
  2328.  
  2329.     def _doCmdInt3(self, cmd, int1, int2, int3, callback):
  2330.         self.__doCmd('doCmdInt3', cmd, callback, int1, int2, int3)
  2331.  
  2332.     def _doCmdInt4(self, cmd, int1, int2, int3, int4, callback):
  2333.         self.__doCmd('doCmdInt4', cmd, callback, int1, int2, int3, int4)
  2334.  
  2335.     def _doCmdInt2Str(self, cmd, int1, int2, str, callback):
  2336.         self.__doCmd('doCmdInt2Str', cmd, callback, int1, int2, str)
  2337.  
  2338.     def _doCmdIntArr(self, cmd, arr, callback):
  2339.         self.__doCmd('doCmdIntArr', cmd, callback, arr)
  2340.  
  2341.     def _doCmdIntArrStrArr(self, cmd, intArr, strArr, callback):
  2342.         self.__doCmd('doCmdIntArrStrArr', cmd, callback, intArr, strArr)
  2343.  
  2344.     def update(self, pickledDiff):
  2345.         self._update(cPickle.loads(pickledDiff))
  2346.  
  2347.     def _update(self, diff):
  2348.         LOG_DEBUG('_update', diff)
  2349.         if not BattleReplay.isPlaying():
  2350.             self.intUserSettings.synchronize(False, diff)
  2351.             g_playerEvents.onClientUpdated(diff)
  2352.  
  2353.     def isSynchronized(self):
  2354.         if BattleReplay.isPlaying():
  2355.             return True
  2356.         else:
  2357.             return self.intUserSettings.isSynchronized()
  2358.  
  2359.  
  2360. def preload(alist):
  2361.     ds = ResMgr.openSection('precache.xml')
  2362.     if ds is not None:
  2363.         for sec in ds.values():
  2364.             alist.append(sec.asString)
  2365.  
  2366.     return
  2367.  
  2368.  
  2369. def _boundingBoxAsVector4(bb):
  2370.     return Math.Vector4(bb[0][0], bb[0][1], bb[1][0], bb[1][1])
  2371.  
  2372.  
  2373. def _getBestShotResultSound(currBest, newSoundName, otherData):
  2374.     newSoundPriority = _shotResultSoundPriorities[newSoundName]
  2375.     if currBest is None:
  2376.         return (newSoundName, otherData, newSoundPriority)
  2377.     elif newSoundPriority > currBest[2]:
  2378.         return (newSoundName, otherData, newSoundPriority)
  2379.     else:
  2380.         return currBest
  2381.  
  2382.  
  2383. _shotResultSoundPriorities = {'enemy_hp_damaged_by_projectile_and_gun_damaged_by_player': 12,
  2384.  'enemy_hp_damaged_by_projectile_and_chassis_damaged_by_player': 11,
  2385.  'enemy_hp_damaged_by_projectile_by_player': 10,
  2386.  'enemy_hp_damaged_by_explosion_at_direct_hit_by_player': 9,
  2387.  'enemy_hp_damaged_by_near_explosion_by_player': 8,
  2388.  'enemy_no_hp_damage_at_attempt_and_gun_damaged_by_player': 7,
  2389.  'enemy_no_hp_damage_at_no_attempt_and_gun_damaged_by_player': 6,
  2390.  'enemy_no_hp_damage_at_attempt_and_chassis_damaged_by_player': 5,
  2391.  'enemy_no_hp_damage_at_no_attempt_and_chassis_damaged_by_player': 4,
  2392.  'enemy_no_piercing_by_player': 3,
  2393.  'enemy_no_hp_damage_at_attempt_by_player': 3,
  2394.  'enemy_no_hp_damage_at_no_attempt_by_player': 2,
  2395.  'enemy_no_hp_damage_by_near_explosion_by_player': 1,
  2396.  'enemy_ricochet_by_player': 0}
  2397. Avatar = PlayerAvatar
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement