NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

navigation.py (27384B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\navigation.py
      2 from itertools import chain
      3 import blue
      4 import evecamera
      5 import evetypes
      6 import geo2
      7 import uthread
      8 from carbonui import uiconst
      9 from carbonui.control.layer import LayerCore
     10 from carbonui.primitives.base import ReverseScaleDpi
     11 from carbonui.primitives.bracket import Bracket
     12 from carbonui.primitives.container import Container
     13 from carbonui.primitives.line import Line
     14 from carbonui.uianimations import animations
     15 from carbonui.uicore import uicore
     16 from eve.client.script.parklife import states
     17 from eve.client.script.parklife.tacticalConst import is_interactable_entity
     18 from eve.client.script.ui.camera.cameraUtil import GetCameraMaxLookAtRange, GetBallPosition
     19 from eve.client.script.ui.camera.debugCameraController import DebugCameraController
     20 from eve.client.script.ui.camera.enterSpaceCameraController import EnterSpaceCameraController
     21 from eve.client.script.ui.camera.explosionCameraController import ExplosionCameraController
     22 from eve.client.script.ui.camera.shipOrbitAbyssalSpaceCameraController import ShipOrbitCameraAbyssalSpaceController
     23 from eve.client.script.ui.camera.shipOrbitCameraController import ShipOrbitCameraController
     24 from eve.client.script.ui.camera.shipOrbitCameraRestrictedController import ShipOrbitCameraRestrictedController
     25 from eve.client.script.ui.camera.shipOrbitHazardCameraController import ShipOrbitCameraHazardSpaceController
     26 from eve.client.script.ui.camera.shipPOVCameraController import ShipPOVCameraController
     27 from eve.client.script.ui.camera.tacticalCameraController import TacticalCameraController
     28 from eve.client.script.ui.camera.undockCameraController import UndockCameraController
     29 from eve.client.script.ui.control.marqueeCont import MarqueeCont
     30 from eve.client.script.ui.inflight import positionalControl
     31 from eve.client.script.ui.inflight.bracketsAndTargets.bracketVarious import GetOverlaps
     32 from eve.client.script.ui.inflight.bracketsAndTargets.inSpaceBracketTooltip import PersistentInSpaceBracketTooltip
     33 from eve.client.script.ui.inflight.drone import DropDronesInSpace
     34 from eve.client.script.ui.inflight.drones import dronesUtil, dronesDragData, droneSignals
     35 from eve.client.script.ui.inflight.drones.dronesDragData import AllDronesInBayDragData
     36 from eve.client.script.ui.services.menuSvcExtras import droneFunctions
     37 from eve.client.script.ui.shared.infoPanels.listSurroundingsBtn import ListSurroundingsBtn
     38 from eve.client.script.ui.shared.radialMenu.spaceRadialMenuFunctions import AreOtherMouseBtnsDown, GetSingleMouseBtnBroadcastRadialMenu
     39 from eve.client.script.ui.tooltips.tooltipHandler import TOOLTIP_SETTINGS_BRACKET, TOOLTIP_DELAY_BRACKET
     40 from eve.common.lib import appConst
     41 from eveservices.menu import GetMenuService
     42 from menu import MenuLabel
     43 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     44 from sensorsuite.overlay.brackets import SensorSuiteBracket
     45 from spacecomponents.client.components import deploy
     46 from spacecomponents.common.helper import HasDeployComponent
     47 multiTargetCmds = ('CmdLockTargetItem', 'CmdToggleTargetItem', 'CmdSelectTargetItem', 'CmdUnlockTargetItem', 'CmdShowItemInfo')
     48 nearestTargetCmds = ('CmdToggleLookAtItem', 'CmdToggleCameraTracking', 'CmdApproachItem', 'CmdAlignToItem', 'CmdOrbitItem', 'CmdKeepItemAtRange')
     49 
     50 class InflightLayer(LayerCore):
     51     __guid__ = 'uicls.InflightLayer'
     52     __notifyevents__ = ['OnActiveCameraChanged', 'OnRadialMenuExpanded']
     53 
     54     def ApplyAttributes(self, attributes):
     55         LayerCore.ApplyAttributes(self, attributes)
     56         self.locked = 0
     57         self.sr.tcursor = None
     58         self.hoverbracket = None
     59         self.sr.spacemenu = None
     60         self.marqueeCont = None
     61         self.locks = {}
     62         self.mouseDown = False
     63         self._structureDeploymentSvc = None
     64         self.lastCamera = None
     65         self.cameraController = None
     66         self.positionalControl = positionalControl.PositionalControl()
     67         self.sr.tcursor = Container(name='targetingcursor', parent=self, align=uiconst.ABSOLUTE, width=1, height=1, state=uiconst.UI_HIDDEN)
     68         Line(parent=self.sr.tcursor, align=uiconst.RELATIVE, left=10, width=3000, height=1)
     69         Line(parent=self.sr.tcursor, align=uiconst.TOPRIGHT, left=10, width=3000, height=1)
     70         Line(parent=self.sr.tcursor, align=uiconst.RELATIVE, top=10, width=1, height=3000)
     71         Line(parent=self.sr.tcursor, align=uiconst.BOTTOMLEFT, top=10, width=1, height=3000)
     72 
     73     @property
     74     def structureDeploymentSvc(self):
     75         if not self._structureDeploymentSvc:
     76             self._structureDeploymentSvc = sm.GetService('structureDeployment')
     77         return self._structureDeploymentSvc
     78 
     79     def OnOpenView(self, **kwargs):
     80         camera = sm.GetService('sceneManager').GetActiveCamera()
     81         if camera:
     82             self.OnActiveCameraChanged(camera.cameraID)
     83 
     84     def OnCloseView(self):
     85         if self.cameraController:
     86             self.cameraController.Deactivate()
     87 
     88     def OnActiveCameraChanged(self, cameraID):
     89         if self.cameraController:
     90             self.cameraController.Deactivate()
     91         if cameraID == evecamera.CAM_SHIPORBIT:
     92             self.cameraController = ShipOrbitCameraController()
     93         elif cameraID == evecamera.CAM_SHIPORBIT_ABYSSAL_SPACE:
     94             self.cameraController = ShipOrbitCameraAbyssalSpaceController()
     95         elif cameraID == evecamera.CAM_SHIPORBIT_HAZARD:
     96             self.cameraController = ShipOrbitCameraHazardSpaceController()
     97         elif cameraID == evecamera.CAM_SHIPORBIT_RESTRICTED:
     98             self.cameraController = ShipOrbitCameraRestrictedController()
     99         elif cameraID == evecamera.CAM_TACTICAL:
    100             self.cameraController = TacticalCameraController()
    101         elif cameraID == evecamera.CAM_SHIPPOV:
    102             self.cameraController = ShipPOVCameraController()
    103         elif cameraID == evecamera.CAM_DEBUG:
    104             self.cameraController = DebugCameraController()
    105         elif cameraID == evecamera.CAM_UNDOCK:
    106             self.cameraController = UndockCameraController()
    107         elif cameraID == evecamera.CAM_ENTERSPACE:
    108             self.cameraController = EnterSpaceCameraController()
    109         elif cameraID == evecamera.CAM_EXPLOSION:
    110             self.cameraController = ExplosionCameraController()
    111         else:
    112             self.cameraController = None
    113         if self.cameraController:
    114             self.cameraController.Activate()
    115         self.positionalControl.SetCameraController(self.cameraController)
    116         if self.lastCamera == evecamera.CAM_SHIPPOV:
    117             self.UpdatePlayerImpactDamages()
    118         self.lastCamera = cameraID
    119 
    120     def UpdatePlayerImpactDamages(self):
    121         if session.shipid is not None:
    122             michelle = sm.GetService('michelle')
    123             ball = michelle.GetBall(session.shipid)
    124 
    125             def Delay():
    126                 blue.synchro.SleepSim(50)
    127                 if ball is not None and hasattr(ball, 'model') and ball.model is not None:
    128                     ball._UpdateImpacts()
    129 
    130             uthread.new(Delay)
    131 
    132     def GetSpaceMenu(self, solarsystemID):
    133         if self.sr.spacemenu:
    134             if self.sr.spacemenu.solarsystemID == solarsystemID:
    135                 return self.sr.spacemenu
    136             m = self.sr.spacemenu
    137             self.sr.spacemenu = None
    138             m.Close()
    139         listbtn = ListSurroundingsBtn(name='gimp', parent=self, state=uiconst.UI_HIDDEN, pos=(0, 0, 0, 0), useDynamicMapItems=True, isInSpaceMenu=True)
    140         listbtn.SetSolarsystemID(solarsystemID)
    141         listbtn.sr.groupByType = 1
    142         listbtn.filterCurrent = 1
    143         self.sr.spacemenu = listbtn
    144         return self.sr.spacemenu
    145 
    146     def _OnClose(self):
    147         Container._OnClose(self)
    148         if sm.GetService('ui').IsUiVisible():
    149             uicore.layer.main.state = uiconst.UI_PICKCHILDREN
    150 
    151     def PrepareTooltipLoad(self, bracket):
    152         if uicore.uilib.leftbtn or uicore.uilib.rightbtn:
    153             return None
    154         currentPos = (uicore.uilib.x, uicore.uilib.y)
    155         lastPos = getattr(self, 'lastLoadPos', (None, None))
    156         if lastPos == currentPos:
    157             return None
    158         self.lastLoadPos = currentPos
    159         self.tooltipBracket = bracket
    160         currentTooltip = uicore.uilib.tooltipHandler.GetPersistentTooltipByOwner(self)
    161         if currentTooltip and not (currentTooltip.destroyed or currentTooltip.beingDestroyed):
    162             if currentTooltip.IsOverlapBracket(bracket):
    163                 return None
    164             currentTooltip.Close()
    165         isFloating = bracket.IsFloating()
    166         overlaps, boundingBox = GetOverlaps(bracket, useMousePosition=isinstance(bracket, SensorSuiteBracket), customBracketParent=uicore.layer.bracket)
    167         overlapSites = sm.GetService('sensorSuite').GetOverlappingSites()
    168         if isFloating and len(overlaps) + len(overlapSites) == 1:
    169             return None
    170         overlapSites.sort(key=lambda x: x.data.GetSortKey())
    171         self.tooltipPositionRect = bracket.GetAbsolute()
    172         ro = bracket.renderObject
    173         self.bracketPosition = (ro.displayX,
    174          ro.displayY,
    175          ro.displayWidth,
    176          ro.displayHeight)
    177         for bracket in chain(overlaps, overlapSites):
    178             bracket.opacity = 2.0
    179 
    180         for layer in (uicore.layer.inflight, uicore.layer.sensorSuite):
    181             animations.FadeTo(layer, startVal=layer.opacity, endVal=0.5, duration=0.5)
    182 
    183         uicore.uilib.tooltipHandler.LoadPersistentTooltip(self, loadArguments=(bracket,
    184          overlaps,
    185          boundingBox,
    186          overlapSites), customTooltipClass=PersistentInSpaceBracketTooltip)
    187 
    188     def OnRadialMenuExpanded(self, *args):
    189         self.StopMarqueeSelection()
    190 
    191     def GetTooltipDelay(self):
    192         return settings.user.ui.Get(TOOLTIP_SETTINGS_BRACKET, TOOLTIP_DELAY_BRACKET)
    193 
    194     def GetTooltipPosition(self, *args, **kwds):
    195         return self.tooltipPositionRect
    196 
    197     def GetTooltipPointer(self):
    198         tooltipPanel = uicore.uilib.tooltipHandler.GetPersistentTooltipByOwner(self)
    199         if not tooltipPanel:
    200             return
    201         x, y, width, height = self.bracketPosition
    202         bracketLayerWidth = uicore.layer.bracket.displayWidth
    203         bracketLayerHeight = uicore.layer.bracket.displayHeight
    204         width = uicore.ReverseScaleDpi(width)
    205         height = uicore.ReverseScaleDpi(height)
    206         overlapAmount = len(tooltipPanel.overlaps)
    207         isCompact = tooltipPanel.isCompact
    208         if x <= 0:
    209             if isCompact and overlapAmount == 1:
    210                 return uiconst.POINT_LEFT_2
    211             else:
    212                 return uiconst.POINT_LEFT_3
    213         elif x + width >= bracketLayerWidth:
    214             if isCompact and overlapAmount == 1:
    215                 return uiconst.POINT_RIGHT_2
    216             else:
    217                 return uiconst.POINT_RIGHT_3
    218         elif y <= 0:
    219             if isCompact:
    220                 return uiconst.POINT_TOP_2
    221             else:
    222                 return uiconst.POINT_TOP_1
    223         elif y + height >= bracketLayerHeight:
    224             if isCompact:
    225                 return uiconst.POINT_BOTTOM_2
    226             else:
    227                 return uiconst.POINT_BOTTOM_1
    228         if isCompact:
    229             return uiconst.POINT_BOTTOM_2
    230         else:
    231             return uiconst.POINT_BOTTOM_1
    232 
    233     def GetTooltipPositionFallbacks(self):
    234         tooltipPanel = uicore.uilib.tooltipHandler.GetPersistentTooltipByOwner(self)
    235         if tooltipPanel:
    236             isCompact = tooltipPanel.isCompact
    237         else:
    238             isCompact = False
    239         if isCompact:
    240             return [uiconst.POINT_TOP_2,
    241              uiconst.POINT_TOPLEFT,
    242              uiconst.POINT_TOPRIGHT,
    243              uiconst.POINT_BOTTOMLEFT,
    244              uiconst.POINT_BOTTOMRIGHT]
    245         else:
    246             return [uiconst.POINT_TOP_1,
    247              uiconst.POINT_TOPLEFT,
    248              uiconst.POINT_TOPRIGHT,
    249              uiconst.POINT_BOTTOMLEFT,
    250              uiconst.POINT_BOTTOMRIGHT]
    251 
    252     def ShowTargetingCursor(self):
    253         self.sr.tcursor.left = uicore.uilib.x - 1
    254         self.sr.tcursor.top = uicore.uilib.y
    255         self.sr.tcursor.state = uiconst.UI_DISABLED
    256 
    257     def HideTargetingCursor(self):
    258         self.sr.tcursor.state = uiconst.UI_HIDDEN
    259 
    260     def GetMenu(self, itemID = None):
    261         if self.positionalControl.IsActive():
    262             self.positionalControl.AbortCommand()
    263             return
    264         if self.locked or sm.GetService('target').IsSomeModuleWaitingForTargetClick():
    265             return []
    266         m = []
    267         if not itemID and self.cameraController:
    268             picktype, pickobject = self.cameraController.GetPick()
    269             if pickobject and hasattr(pickobject, 'translationCurve') and hasattr(pickobject.translationCurve, 'id'):
    270                 itemID = pickobject.translationCurve.id
    271             if pickobject:
    272                 if sm.GetService('posAnchor').IsActive():
    273                     if pickobject.name[:6].lower() == 'cursor':
    274                         m.append((MenuLabel('UI/Inflight/POS/AnchorHere'), sm.GetService('posAnchor').SubmitAnchorPosSelect, ()))
    275                         m.append(None)
    276                         m.append((MenuLabel('UI/Inflight/POS/CancelAnchoring'), sm.GetService('posAnchor').CancelAchorPosSelect, ()))
    277                         return m
    278         if not itemID:
    279             locationShortcutActive = sm.GetService('cmd').IsCombatCommandLoaded('CmdGetLocationMenuForNavigation')
    280             if locationShortcutActive:
    281                 m = sm.GetService('bookmarkSvc').GetBookmarkMenuForNavigation(includeTopLevel=False)
    282                 if not m:
    283                     prompt_player_fsd_dialog('NoLocationsFoundForMenu')
    284                 return m
    285             mm = self.GetSpaceMenu(session.solarsystemid2).GetMenu()
    286             m.extend([(MenuLabel('UI/Inflight/ResetCamera'), sm.GetService('sceneManager').GetActiveCamera().ResetCamera, ()),
    287              None,
    288              (MenuLabel('UI/Inflight/ShowSystemInMapBrowser'), GetMenuService().ShowInMapBrowser, (session.solarsystemid2,)),
    289              None])
    290             return m + mm
    291         bp = sm.GetService('michelle').GetBallpark()
    292         if not bp:
    293             return m
    294         slimItem = bp.GetInvItem(itemID)
    295         if slimItem is None:
    296             return m
    297         pickid = slimItem.itemID
    298         groupID = slimItem.groupID
    299         categoryID = slimItem.categoryID
    300         if session.shipid is None:
    301             return m
    302         m += GetMenuService().CelestialMenu(slimItem.itemID, slimItem=slimItem)
    303         return m
    304 
    305     def ShowRadialMenuIndicator(self, slimItem, *args):
    306         if not slimItem:
    307             return
    308         bracket = sm.GetService('bracket').GetBracket(slimItem.itemID)
    309         if bracket is None:
    310             return
    311         bracket.ShowRadialMenuIndicator()
    312 
    313     def HideRadialMenuIndicator(self, slimItem, *args):
    314         if slimItem is None:
    315             return
    316         bracket = sm.GetService('bracket').GetBracket(slimItem.itemID)
    317         if bracket is None:
    318             return
    319         bracket.HideRadialMenuIndicator()
    320 
    321     def OnDropData(self, dragObj, dragData):
    322         inBayDroneIDs = dronesDragData.GetInBayDroneIDs(dragData)
    323         if inBayDroneIDs:
    324             droneFunctions.LaunchDrones(inBayDroneIDs)
    325             droneSignals.on_drones_dropped_in_space()
    326         elif dragData and hasattr(dragData[0], '__guid__') and dragData[0].__guid__ in ('xtriui.InvItem', 'listentry.InvItem'):
    327             deployItems = []
    328             for node in dragData:
    329                 if node.item.ownerID != session.charid:
    330                     return
    331                 if node.item.locationID != session.shipid:
    332                     return
    333                 if node.item.categoryID == appConst.categoryStructure:
    334                     self.structureDeploymentSvc.Deploy(node.item)
    335                     return
    336                 if HasDeployComponent(node.item.typeID):
    337                     if not session.structureid:
    338                         deployItems.append(node.item)
    339 
    340             if deployItems:
    341                 deploy.DeployAction(deployItems)
    342 
    343     def OnDragEnter(self, dragSource, dragData):
    344         if dronesDragData.HasInBayDroneIDs(dragData):
    345             droneSignals.on_in_space_entry_drag_enter()
    346 
    347     def OnMouseDown(self, *args):
    348         self.mouseDown = True
    349         if sm.GetService('ui').IsUiVisible():
    350             uicore.layer.main.state = uiconst.UI_DISABLED
    351         if not self.cameraController:
    352             return
    353         pickObject = self.cameraController.OnMouseDown(*args)
    354         if self.positionalControl.IsActive():
    355             return
    356         self.TryExpandActionMenu(pickObject)
    357         uicore.uilib.ClipCursor(0, 0, uicore.desktop.width, uicore.desktop.height)
    358         if pickObject and pickObject.name == 'StructurePlacement' and self.structureDeploymentSvc.IsOnPositionStep():
    359             self.structureDeploymentSvc.StartMovingStructure()
    360         elif uicore.uilib.leftbtn and not uicore.uilib.rightbtn and uicore.cmd.IsSomeCombatCommandLoaded():
    361             self.StartMarqueeSelection()
    362         elif uicore.uilib.rightbtn:
    363             self.StopMarqueeSelection()
    364 
    365     def StartMarqueeSelection(self):
    366         self.StopMarqueeSelection()
    367         self.marqueeCont = MarqueeCont(parent=self)
    368 
    369     def OnMouseUp(self, btnID):
    370         if sm.GetService('ui').IsUiVisible():
    371             uicore.layer.main.state = uiconst.UI_PICKCHILDREN
    372         if not uicore.uilib.leftbtn and not uicore.uilib.rightbtn:
    373             self.mouseDown = False
    374             uicore.uilib.UnclipCursor()
    375             if uicore.uilib.GetCapture() == self:
    376                 uicore.uilib.ReleaseCapture()
    377         elif uicore.uilib.leftbtn or uicore.uilib.rightbtn:
    378             uicore.uilib.SetCapture(self)
    379         if self._IsMovingStructure():
    380             self.structureDeploymentSvc.EndMovingStructure()
    381         if not self.cameraController:
    382             return
    383         if self.positionalControl.IsActive():
    384             if not self.cameraController.IsMouseDragged():
    385                 if btnID == 0:
    386                     self.positionalControl.AddPoint()
    387             return
    388         if uicore.cmd.IsCombatCommandLoaded('CmdApproachItem') and not self.IsMarqueeActivated():
    389             self.positionalControl.StartMoveCommand()
    390         if self.IsMarqueeActivated():
    391             self.ApplyMarqueeCommands()
    392             self.cameraController.mouseDownPos = None
    393         else:
    394             if not self.cameraController.IsMouseDragged() and not uicore.cmd.IsSomeCombatCommandLoaded():
    395                 sm.GetService('stateSvc').ResetByFlag(states.multiSelected)
    396             self.cameraController.OnMouseUp(btnID)
    397         self.StopMarqueeSelection()
    398 
    399     def SetMouseDownAndDoMouseUp(self, *args):
    400         btnID = uiconst.MOUSELEFT
    401         self.cameraController.OnMouseDown(btnID)
    402         self.OnMouseUp(btnID)
    403 
    404     def ApplyMarqueeCommands(self):
    405         balls = self.GetMarqueeSelectedBalls()
    406         if balls:
    407             sm.GetService('stateSvc').SetState(balls[0].id, states.selected, True)
    408             combatCmd = uicore.cmd.GetCombatCmdLoadedName()
    409             if not combatCmd:
    410                 return
    411             if len(balls) > 1 and combatCmd and combatCmd.name in multiTargetCmds:
    412                 self._ApplyCommandToMultiple(balls, combatCmd)
    413             else:
    414                 self._ApplyCommandToNearest(balls, combatCmd)
    415 
    416     def _ApplyCommandToNearest(self, balls, combatCmd):
    417         if combatCmd.name == 'CmdToggleLookAtItem':
    418             radius = self._GetLookAtRadius(balls)
    419             uicore.cmd.ExecuteCombatCommand(balls[0].id, uiconst.UI_CLICK, radius=radius)
    420         else:
    421             uicore.cmd.ExecuteCombatCommand(balls[0].id, uiconst.UI_CLICK)
    422 
    423     def _ApplyCommandToMultiple(self, balls, combatCmd):
    424         ballsWithBracket = [ ball for ball in balls if ball.id in sm.GetService('bracket').brackets ]
    425         if ballsWithBracket:
    426             balls = ballsWithBracket
    427         balls = self._FilterBallsByCombatCmd(balls, combatCmd)
    428         for ball in balls:
    429             uicore.cmd.ExecuteActiveCombatCommand(ball.id)
    430 
    431     def _FilterBallsByCombatCmd(self, balls, combatCmd):
    432         if combatCmd.name == 'CmdLockTargetItem':
    433             maxTargets = sm.GetService('target').GetNumAdditionalTargetsAllowed()
    434             balls = balls[:int(maxTargets)]
    435         return balls
    436 
    437     def _GetLookAtRadius(self, balls):
    438         ret = 0.0
    439         v0 = GetBallPosition(balls[0])
    440         camera = self.cameraController.GetCamera()
    441         v0 = camera.ProjectWorldToCamera(v0)
    442         for ball in balls[1:]:
    443             v1 = GetBallPosition(ball)
    444             if geo2.Vec3Length(v1) > GetCameraMaxLookAtRange():
    445                 continue
    446             v1 = camera.ProjectWorldToCamera(v1)
    447             diff = geo2.Vec3Subtract(v1, v0)
    448             dist = geo2.Vec2Length(diff[:2])
    449             if ret < dist:
    450                 ret = dist
    451 
    452         return ret
    453 
    454     def IsMarqueeActivated(self):
    455         if not self.cameraController:
    456             return False
    457         return self.cameraController.GetMouseTravel() >= 5 and self.marqueeCont
    458 
    459     def GetMarqueeSelectedBalls(self):
    460         ret = []
    461         for itemID, x, y in self.GetAllSlimItemScreenCoords():
    462             if self.IsMarqueeSelected(x, y):
    463                 ret.append(itemID)
    464 
    465         michelle = sm.GetService('michelle')
    466         balls = []
    467         for itemID in ret:
    468             ball = michelle.GetBall(itemID)
    469             if not ball:
    470                 continue
    471             typeID = getattr(ball, 'typeID', None)
    472             if not typeID or is_interactable_entity(evetypes.GetGroupID(typeID)):
    473                 balls.append(ball)
    474 
    475         return sorted(balls, key=self._GetDistanceToCamera)
    476 
    477     def GetBrackets(self):
    478         return sm.GetService('bracket').brackets.values()
    479 
    480     def GetAllSlimItemScreenCoords(self):
    481         bp = sm.GetService('michelle').GetBallpark()
    482         camera = self.cameraController.GetCamera()
    483         ret = []
    484         for itemID in self._GetAllSlimAndSiteItemIDs():
    485             ball = bp.GetBall(itemID)
    486             if not ball:
    487                 continue
    488             vec = ball.GetVectorAt(blue.os.GetSimTime())
    489             vec = (vec.x, vec.y, vec.z)
    490             if camera.IsInFrontOfCamera(vec):
    491                 x, y = self.cameraController.ProjectWorldToScreen(vec)
    492                 ret.append((itemID, ReverseScaleDpi(int(x)), ReverseScaleDpi(int(y))))
    493 
    494         return ret
    495 
    496     def _GetAllSlimAndSiteItemIDs(self):
    497         bp = sm.GetService('michelle').GetBallpark()
    498         slimItemIDs = [ itemID for itemID, _ in bp.slimItems.iteritems() ]
    499         siteItemIDs = [ site.ballID for site in sm.GetService('sensorSuite').GetVisibleSites() ]
    500         return slimItemIDs + siteItemIDs
    501 
    502     def _GetDistanceToCamera(self, ball):
    503         bp = sm.GetService('michelle').GetBallpark()
    504         ballPos = GetBallPosition(ball)
    505         camPos = self.cameraController.GetCamera().eyePosition
    506         return geo2.Vec3Distance(ballPos, camPos)
    507 
    508     def IsMarqueeSelected(self, x, y):
    509         left, top, width, height = self.marqueeCont.GetAbsolute()
    510         if x < left:
    511             return False
    512         elif x > left + width:
    513             return False
    514         elif y < top:
    515             return False
    516         elif y > top + height:
    517             return False
    518         else:
    519             return True
    520 
    521     def OnDblClick(self, *args):
    522         if self.positionalControl.IsActive():
    523             return
    524         if self.cameraController:
    525             self.cameraController.OnDblClick(*args)
    526 
    527     def OnMouseWheel(self, *args):
    528         if self.cameraController:
    529             self.cameraController.OnMouseWheel(*args)
    530 
    531     def OnMouseEnter(self, *args):
    532         if self.destroyed or self.parent is None or self.parent.destroyed:
    533             return
    534         if sm.GetService('ui').IsUiVisible():
    535             uicore.layer.main.state = uiconst.UI_PICKCHILDREN
    536         if sm.IsServiceRunning('tactical'):
    537             uthread.new(sm.GetService('tactical').ClearModuleRange)
    538         if uicore.cmd.IsCombatCommandLoaded('CmdApproachItem') and not self.positionalControl.IsActive():
    539             self.positionalControl.StartMoveCommand()
    540         self.SetOrder(-1)
    541 
    542     def OnMouseExit(self, *args):
    543         if self._ShouldExitPositionalMode():
    544             self.positionalControl.OnSceneMouseExit()
    545         if self.cameraController:
    546             self.cameraController.OnMouseExit()
    547 
    548     def _ShouldExitPositionalMode(self):
    549         currentMouseOver = uicore.uilib.GetMouseOver()
    550         if currentMouseOver is None:
    551             return True
    552         if isinstance(currentMouseOver, Bracket):
    553             if self.positionalControl.IsTargeting():
    554                 return False
    555         return True
    556 
    557     def OnMouseMove(self, *args):
    558         if uicore.IsDragging():
    559             return
    560         self.sr.hint = ''
    561         self.sr.tcursor.left = uicore.uilib.x - 1
    562         self.sr.tcursor.top = uicore.uilib.y
    563         self.CheckStartMoveCommand()
    564         if self.positionalControl.IsActive():
    565             if uicore.uilib.leftbtn and self.cameraController.IsMouseDragged():
    566                 self.positionalControl.AbortCommand()
    567                 self.StartMarqueeSelection()
    568             else:
    569                 return
    570         if self._IsMovingStructure():
    571             if uicore.uilib.leftbtn:
    572                 if uicore.uilib.Key(uiconst.VK_CONTROL):
    573                     self.structureDeploymentSvc.RotateDragObject()
    574                 else:
    575                     self.structureDeploymentSvc.MoveDragObject()
    576             elif uicore.uilib.rightbtn:
    577                 self.structureDeploymentSvc.RotateDragObject()
    578         elif self.cameraController:
    579             if self.cameraController.CheckMoveSceneCursor():
    580                 self.StopMarqueeSelection()
    581             elif not self.marqueeCont and self.mouseDown:
    582                 self.cameraController.OnMouseMove(*args)
    583 
    584     def _IsMovingStructure(self):
    585         if not sm.IsServiceRunning('structureDeployment'):
    586             return False
    587         return self.structureDeploymentSvc.IsMovingStructure()
    588 
    589     def CheckStartMoveCommand(self):
    590         isMouseDown = uicore.uilib.leftbtn
    591         approachCmdActive = uicore.cmd.IsCombatCommandLoaded('CmdApproachItem')
    592         moveCommandActive = self.positionalControl.IsActive()
    593         if approachCmdActive and not moveCommandActive and not isMouseDown:
    594             self.positionalControl.StartMoveCommand()
    595 
    596     def StopMarqueeSelection(self):
    597         if self.marqueeCont:
    598             self.marqueeCont.Close()
    599             self.marqueeCont = None
    600 
    601     def TryExpandActionMenu(self, pickObj):
    602         if pickObj and hasattr(pickObj, 'translationCurve') and hasattr(pickObj.translationCurve, 'id'):
    603             uthread.new(sm.GetService('radialmenu').TryExpandActionMenu, pickObj.translationCurve.id, self)
    604         elif session.fleetid:
    605             myBtn = GetSingleMouseBtnBroadcastRadialMenu()
    606             if myBtn and uicore.uilib.GetMouseButtonState(myBtn) and not AreOtherMouseBtnsDown(myBtn):
    607                 uthread.new(sm.GetService('radialmenu').TryExpandActionMenu, None, self)
    608                 return
    609             combatCmdLoaded = uicore.cmd.combatCmdLoaded
    610             if combatCmdLoaded and combatCmdLoaded.name == 'CmdOpenBroadcastRadialMenu':
    611                 uthread.new(sm.GetService('radialmenu').TryExpandActionMenu, None, self)
    612 
    613     def ZoomBy(self, amount):
    614         if self.cameraController:
    615             camera = self.cameraController.GetCamera()
    616             camera.Zoom(0.001 * amount)