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

systemMapSvc.py (52179B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\maps\systemMapSvc.py
      2 import sys
      3 from math import sin, cos, pi
      4 import eveformat
      5 import utillib
      6 from carbon.common.script.sys.service import Service
      7 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING
      8 from carbon.common.script.util.commonutils import GetAttrs
      9 from carbon.common.script.util.format import FmtDist
     10 from carbonui.primitives.sprite import Sprite
     11 from carbonui.util.various_unsorted import SortListOfTuples
     12 from eve.client.script.ui.station import stationServiceConst
     13 from eve.client.script.ui.camera.systemMapCamera2 import SystemMapCamera2
     14 import evecamera
     15 import evetypes
     16 import blue
     17 import log
     18 from eve.client.script.parklife import states as state
     19 from eve.client.script.ui.control.eveHint import BubbleHint
     20 from eve.client.script.ui.inflight.bracket import SimpleBracket, Bracket
     21 from eve.client.script.ui.shared.maps.label import TransformableLabel
     22 import trinity
     23 from eve.client.script.ui.util import uix
     24 import uthread
     25 from eve.client.script.ui.shared.maps import maputils
     26 import carbonui.const as uiconst
     27 import localization
     28 import telemetry
     29 from eve.common.lib import appConst as const
     30 from evefleet import BROADCAST_TRAVEL_TO
     31 from evestations.data import service_in_station_operation
     32 from eve.client.script.ui.shared.maps.mapcommon import SYSTEMMAP_SCALE, ZOOM_FAR_SYSTEMMAP
     33 from eve.common.script.mgt.entityConst import POS_STRUCTURE_STATE
     34 import geo2
     35 from carbonui.uicore import uicore
     36 from eveservices.menu import GetMenuService
     37 from menu import MenuLabel
     38 from npcs.divisions import get_division_name
     39 NEUTRAL_COLOR = (0.25,
     40  0.25,
     41  0.25,
     42  1.0)
     43 
     44 class SystemMapSvc(Service):
     45     __guid__ = 'svc.systemmap'
     46     __notifyevents__ = ['OnSessionChanged',
     47      'OnStateChange',
     48      'OnRefreshBookmarks',
     49      'OnSolarsystemMapSettingsChange',
     50      'OnTacticalOverlayChange',
     51      'DoBallsAdded',
     52      'DoBallRemove',
     53      'OnDistributionDungeonEntered',
     54      'OnEscalatingPathDungeonEntered',
     55      'OnSlimItemChange',
     56      'OnMapReset',
     57      'OnMapModeChangeDone',
     58      'DoBallsRemove']
     59     __servicename__ = 'systemmap'
     60     __displayname__ = 'System Map Client Service'
     61     __dependencies__ = ['station',
     62      'map',
     63      'settings',
     64      'facwar',
     65      'securityOfficeSvc']
     66     __update_on_reload__ = 0
     67 
     68     def Run(self, memStream = None):
     69         self.state = SERVICE_START_PENDING
     70         self.LogInfo('Starting System Map Client Svc')
     71         self.Reset()
     72         self.state = SERVICE_RUNNING
     73 
     74     def Stop(self, memStream = None):
     75         if trinity.device is None:
     76             return
     77         self.LogInfo('Map svc')
     78         self.Reset()
     79 
     80     def CleanUp(self):
     81         self.Reset()
     82         scene = sm.GetService('sceneManager').GetRegisteredScene('systemmap')
     83         if scene:
     84             del scene.objects[:]
     85         sm.GetService('sceneManager').UnregisterScene('systemmap')
     86         sm.GetService('sceneManager').UnregisterCamera(evecamera.CAM_SYSTEMMAP)
     87 
     88     def Open(self):
     89         from eve.client.script.ui.shared.mapView.mapViewUtil import OpenSolarSystemMap
     90         OpenSolarSystemMap()
     91 
     92     def OnMapModeChangeDone(self, mapMode):
     93         if mapMode == 'systemmap':
     94             if self.updateDisplayInfomationWorkerRunning == False:
     95                 self.updateDisplayInfomationWorkerRunning = True
     96                 uthread.new(self.UpdateDisplayInformationWorker).context = 'systemMapSvc::UpdateDisplayInformationWorker'
     97 
     98     def UpdateDisplayInformationWorker(self):
     99         while sm.GetService('viewState').IsViewActive('systemmap'):
    100             startTime = blue.os.GetWallclockTime()
    101             for panel in self.bracketPanels[:]:
    102                 if panel and not panel.destroyed:
    103                     if panel.ball:
    104                         panel.ball.GetVectorAt(blue.os.GetSimTime())
    105                     if getattr(panel, 'hasBubbleHintShowing', False):
    106                         if panel.itemID and panel.slimItem and hasattr(panel.sr, 'bubble'):
    107                             if panel.sr.bubble.state != uiconst.UI_HIDDEN:
    108                                 hintText = self.GetBubbleHint(panel.itemID, panel.slimItem, bracket=panel, extended=0)
    109                                 panel.ShowBubble(hintText)
    110                 blue.pyos.BeNice()
    111 
    112             diff = blue.os.TimeDiffInMs(startTime, blue.os.GetWallclockTime())
    113             sleep = max(500, 2000 - diff)
    114             blue.pyos.synchro.SleepWallclock(sleep)
    115 
    116         self.updateDisplayInfomationWorkerRunning = False
    117 
    118     def OnMapReset(self):
    119         self.Reset()
    120 
    121     def InitMap(self):
    122         title = localization.GetByLabel('UI/Map/StarMap/InitializingMap')
    123         loadLabel = localization.GetByLabel('UI/Map/StarMap/BuildingModel')
    124         sm.GetService('loading').ProgressWnd(title, loadLabel, 0, 3)
    125         sceneManager = sm.GetService('sceneManager')
    126         registered = sceneManager.GetRegisteredScene('systemmap')
    127         camera = sceneManager.GetRegisteredCamera(evecamera.CAM_SYSTEMMAP)
    128         if registered is None or self.currentSolarsystemID != session.solarsystemid2:
    129             cameraFov = 0.7
    130             scene = trinity.Load('res:/dx9/scene/systemMap.red')
    131             lineSet = self.map.CreateLineSet()
    132             lineSet.scaling = (SYSTEMMAP_SCALE, SYSTEMMAP_SCALE, SYSTEMMAP_SCALE)
    133             scene.objects.append(lineSet)
    134             self.orbitLineSet = lineSet
    135             ssmap, self.solarsystemSunID = self.DrawSolarSystem(session.solarsystemid2)
    136             self.currentSolarsystemID = session.solarsystemid2
    137             if camera is None:
    138                 camera = SystemMapCamera2()
    139                 camera.idleMove = 0
    140                 camera.friction = 25.0
    141                 camera.fieldOfView = cameraFov
    142                 camera.frontClip = 0.3
    143                 camera.backClip = 30000.0
    144                 for i, each in enumerate(camera.zoomCurve.keys):
    145                     key = list(each)
    146                     key[1] = cameraFov
    147                     camera.zoomCurve.keys[i] = tuple(key)
    148 
    149                 camera.translationFromParent = settings.user.ui.Get('systemmapTFP', 0.8 * ZOOM_FAR_SYSTEMMAP)
    150                 if camera.translationFromParent < 0:
    151                     camera.translationFromParent = -camera.translationFromParent
    152                 camera.OrbitParent(0.0, 10.0)
    153                 sceneManager.RegisterCamera(camera)
    154             ssmap.scaling = (SYSTEMMAP_SCALE, SYSTEMMAP_SCALE, SYSTEMMAP_SCALE)
    155             scene.objects.append(ssmap)
    156             self.currentSolarsystem = ssmap
    157             sceneManager.RegisterScene(scene, 'systemmap')
    158             sm.GetService('viewState').GetView('systemmap').layer.SetInterest(session.shipid, interpolate=False)
    159         sceneManager.SetRegisteredScenes('systemmap')
    160         sceneManager.SetSecondaryCamera(evecamera.CAM_SYSTEMMAP)
    161         sm.GetService('loading').ProgressWnd(title, loadLabel, 1, 3)
    162         self.LoadBookmarks()
    163         self.LoadSolarsystemBrackets()
    164         self.LoadBeacons()
    165         self.LoadSatellites()
    166         self.LoadSovereigntyStructures()
    167         self.LoadDungeons()
    168         sm.GetService('loading').ProgressWnd(title, loadLabel, 2, 3)
    169         uthread.new(self.ShowRanges, sm.GetService('tactical').IsTacticalOverlayActive())
    170         sm.GetService('loading').StopCycle()
    171 
    172     def OnSessionChanged(self, isremote, session, change):
    173         if session.charid is None:
    174             return
    175         if 'solarsystemid' in change:
    176             if sm.GetService('viewState').IsViewActive('systemmap'):
    177                 self.InitMap()
    178             else:
    179                 self.ClearAllBrackets()
    180 
    181     def DoBallsAdded(self, *args, **kw):
    182         import stackless
    183         import blue
    184         t = stackless.getcurrent()
    185         timer = t.PushTimer(blue.pyos.taskletTimer.GetCurrent() + '::map')
    186         try:
    187             return self.DoBallsAdded_(*args, **kw)
    188         finally:
    189             t.PopTimer(timer)
    190 
    191     def DoBallsAdded_(self, lst, ignoreMoons = 0, ignoreAsteroids = 1):
    192         if sm.GetService('viewState').IsViewActive('systemmap'):
    193             groupIDs = []
    194             for ball, slimItem in lst:
    195                 groupIDs.append(slimItem.groupID)
    196                 if ball.id == session.shipid:
    197                     self.LoadSolarsystemBrackets(1)
    198 
    199             if const.groupCosmicSignature in groupIDs or const.groupCosmicAnomaly in groupIDs:
    200                 uthread.worker('MapMgr::LoadDungeons', self.LoadDungeons)
    201             if slimItem.groupID in const.sovereigntyClaimStructuresGroups:
    202                 self.LoadSovereigntyStructures()
    203 
    204     @telemetry.ZONE_METHOD
    205     def DoBallsRemove(self, pythonBalls, isRelease):
    206         for ball, slimItem, terminal in pythonBalls:
    207             self.DoBallRemove(ball, slimItem, terminal)
    208 
    209     def DoBallRemove(self, ball, slimItem, terminal):
    210         if not trinity.device:
    211             return
    212         if sm.GetService('viewState').IsViewActive('systemmap'):
    213             if slimItem.groupID in const.sovereigntyClaimStructuresGroups:
    214                 self.LoadSovereigntyStructures()
    215 
    216     def OnStateChange(self, itemID, flag, true, *args):
    217         if not sm.GetService('viewState').IsViewActive('starmap', 'systemmap'):
    218             return None
    219         if flag == state.gbTravelTo:
    220             self.broadcastBrackets = self.broadcastBrackets or {}
    221             gbID, charID = args
    222             if true:
    223                 self.broadcastBrackets[itemID] = (gbID, sm.GetService('starmap').MakeBroadcastBracket(BROADCAST_TRAVEL_TO, itemID, charID))
    224             else:
    225                 lastGBID, bracket = self.broadcastBrackets.get(itemID, (None, None))
    226                 if lastGBID == gbID:
    227                     del self.broadcastBrackets[itemID]
    228         bracket = self.GetBracket(itemID)
    229         if bracket:
    230             bracket.OnStateChange(itemID, flag, true, *args)
    231 
    232     def OnRefreshBookmarks(self):
    233         if sm.GetService('viewState').IsViewActive('systemmap'):
    234             self.LoadBookmarks()
    235             sm.GetService('bracket').ResetOverlaps()
    236 
    237     def OnSolarsystemMapSettingsChange(self, change, *args):
    238         if sm.GetService('viewState').IsViewActive('systemmap') and change == 'brackets':
    239             self.LoadBookmarks()
    240             self.LoadSolarsystemBrackets(1)
    241             self.LoadBeacons()
    242             self.LoadSatellites()
    243             self.LoadSovereigntyStructures()
    244             self.LoadDungeons()
    245 
    246     def OnDistributionDungeonEntered(self, row):
    247         self.LoadDungeons()
    248 
    249     def OnEscalatingPathDungeonEntered(self, row):
    250         self.LoadDungeons()
    251 
    252     def OnTacticalOverlayChange(self):
    253         on = sm.GetService('tactical').IsTacticalOverlayActive()
    254         if sm.GetService('viewState').IsViewActive('systemmap'):
    255             self.ShowRanges(on)
    256 
    257     def Reset(self):
    258         self.LogInfo('System Map Reset')
    259         self.currentSolarsystemID = None
    260         self.currentSolarsystem = None
    261         self.solarsystemBracketsLoaded = None
    262         self.solarsystemHierarchyData = {}
    263         self.expandingHint = None
    264         self.talking = set()
    265         rangeCircleTF = getattr(self, 'rangeCircleTF', None)
    266         if rangeCircleTF:
    267             for each in rangeCircleTF.curveSets[:]:
    268                 rangeCircleTF.curveSets.remove(each)
    269 
    270         self.rangeCircleTF = None
    271         self.rangeLineSet = None
    272         self.ssitems = None
    273         self.broadcastBrackets = None
    274         self.taxLevel = None
    275         self.mapStars = None
    276         self.starParticles = None
    277         self.solarSystemJumpLineSet = None
    278         self.cursor = None
    279         self.uicursor = None
    280         self.minimizedWindows = []
    281         self.activeMap = ''
    282         toRemove = getattr(self, 'bracketPanels', [])
    283         for each in toRemove:
    284             each.Close()
    285 
    286         self.bracketPanels = []
    287         self.updateDisplayInfomationWorkerRunning = False
    288 
    289     def GetBracket(self, itemID):
    290         wnd = uicore.layer.systemMapBrackets
    291         for each in wnd.children:
    292             if getattr(each, 'IsBracket', 0) and getattr(each, 'itemID', None) == itemID:
    293                 return each
    294 
    295     def GetSolarsystemHierarchy(self, solarsystemID = None, toplevel = None):
    296         toplevel = toplevel or (const.groupPlanet,
    297          const.groupSun,
    298          const.groupStargate,
    299          const.groupStation)
    300         solarsystemID = solarsystemID or self.currentSolarsystemID
    301         if not solarsystemID:
    302             return ({}, {})
    303         if (solarsystemID, toplevel) in self.solarsystemHierarchyData:
    304             return self.solarsystemHierarchyData[solarsystemID, toplevel]
    305         ssData = self.GetSolarsystemData(solarsystemID).Index('itemID')
    306         groups = {}
    307         noOrbitID = []
    308         for id in ssData:
    309             each = ssData[id]
    310             if evetypes.GetGroupID(each.typeID) in toplevel:
    311                 if each.itemID not in groups:
    312                     groups[each.itemID] = []
    313             elif each.orbitID is None:
    314                 noOrbitID.append(each)
    315 
    316         for each in noOrbitID:
    317             if evetypes.GetGroupID(each.typeID) == const.groupSun:
    318                 continue
    319             pos = trinity.TriVector(each.x, each.y, each.z)
    320             lst = []
    321             for parentID, orbits in groups.iteritems():
    322                 parentItem = ssData[parentID]
    323                 parentPos = trinity.TriVector(parentItem.x, parentItem.y, parentItem.z)
    324                 dist = (pos - parentPos).Length()
    325                 lst.append((dist, parentID))
    326 
    327             lst.sort()
    328             groups[lst[0][1]].append(each)
    329 
    330         parentLess = []
    331         for id in ssData:
    332             each = ssData[id]
    333             if each.itemID not in groups:
    334                 if each.orbitID in groups:
    335                     groups[each.orbitID].append(each)
    336                 elif each.orbitID:
    337                     parent = ssData[each.orbitID]
    338                     if parent.orbitID in groups:
    339                         groups[parent.orbitID].append(each)
    340                     else:
    341                         parentLess.append(each)
    342 
    343         self.solarsystemHierarchyData[solarsystemID, toplevel] = (groups, ssData)
    344         return (groups, ssData)
    345 
    346     def ClearAllBrackets(self):
    347         solarsystem = self.GetCurrentSolarSystem()
    348         bracketWnd = uicore.layer.systemMapBrackets
    349         for each in bracketWnd.children[:]:
    350             each.Close()
    351 
    352         self.solarsystemBracketsLoaded = None
    353 
    354     def ClearBrackets(self, _ui = None, _tf = None):
    355         solarsystem = self.GetCurrentSolarSystem()
    356         if solarsystem and _tf:
    357             for tf in solarsystem.children[:]:
    358                 if hasattr(tf, 'name') and tf.name.startswith(_tf):
    359                     solarsystem.children.remove(tf)
    360 
    361         bracketWnd = uicore.layer.systemMapBrackets
    362         for each in bracketWnd.children[:]:
    363             if each.name == _ui:
    364                 each.Close()
    365 
    366     @telemetry.ZONE_METHOD
    367     def LoadBookmarks(self):
    368         self.ClearBrackets('__bookmarkbracket', 'bm_')
    369         if 'bookmark' not in maputils.GetVisibleSolarsystemBrackets():
    370             return
    371         solarSystemID = session.solarsystemid2
    372         bookmarks = sm.GetService('bookmarkSvc').GetActiveBookmarksFiltered(solarSystemID=solarSystemID, usePersonalFilter=False)
    373         ballPark = sm.GetService('michelle').GetBallpark()
    374         bracketWnd = uicore.layer.systemMapBrackets
    375         solarsystem = self.GetCurrentSolarSystem()
    376         showhint = maputils.GetHintsOnSolarsystemBrackets()
    377         showBubbleHint = 'bookmark' in showhint
    378         for bookmark in bookmarks.itervalues():
    379             if bookmark.locationID != solarSystemID:
    380                 continue
    381             if bookmark.x is None:
    382                 if bookmark.itemID is not None:
    383                     if ballPark and bookmark.itemID in ballPark.balls:
    384                         ball = ballPark.balls[bookmark.itemID]
    385                         pos = (ball.x, ball.y, ball.z)
    386                     elif solarsystem:
    387                         for tf in solarsystem.children:
    388                             try:
    389                                 itemID = int(tf.name)
    390                             except:
    391                                 sys.exc_clear()
    392                                 continue
    393 
    394                             if itemID == bookmark.itemID:
    395                                 pos = tf.translation
    396                                 break
    397                         else:
    398                             self.LogError('Didnt find propper item to track for bookmark', bookmark)
    399                             continue
    400 
    401                     else:
    402                         self.LogError('No ballpark or solarsystem to search for transform to track', bookmark)
    403                         continue
    404                 else:
    405                     self.LogError('Cannot draw bookmark into solarsystem view', bookmark)
    406                     continue
    407             else:
    408                 pos = (bookmark.x, bookmark.y, bookmark.z)
    409             if solarsystem and pos:
    410                 panel = BookmarkBracket()
    411                 panel.name = '__bookmarkbracket'
    412                 panel.align = uiconst.NOALIGN
    413                 panel.state = uiconst.UI_NORMAL
    414                 panel.width = panel.height = 16
    415                 panel.dock = 0
    416                 panel.minDispRange = 0.0
    417                 panel.maxDispRange = 1e+32
    418                 panel.inflight = False
    419                 panel.color = None
    420                 panel.invisible = False
    421                 panel.fadeColor = 0
    422                 panel.OnDblClick = (self.OnBracketDoubleClick, panel)
    423                 tf = trinity.EveTransform()
    424                 tf.name = 'bm_%d' % bookmark.bookmarkID
    425                 solarsystem.children.append(tf)
    426                 panel.trackTransform = tf
    427                 tf.translation = geo2.Vector(*pos)
    428                 panel.Startup(bookmark, showBubbleHint)
    429                 bracketWnd.children.insert(0, panel)
    430 
    431     def GetSolarsystem(self):
    432         return getattr(self, 'currentSolarsystem', None)
    433 
    434     def RefreshBubble(self, bubble):
    435         bracket = bubble.parent
    436         if bracket is None:
    437             log.LogTraceback('RefreshBubble: no bracket')
    438             return
    439         if bubble.expanded:
    440             bubble.ShowHint(bracket.expandedHint)
    441         else:
    442             bubble.ShowHint(bracket.collapsedHint)
    443         bracket.sr.bubble.sr.ExpandBubbleHint = lambda *args: self.ExpandBubbleHint(*args)
    444 
    445     def ShowRanges(self, on = 1):
    446         scene = sm.GetService('sceneManager').GetRegisteredScene('systemmap')
    447         if self.rangeCircleTF:
    448             for each in self.rangeCircleTF.curveSets[:]:
    449                 self.rangeCircleTF.curveSets.remove(each)
    450 
    451             if self.rangeCircleTF in scene.objects:
    452                 scene.objects.remove(self.rangeCircleTF)
    453         if self.rangeLineSet and self.rangeLineSet in scene.objects:
    454             scene.objects.remove(self.rangeLineSet)
    455         self.rangeLineSet = None
    456         self.rangeCircleTF = None
    457         if not on:
    458             return
    459         ranges = trinity.EveRootTransform()
    460         ranges.name = 'rangeCircleLabels'
    461         ranges.scaling = (SYSTEMMAP_SCALE, SYSTEMMAP_SCALE, SYSTEMMAP_SCALE)
    462         scene.objects.append(ranges)
    463         self.rangeCircleTF = ranges
    464         lineSet = self.map.CreateLineSet()
    465         for r in [5,
    466          10,
    467          15,
    468          20,
    469          25]:
    470             color = 0.25
    471             if r in (10, 20):
    472                 color = 0.33
    473             radius = r * const.AU
    474             self.AddCircle(lineSet, radius * SYSTEMMAP_SCALE, color=color)
    475             self.AddRangeLabel(ranges, FmtDist(radius, 0), radius)
    476 
    477         lineSet.SubmitChanges()
    478         scene.objects.append(lineSet)
    479         self.rangeLineSet = lineSet
    480         for each in ranges.curveSets[:]:
    481             ranges.curveSets.remove(each)
    482 
    483         if session.solarsystemid:
    484             t = 0
    485             sunBall = sm.GetService('michelle').GetBall(self.solarsystemSunID)
    486             while sunBall is None:
    487                 blue.pyos.synchro.SleepWallclock(1000)
    488                 sunBall = sm.GetService('michelle').GetBall(self.solarsystemSunID)
    489                 t += 1
    490                 if t == 15:
    491                     return
    492 
    493             vectorCurve = trinity.Tr2CurveVector3()
    494             vectorCurve.AddKey(0, (-SYSTEMMAP_SCALE, -SYSTEMMAP_SCALE, -SYSTEMMAP_SCALE))
    495             vectorSequencer = trinity.TriVectorSequencer()
    496             vectorSequencer.operator = trinity.TRIOP_MULTIPLY
    497             vectorSequencer.functions.append(sunBall)
    498             vectorSequencer.functions.append(vectorCurve)
    499             binding = trinity.TriValueBinding()
    500             binding.sourceAttribute = 'value'
    501             binding.destinationAttribute = 'translation'
    502             binding.scale = 1.0
    503             binding.sourceObject = vectorSequencer
    504             binding.destinationObject = ranges
    505             curveSet = trinity.TriCurveSet()
    506             curveSet.name = 'translationCurveSet'
    507             curveSet.playOnLoad = True
    508             curveSet.curves.append(vectorSequencer)
    509             curveSet.bindings.append(binding)
    510             ranges.curveSets.append(curveSet)
    511             curveSet.Play()
    512             lineSet.translationCurve = vectorSequencer
    513         else:
    514             pos = maputils.GetMyPos()
    515             vectorCurve = trinity.Tr2TranslationAdapter()
    516             vectorCurve.value = (pos.x * SYSTEMMAP_SCALE, pos.y * SYSTEMMAP_SCALE, pos.z * SYSTEMMAP_SCALE)
    517             ranges.translationCurve = vectorCurve
    518             lineSet.translationCurve = vectorCurve
    519 
    520     def AddRangeLabel(self, parent, text, radius):
    521         for x, z in [(0.0, radius),
    522          (radius, 0.0),
    523          (0.0, -radius),
    524          (-radius, 0.0)]:
    525             label = TransformableLabel(text, parent, shadow=0, hspace=0)
    526             label.transform.translation = (x, 0.0, z)
    527             scale = geo2.Vector(*label.transform.scaling) * 1250000000.0
    528             label.transform.scaling = scale
    529             label.SetDiffuseColor((0.7, 0.7, 0.7, 1.0))
    530 
    531     def AddCircle(self, lineSet, radius, numberOfPoints = 256, color = 0.35):
    532         color = (color,
    533          color,
    534          color,
    535          color)
    536         step = pi * 2.0 / numberOfPoints
    537         points = []
    538         for idx in range(numberOfPoints):
    539             angle = idx * step
    540             x = cos(angle) * radius
    541             z = sin(angle) * radius
    542             points.append((x, 0.0, z))
    543 
    544         for idx1 in range(numberOfPoints):
    545             idx2 = (idx1 + 1) % numberOfPoints
    546             lineSet.AddLine(points[idx1], color, points[idx2], color)
    547 
    548     def LoadSolarsystemBrackets(self, reload = 0):
    549         if self.solarsystemBracketsLoaded == session.solarsystemid2 and not reload:
    550             return
    551         bracketWnd = uicore.layer.systemMapBrackets
    552         bp = sm.GetService('michelle').GetBallpark()
    553         groups, ssData = self.GetSolarsystemHierarchy(self.currentSolarsystemID)
    554         self.ClearBrackets('__solarsystembracket')
    555         self.ClearBrackets('__iamherebracket')
    556         solarsystem = self.GetCurrentSolarSystem()
    557         if solarsystem is None:
    558             return
    559         self.solarsystemBracketsLoaded = session.solarsystemid2
    560         validGroups = groups
    561         inf = 1e+32
    562         visible = maputils.GetVisibleSolarsystemBrackets()
    563         showhint = maputils.GetHintsOnSolarsystemBrackets()
    564         self.bracketPanels = []
    565         bracket = Bracket(parent=bracketWnd, name='__iamherebracket', align=uiconst.NOALIGN, state=uiconst.UI_PICKCHILDREN)
    566         bubble = BubbleHint(parent=bracket, name='bubblehint', align=uiconst.TOPLEFT, width=0, height=0, idx=0, state=uiconst.UI_PICKCHILDREN)
    567         bubble.ShowHint(localization.GetByLabel('UI/Map/StarMap/lblYouAreHere'), 2)
    568         bb = trinity.device.GetRenderContext().GetDefaultBackBuffer()
    569         if bb.width & 1:
    570             bracket.projectBracket.offsetX = 0.5
    571         if bb.height & 1:
    572             bracket.projectBracket.offsetY = 0.5
    573         if session.stationid:
    574             pos = maputils.GetMyPos()
    575             tf = trinity.EveTransform()
    576             tf.name = 'mypos'
    577             tf.translation = (pos.x, pos.y, pos.z)
    578             solarsystem.children.append(tf)
    579             bracket.trackTransform = tf
    580         elif session.solarsystemid:
    581             sunBall = sm.GetService('michelle').GetBall(self.solarsystemSunID)
    582             bracket.trackBall = sunBall
    583             bracket.ballTrackingScaling = -SYSTEMMAP_SCALE
    584         self.bracketPanels.append(bracket)
    585         for tf in solarsystem.children:
    586             try:
    587                 itemID = int(tf.name)
    588                 itemData = ssData[itemID]
    589             except:
    590                 sys.exc_clear()
    591                 continue
    592 
    593             if bp is not None and bp.slimItems:
    594                 slimItem = bp.GetInvItem(itemID)
    595                 if slimItem is None:
    596                     self.LogError('slimItem is None but I was expecting it to be something relevant', itemID, session.solarsystemid)
    597                     continue
    598                 ball = bp.GetBall(itemID)
    599                 if evetypes.GetGroupID(slimItem.typeID) not in visible:
    600                     continue
    601             else:
    602                 if evetypes.GetGroupID(itemData.typeID) not in visible:
    603                     continue
    604                 ball = None
    605                 slimItem = utillib.KeyVal()
    606                 slimItem.jumps = []
    607                 slimItem.itemID = itemData.itemID
    608                 slimItem.ballID = None
    609                 slimItem.charID = None
    610                 slimItem.ownerID = None
    611                 slimItem.typeID = itemData.typeID
    612                 slimItem.groupID = evetypes.GetGroupID(itemData.typeID)
    613                 slimItem.categoryID = evetypes.GetCategoryID(itemData.typeID)
    614                 slimItem.corpID = getattr(itemData, 'corpID', None)
    615                 slimItem.locationID = getattr(itemData, 'locationID', None)
    616                 slimItem.warFactionID = getattr(itemData, 'warFactionID', 0)
    617                 slimItem.allianceID = getattr(itemData, 'allianceID', None)
    618             panel = Bracket(name='__solarsystembracket', align=uiconst.NOALIGN, state=uiconst.UI_NORMAL, width=16, height=16)
    619             panel.data = sm.GetService('bracket').GetBracketProps(slimItem, ball)
    620             try:
    621                 displayName = uix.GetSlimItemName(slimItem)
    622             except:
    623                 sys.exc_clear()
    624                 continue
    625 
    626             if slimItem.groupID == const.groupStation:
    627                 displayName = uix.EditStationName(displayName, usename=1)
    628             _iconNo, _dockType, _minDist, _maxDist, _iconOffset, _logflag = panel.data
    629             panel.displayName = displayName
    630             bracketWnd.children.insert(0, panel)
    631             panel.trackTransform = tf
    632             bb = trinity.device.GetRenderContext().GetDefaultBackBuffer()
    633             if bb.width & 1:
    634                 panel.projectBracket.offsetX = 0.5
    635             if bb.height & 1:
    636                 panel.projectBracket.offsetY = 0.5
    637             panel.dock = 0
    638             panel.minDispRange = 0.0
    639             panel.maxDispRange = 1e+32
    640             panel.inflight = False
    641             panel.color = None
    642             panel.invisible = False
    643             panel.updateItem = False
    644             panel.fadeColor = 0
    645             panel.sr.slimItem = slimItem
    646             panel.ssData = itemData
    647             panel.groupID = slimItem.groupID
    648             panel.ball = ball
    649             panel.Startup(slimItem, ball, tf)
    650             panel.OnDblClick = (self.OnBracketDoubleClick, panel)
    651             if slimItem.groupID in showhint:
    652                 panel.hasBubbleHintShowing = True
    653                 panel.pickState = uiconst.TR2_SPS_CHILDREN
    654                 panel.width = panel.height = 800
    655                 panel.sr.icon.SetAlign(uiconst.CENTER)
    656                 panel.ShowBubble(self.GetBubbleHint(itemID, slimItem, bracket=panel, extended=0))
    657                 panel.showLabel = 0
    658                 if slimItem.groupID in (const.groupStation,):
    659                     panel.sr.bubble.sr.ExpandHint = self.ExpandBubbleHint
    660             self.bracketPanels.append(panel)
    661 
    662         self.SortBubbles()
    663 
    664     def LoadBeacons(self):
    665         self.LoadBallparkItems('__beaconbracket', 'beacon_', [const.groupBeacon, const.groupCynosuralBeacon], overrideWidthHeight=(800, 800))
    666 
    667     def LoadSatellites(self):
    668         self.LoadBallparkItems('__satellitebracket', 'satellite_', [const.groupSatellite], overrideWidthHeight=(800, 800))
    669 
    670     def LoadSovereigntyStructures(self):
    671         self.LoadBallparkItems('__sovereigntybracket', 'sovereignty_', [const.groupSovereigntyClaimMarkers, const.groupSovereigntyDisruptionStructures], overrideWidthHeight=(800, 800))
    672 
    673     def LoadBallparkItems(self, bracketName, bracketPrefix, itemGroupIDs, overrideWidthHeight = None):
    674         solarsystem = self.GetSolarsystem()
    675         if solarsystem is None:
    676             log.LogInfo('no solar system (', bracketPrefix, 'Structures)')
    677             return
    678         self.ClearBrackets(bracketName, bracketPrefix)
    679         itemGroupIDlist = []
    680         visibleGroups = maputils.GetVisibleSolarsystemBrackets()
    681         for groupID in itemGroupIDs:
    682             if groupID in visibleGroups:
    683                 itemGroupIDlist.append(groupID)
    684 
    685         if not itemGroupIDlist:
    686             return
    687         ballpark = sm.GetService('michelle').GetBallpark()
    688         if ballpark is None:
    689             return
    690         showhint = maputils.GetHintsOnSolarsystemBrackets()
    691         bracketWnd = uicore.layer.systemMapBrackets
    692         for itemID, ball in ballpark.balls.iteritems():
    693             if ballpark is None:
    694                 break
    695             slimItem = ballpark.GetInvItem(itemID)
    696             if not slimItem:
    697                 continue
    698             if slimItem.groupID not in itemGroupIDlist:
    699                 continue
    700             panel = Bracket(name=bracketName, align=uiconst.NOALIGN, state=uiconst.UI_NORMAL, width=16, height=16)
    701             panel.data = sm.GetService('bracket').GetBracketProps(slimItem, ball)
    702             try:
    703                 displayName = uix.GetSlimItemName(slimItem)
    704             except:
    705                 sys.exc_clear()
    706                 continue
    707 
    708             _iconNo, _dockType, _minDist, _maxDist, _iconOffset, _logflag = panel.data
    709             panel.displayName = displayName
    710             bracketWnd.children.insert(0, panel)
    711             tracker = trinity.EveTransform()
    712             tracker.name = '%s%d' % (bracketPrefix, itemID)
    713             tracker.translation = (ball.x, ball.y, ball.z)
    714             solarsystem.children.append(tracker)
    715             panel.trackTransform = tracker
    716             panel.dock = 0
    717             panel.minDispRange = 0.0
    718             panel.maxDispRange = 1e+32
    719             panel.inflight = False
    720             panel.color = None
    721             panel.invisible = False
    722             panel.updateItem = False
    723             panel.fadeColor = 0
    724             panel.sr.slimItem = slimItem
    725             panel.groupID = slimItem.groupID
    726             panel.Startup(slimItem, ball)
    727             if slimItem.groupID in showhint:
    728                 if overrideWidthHeight is not None:
    729                     panel.width, panel.height = overrideWidthHeight
    730                 panel.hasBubbleHintShowing = True
    731                 panel.pickState = uiconst.TR2_SPS_CHILDREN
    732                 panel.sr.icon.SetAlign(uiconst.CENTER)
    733                 panel.ShowBubble(self.GetBubbleHint(itemID, slimItem, bracket=panel, extended=0))
    734                 panel.showLabel = 0
    735                 panel.sr.bubble.sr.ExpandHint = self.ExpandBubbleHint
    736 
    737         self.SortBubbles()
    738 
    739     def OnSlimItemChange(self, oldItem, newItem):
    740         if newItem.groupID in const.sovereigntyClaimStructuresGroups:
    741             self.LoadSovereigntyStructures()
    742 
    743     def LoadDungeons(self):
    744         self.ClearBrackets('__dungeonbracket', 'dg_')
    745         if not session.solarsystemid:
    746             return
    747         escalatingPath = sm.GetService('dungeonTracking').GetEscalatingPathDungeonsEntered()
    748         knownDungeons = sm.GetService('dungeonTracking').GetDistributionDungeonsEntered()
    749         self._LoadDungeons(escalatingPath)
    750         self._LoadDungeons(knownDungeons)
    751 
    752     def _LoadDungeons(self, data):
    753         solarsystem = self.GetCurrentSolarSystem()
    754         if solarsystem is None:
    755             return
    756         if not data:
    757             return
    758         bracketWnd = uicore.layer.systemMapBrackets
    759         for each in data:
    760             panel = SimpleBracket()
    761             bracketWnd.children.insert(0, panel)
    762             panel.name = '__dungeonbracket'
    763             panel.align = uiconst.NOALIGN
    764             panel.state = uiconst.UI_NORMAL
    765             panel.dock = 0
    766             panel.minDispRange = 0.0
    767             panel.maxDispRange = 1e+32
    768             panel.inflight = False
    769             panel.color = None
    770             panel.invisible = False
    771             panel.fadeColor = False
    772             tf = trinity.EveTransform()
    773             tf.name = 'dg_%s_%s' % (repr(each.name), getattr(each, 'ballID', -1))
    774             solarsystem.children.append(tf)
    775             panel.trackTransform = tf
    776             tf.translation = (each.x, each.y, each.z)
    777             panel.displayName = each.name
    778             panel.Startup(tf.name, None, None, 'ui_38_16_14')
    779             panel.sr.icon.SetAlign(uiconst.CENTER)
    780             panel.ShowBubble(each.name)
    781             panel.showLabel = 0
    782 
    783         self.SortBubbles()
    784 
    785     def GetBubbleHint(self, itemID, slimItem = None, mapData = None, bracket = None, extended = 0):
    786         if extended and getattr(bracket, 'expandedHint', None):
    787             return bracket.expandedHint
    788         if not extended and getattr(bracket, 'collapsedHint', None):
    789             return bracket.collapsedHint
    790         if session.solarsystemid and slimItem is None:
    791             slimItem = sm.GetService('michelle').GetItem(itemID)
    792         if slimItem is None and mapData is None:
    793             mapData = self.map.GetItem(itemID)
    794             if mapData is None:
    795                 return ''
    796         typeID = None
    797         groupID = None
    798         hint = []
    799         if slimItem:
    800             groupID = slimItem.groupID
    801             typeID = slimItem.typeID
    802             displayName = uix.GetSlimItemName(slimItem)
    803         if mapData:
    804             displayName = mapData.itemName
    805             if groupID is None:
    806                 if hasattr(mapData, 'groupID'):
    807                     groupID = mapData.groupID
    808                 else:
    809                     groupID = evetypes.GetGroupID(mapData.typeID)
    810             if hasattr(mapData, 'orbitID'):
    811                 orbitID = mapData.orbitID
    812             typeID = mapData.typeID
    813         if groupID is None:
    814             return hint
    815         ball = None
    816         transform = None
    817         if bracket:
    818             ball = bracket.trackBall or getattr(bracket.sr, 'trackBall', None)
    819             transform = bracket.trackTransform
    820         if groupID == const.groupStation:
    821             displayName = sm.GetService('ui').GetStationName(itemID)
    822             displayName = uix.EditStationName(displayName, usename=1)
    823         hint.append(('<b>' + displayName + '</b>', ('OnClick', 'ShowInfo', (typeID, itemID))))
    824         if groupID == const.groupSolarSystem:
    825             ss = self.map.GetSecurityStatus(itemID)
    826             if ss is not None:
    827                 hint.append(localization.GetByLabel('UI/Map/StarMap/hintSecurityStatus', level=ss))
    828         else:
    829             distance = maputils.GetDistance(slimItem, mapData, ball, transform)
    830             if distance is not None:
    831                 hint.append(localization.GetByLabel('UI/Map/StarMap/lblDistance', distance=FmtDist(distance)))
    832         if extended:
    833             if groupID == const.groupBeacon:
    834                 if session.solarsystemid:
    835                     beacon = sm.GetService('michelle').GetItem(itemID)
    836                     if beacon and hasattr(beacon, 'dunDescriptionID') and beacon.dunDescriptionID:
    837                         desc = localization.GetByMessageID(beacon.dunDescriptionID)
    838                         hint.append(desc)
    839             elif groupID in const.sovereigntyClaimStructuresGroups:
    840                 if session.solarsystemid:
    841                     stateName, stateTimestamp, stateDelay = sm.GetService('pwn').GetStructureState(slimItem)
    842                     hint.append(POS_STRUCTURE_STATE[stateName])
    843             elif groupID == const.groupSolarSystem:
    844                 labelPathDict = {const.groupCharacter: 'UI/Common/Groups/CountedGroupCharacter',
    845                  const.groupDecorations: 'UI/Common/Groups/CountedGroupDecorations',
    846                  const.groupConstellation: 'UI/Common/Groups/CountedGroupConstellation',
    847                  const.groupAsteroidBelt: 'UI/Common/Groups/CountedGroupAsteroidBelt',
    848                  const.groupStargate: 'UI/Common/Groups/CountedGroupStargate',
    849                  const.groupClone: 'UI/Common/Groups/CountedGroupClone',
    850                  const.groupRegion: 'UI/Common/Groups/CountedGroupRegion',
    851                  const.groupStation: 'UI/Common/Groups/CountedGroupStation',
    852                  const.groupMoon: 'UI/Common/Groups/CountedGroupMoon',
    853                  const.groupBooster: 'UI/Common/Groups/CountedGroupBooster',
    854                  const.groupFaction: 'UI/Common/Groups/CountedGroupFaction',
    855                  const.groupSolarSystem: 'UI/Common/Groups/CountedGroupSolarSystem',
    856                  const.groupAlliance: 'UI/Common/Groups/CountedGroupAlliance',
    857                  const.groupCorporation: 'UI/Common/Groups/CountedGroupCorporation',
    858                  const.groupSilo: 'UI/Common/Groups/CountedGroupSilo',
    859                  const.groupSecondarySun: 'UI/Common/Groups/CountedGroupSecondarySun'}
    860                 hint.append('<dotline>')
    861                 groups, ssData = self.GetSolarsystemHierarchy(itemID, (const.groupPlanet,))
    862                 for id, orbits in groups.iteritems():
    863                     planet = ssData[id]
    864                     hint.append((localization.GetByLabel('UI/Map/StarMap/PlanetName', planet=planet.itemID), ('OnClick', 'ShowInfo', (planet.typeID, planet.itemID))))
    865                     byGroup = {}
    866                     for orbit in orbits:
    867                         _groupID = evetypes.GetGroupID(orbit.typeID)
    868                         if _groupID not in byGroup:
    869                             byGroup[_groupID] = []
    870                         byGroup[_groupID].append(orbit)
    871 
    872                     groupEntries = []
    873                     for _groupID, orbits in byGroup.iteritems():
    874                         if _groupID not in (const.groupStation, const.groupStargate, const.groupSecondarySun):
    875                             labelName = labelPathDict.get(_groupID)
    876                             groupEntries.append(localization.GetByLabel(labelName, amount=len(orbits)))
    877 
    878                     if len(groupEntries):
    879                         hint.append(localization.formatters.FormatGenericList(groupEntries))
    880                     for station in byGroup.get(const.groupStation, []):
    881                         itemName = sm.GetService('ui').GetStationName(station.itemID)
    882                         hint.append((uix.EditStationName(itemName, usename=1), ('OnMouseEnter', 'ShowSubhint', ('GetBubbleHint', (station.itemID,
    883                             None,
    884                             station,
    885                             None,
    886                             1)))))
    887 
    888                     for stargate in byGroup.get(const.groupStargate, []):
    889                         hint.append((stargate.itemName, ('OnClick', 'ShowInfo', (stargate.typeID, stargate.itemID))))
    890 
    891                     hint.append('<dotline>')
    892 
    893                 hint = hint[:-1]
    894             elif groupID == const.groupStation:
    895                 services = []
    896                 stationInfo = sm.GetService('ui').GetStation(itemID)
    897                 for info in stationServiceConst.serviceData:
    898                     for serviceID in info.serviceIDs:
    899                         if serviceID == const.stationServiceNavyOffices and not self.facwar.CheckOwnerInFaction(stationInfo.ownerID):
    900                             continue
    901                         if serviceID == const.stationServiceSecurityOffice and not self.securityOfficeSvc.CanAccessServiceInStation(itemID):
    902                             continue
    903                         if service_in_station_operation(stationInfo.operationID, serviceID):
    904                             services.append(info.label)
    905                             break
    906 
    907                 if services:
    908                     services = localization.util.Sort(services)
    909                     hint.append('<dotline>')
    910                     hint.append((localization.GetByLabel('UI/Map/StarMap/ServicesCaption'), ('OnMouseEnter', 'ShowSubhint', (services,))))
    911                 agentsByStationID = sm.GetService('agents').GetAgentsByStationID()
    912                 agentByStation = {}
    913                 for agent in agentsByStationID[itemID]:
    914                     if agent.agentTypeID in (const.agentTypeBasicAgent, const.agentTypeResearchAgent, const.agentTypeFactionalWarfareAgent) and agent.stationID:
    915                         if agent.stationID not in agentByStation:
    916                             agentByStation[agent.stationID] = []
    917                         agentByStation[agent.stationID].append(agent)
    918 
    919                 agents = []
    920                 if itemID in agentByStation:
    921                     agentsAtStation = agentByStation[itemID]
    922                     for agent in agentsAtStation:
    923                         agentsub = []
    924                         agentsub.append(localization.GetByLabel('UI/Map/StarMap/DivisionName', divisionName=get_division_name(agent.divisionID)))
    925                         agentsub.append(localization.GetByLabel('UI/Map/StarMap/AgentLevel', agentLevel=eveformat.number_roman(min(5, agent.level), zero_text='-')))
    926                         isLimitedToFacWar = False
    927                         if agent.agentTypeID == const.agentTypeFactionalWarfareAgent and self.facwar.GetCorporationWarFactionID(agent.corporationID) != session.warfactionid:
    928                             isLimitedToFacWar = True
    929                         if agent.agentTypeID in (const.agentTypeResearchAgent,
    930                          const.agentTypeBasicAgent,
    931                          const.agentTypeEventMissionAgent,
    932                          const.agentTypeCareerAgent,
    933                          const.agentTypeFactionalWarfareAgent) and sm.GetService('standing').CanUseAgent(agent.factionID, agent.corporationID, agent.agentID, agent.level, agent.agentTypeID) and isLimitedToFacWar == False:
    934                             agentsub.append(localization.GetByLabel('UI/Map/StarMap/AvailableToYou'))
    935                         else:
    936                             agentsub.append(localization.GetByLabel('UI/Map/StarMap/NotAvailableToYou'))
    937                         agents.append((cfg.eveowners.Get(agent.agentID).name, ('OnMouseEnter', 'ShowSubhint', (agentsub,))))
    938 
    939                 if agents:
    940                     hint.append('<dotline>')
    941                     hint.append((localization.GetByLabel('UI/Map/StarMap/AgentsCaption'), ('OnMouseEnter', 'ShowSubhint', (agents,))))
    942                 myassets = sm.GetService('assets').GetAll('sysitems')
    943                 for solarsystemID, station in myassets:
    944                     if station.stationID == itemID:
    945                         hint.append('<dotline>')
    946                         hint.append((localization.GetByLabel('UI/Map/StarMap/MyAssetsCount', amount=station.itemCount), ('OnClick', 'OpenAssets', (station.stationID,))))
    947 
    948         return hint
    949 
    950     def CollapseBubbles(self, ignore = []):
    951         bracketWnd = uicore.layer.systemMapBrackets
    952         for bracket in bracketWnd.children[:]:
    953             if getattr(bracket, 'IsBracket', 0) and getattr(bracket.sr, 'bubble', None) is not None:
    954                 if bracket in ignore:
    955                     continue
    956                 bracket.sr.bubble.ClearSubs()
    957                 self._ExpandBubbleHint(bracket.sr.bubble, 0)
    958 
    959         self.expandingHint = 0
    960 
    961     def ExpandBubbleHint(self, bubble, expand = 1):
    962         if self.expandingHint:
    963             return
    964         uthread.new(self._ExpandBubbleHint, bubble, expand)
    965 
    966     def _ExpandBubbleHint(self, bubble, expand = 1):
    967         bracket = bubble.parent
    968         if not bracket:
    969             return
    970         if not expand and GetAttrs(bubble, 'sr', 'CollapseCleanup'):
    971             force = bubble.sr.CollapseCleanup(bracket)
    972         else:
    973             force = False
    974         if bubble.destroyed:
    975             return
    976         if not force and expand == bubble.expanded:
    977             return
    978         if expand:
    979             bracket.SetOrder(0)
    980             blue.pyos.synchro.Yield()
    981             self.CollapseBubbles([bracket])
    982         self.expandingHint = id(bracket)
    983         hint = self.GetBubbleHint(bracket.itemID, getattr(bracket, 'slimItem', None), bracket=bracket, extended=expand)
    984         if bubble.destroyed:
    985             return
    986         currentHint, pointer = bubble.data
    987         if hint != currentHint:
    988             bubble.ShowHint(hint, pointer)
    989         bubble.expanded = expand
    990         self.expandingHint = 0
    991 
    992     def SortBubbles(self, ignore = []):
    993         last = getattr(self, 'lastBubbleSort', None)
    994         if last and blue.os.TimeDiffInMs(last, blue.os.GetWallclockTime()) < 500:
    995             return
    996         bracketWnd = uicore.layer.systemMapBrackets
    997         order = []
    998         cameraParent = sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_SYSTEMMAP).GetCameraParent()
    999         if cameraParent is None:
   1000             return
   1001         camPos = cameraParent.translation
   1002         for bracket in bracketWnd.children:
   1003             if getattr(bracket, 'IsBracket', 0) and getattr(bracket, 'trackTransform', None) is not None and getattr(bracket.sr, 'bubble', None) is not None:
   1004                 bracketPos = geo2.Vector(*bracket.trackTransform.translation)
   1005                 order.append((geo2.Vec3LengthSq(camPos - bracketPos), bracket))
   1006 
   1007         order = SortListOfTuples(order)
   1008         order.reverse()
   1009         for bracket in order:
   1010             bracket.SetOrder(0)
   1011 
   1012         self.lastBubbleSort = blue.os.GetWallclockTime()
   1013 
   1014     def GetCurrentSolarSystem(self):
   1015         return self.currentSolarsystem
   1016 
   1017     def GetSolarsystemData(self, ssid):
   1018         self.ssitems = self.ssitems or {}
   1019         if ssid not in self.ssitems:
   1020             self.ssitems[ssid] = self.map.GetSolarsystemItems(ssid)
   1021         return self.ssitems[ssid]
   1022 
   1023     def GetSolarSystemRadius(self, solarSystemID):
   1024         solarSystemData = self.GetSolarsystemData(solarSystemID)
   1025         return max((geo2.Vec3Length((entity.x, entity.y, entity.z)) for entity in solarSystemData))
   1026 
   1027     def DrawSolarSystem(self, ssid):
   1028         ssitems = self.GetSolarsystemData(ssid)
   1029         parent = trinity.EveTransform()
   1030         parent.name = 'solarsystem_%s' % ssid
   1031         orbits = []
   1032         objects = {}
   1033         sunID = None
   1034         pm = (const.groupPlanet, const.groupMoon)
   1035         for each in ssitems:
   1036             if each.itemID == each.locationID:
   1037                 continue
   1038             groupID = evetypes.GetGroupID(each.typeID)
   1039             if groupID == const.groupSecondarySun:
   1040                 continue
   1041             transform = trinity.EveTransform()
   1042             if groupID in pm:
   1043                 parentID = self.FindCelestialParent(each, ssitems)
   1044                 orbits.append([each.itemID, parentID])
   1045             elif groupID == const.groupSun:
   1046                 sunID = each.itemID
   1047             pos = geo2.Vector(each.x, each.y, each.z)
   1048             transform.translation = pos
   1049             transform.name = str(each.itemID)
   1050             parent.children.append(transform)
   1051             objects[each.itemID] = transform
   1052 
   1053         for childID, parentID in orbits:
   1054             if childID in objects and parentID in objects:
   1055                 self.Add3DCircle(objects[childID], objects[parentID])
   1056 
   1057         cfg.evelocations.Prime(objects.keys(), 0)
   1058         self.orbitLineSet.SubmitChanges()
   1059         return (parent, sunID)
   1060 
   1061     def FindCelestialParent(self, body, ssitems):
   1062         bodyPos = geo2.Vector(body.x, body.y, body.z)
   1063         planets = []
   1064         groupID = evetypes.GetGroupID(body.typeID)
   1065         if groupID == const.groupPlanet or groupID == const.groupStargate:
   1066             for object in ssitems:
   1067                 typeinfo2 = evetypes.GetGroupID(object.typeID)
   1068                 if typeinfo2 == const.groupSun:
   1069                     return object.itemID
   1070 
   1071         for each in ssitems:
   1072             if each.itemID == body.itemID:
   1073                 continue
   1074             if evetypes.GetGroupID(each.typeID) != const.groupPlanet:
   1075                 continue
   1076             pos = geo2.Vector(each.x, each.y, each.z)
   1077             diffPos = pos - bodyPos
   1078             planets.append([geo2.Vec3Length(diffPos), each])
   1079 
   1080         planets.sort()
   1081         return planets[0][1].itemID
   1082 
   1083     def Add3DCircle(self, orbitem, parent, points = 256):
   1084         orbitPos = geo2.Vector(*orbitem.translation)
   1085         parentPos = geo2.Vector(*parent.translation)
   1086         dirVec = orbitPos - parentPos
   1087         radius = geo2.Vec3Length(dirVec)
   1088         if radius == 0:
   1089             return
   1090         fwdVec = geo2.Vector(-1.0, 0.0, 0.0)
   1091         dirVec = geo2.Vec3Normalize(dirVec)
   1092         fwdVec = geo2.Vec3Normalize(fwdVec)
   1093         color = (0.3, 0.3, 0.3, 1.0)
   1094         stepSize = pi * 2.0 / points
   1095         lineSet = self.orbitLineSet
   1096         rotation = geo2.QuaternionRotationArc(fwdVec, dirVec)
   1097         matrix = geo2.MatrixAffineTransformation(1.0, geo2.Vector(0.0, 0.0, 0.0), rotation, geo2.Vector(*parent.translation))
   1098         coordinates = []
   1099         for step in range(points):
   1100             angle = step * stepSize
   1101             x = cos(angle) * radius
   1102             z = sin(angle) * radius
   1103             pos = geo2.Vector(x, 0.0, z)
   1104             pos = geo2.Vec3TransformCoord(pos, matrix)
   1105             coordinates.append(pos)
   1106 
   1107         for start in xrange(points):
   1108             end = (start + 1) % points
   1109             lineSet.AddLine(coordinates[start], color, coordinates[end], color)
   1110 
   1111     def OnBracketDoubleClick(self, _bracket, *args):
   1112         if _bracket.itemID is not None:
   1113             sm.GetService('viewState').GetView('systemmap').layer.SetInterest(_bracket.itemID)
   1114 
   1115 
   1116 class BookmarkBracket(SimpleBracket):
   1117     __guid__ = 'xtriui.BookmarkBracket'
   1118 
   1119     def Startup(self, bookmark, showBubbleHint):
   1120         iconNo = 'ui_38_16_150'
   1121         itemID = ('bookmark', bookmark.bookmarkID)
   1122         caption, note = sm.GetService('bookmarkSvc').UnzipMemo(bookmark.memo)
   1123         self.displayName = localization.GetByLabel('UI/Map/StarMap/hintSystemBookmark', memo=caption)
   1124         self.bmData = bookmark
   1125         if showBubbleHint:
   1126             myPos = maputils.GetMyPos()
   1127             distance = (trinity.TriVector(*self.trackTransform.translation) - myPos).Length()
   1128             self.ShowBubble([localization.GetByLabel('UI/Map/StarMap/lblBoldName', name=caption), localization.GetByLabel('UI/Map/StarMap/lblDistance', distance=FmtDist(distance))])
   1129         SimpleBracket.Startup(self, itemID, None, None, iconNo)
   1130 
   1131     def GetMenu(self, *args):
   1132         bmData = getattr(self, 'bmData', None)
   1133         if bmData is None:
   1134             return
   1135         m = GetMenuService().BookmarkMenu(bookmark=bmData)
   1136         m.append((MenuLabel('UI/Map/StarMap/EditViewLocation'), sm.GetService('addressbook').EditBookmark, (bmData,)))
   1137         return m
   1138 
   1139     def OnMouseDown(self, *args):
   1140         bookMarkInfo = getattr(self, 'bmData', None)
   1141         if bookMarkInfo is None:
   1142             return
   1143         GetMenuService().TryExpandActionMenu(itemID=bookMarkInfo.itemID, clickedObject=self, bookmarkInfo=bookMarkInfo)
   1144 
   1145     def GetRadialMenuIndicator(self, create = True, *args):
   1146         radialMenuSprite = getattr(self, 'radialMenuSprite', None)
   1147         if radialMenuSprite and not radialMenuSprite.destroyed:
   1148             return radialMenuSprite
   1149         if not create:
   1150             return
   1151         radialMenuSprite = Sprite(name='radialMenuSprite', parent=self, texturePath='res:/UI/Texture/classes/RadialMenu/bracketHilite.png', pos=(0, 0, 20, 20), color=(0.5, 0.5, 0.5, 0.5), idx=-1, align=uiconst.CENTER)
   1152         self.radialMenuSprite = radialMenuSprite
   1153         return radialMenuSprite
   1154 
   1155     def ShowRadialMenuIndicator(self, slimItem, *args):
   1156         mySprite = self.GetRadialMenuIndicator(create=True)
   1157         mySprite.display = True
   1158 
   1159     def HideRadialMenuIndicator(self, slimItem, *args):
   1160         mySprite = self.GetRadialMenuIndicator(create=False)
   1161         if mySprite:
   1162             mySprite.display = False