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

starMapSvc.py (123644B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\maps\starMapSvc.py
      2 from collections import defaultdict
      3 import itertools
      4 import math
      5 from math import sin, cos, pi
      6 import sys
      7 import mathext
      8 import utillib
      9 from carbon.common.script.sys.service import Service
     10 from carbon.common.script.sys.serviceConst import ROLE_GML, SERVICE_RUNNING, SERVICE_START_PENDING
     11 from carbon.common.script.util.commonutils import StripTags
     12 from carbonui.primitives.bracket import Bracket as BracketCore
     13 from carbonui.primitives.fill import Fill
     14 from carbonui.primitives.sprite import Sprite
     15 from eve.client.script.ui.camera.starmapCamera import StarmapCamera
     16 from eve.client.script.ui.control import eveIcon, eveLabel
     17 from eve.client.script.ui.control.infoIcon import InfoIcon
     18 from eve.client.script.ui.inflight.bracket import Bracket
     19 from eve.client.script.ui.shared.mapView.analytics_util import send_set_waypoint_analytics_event
     20 from eve.client.script.ui.shared.mapView.mapViewUtil import OpenMap
     21 from eve.common.script.util.systemExclusions import IsValidDestination
     22 from eve.client.script.ui.shared.maps.label import MapLabel, TransformableLabel
     23 from eve.client.script.ui.shared.maps.route import MapRoute
     24 import evecamera
     25 import evetypes
     26 import industry
     27 from eve.common.script.sys import eveCfg, idCheckers
     28 from eve.common.script.sys.eveCfg import InShipInSpace
     29 from eve.common.script.sys.idCheckers import IsKnownSpaceSystem, IsKnownSpaceRegion, IsKnownSpaceConstellation, IsDeprecatedStation, IsTriglavianSystem
     30 import blue
     31 import telemetry
     32 from eve.client.script.ui.tooltips.tooltipUtil import RefreshTooltipForOwner
     33 import trinity
     34 from eve.client.script.ui.util import uix
     35 import uthread
     36 from eve.client.script.ui.shared.fleet import fleetbroadcastexports as fleetbr, fleetBroadcastConst
     37 from carbonui.primitives.line import Line
     38 from eve.client.script.ui.shared.maps import starModeHandler
     39 from eve.client.script.ui.shared.maps.hexMap import HexMapController
     40 from eve.client.script.ui.control.pointerPanel import RefreshPanelPosition
     41 from evePathfinder.pathfinderconst import ROUTE_TYPE_SAFE, ROUTE_TYPE_SHORTEST, ROUTE_TYPE_UNSAFE
     42 from eve.client.script.ui.shared.maps import mapcommon
     43 from eve.client.script.ui.shared.maps.mapcommon import STARMAP_SCALE, SUN_DATA, JUMP_TYPES, JUMP_COLORS, ZOOM_MAX_STARMAP, ZOOM_MIN_STARMAP, TILE_MODE_SOVEREIGNTY, TILE_MODE_STANDIGS
     44 import geo2
     45 import carbonui.const as uiconst
     46 import localization
     47 from eve.client.script.ui.shared.maps import maputils
     48 from eve.common.script.util.facwarCommon import IsAnyFWFaction
     49 from npcs.npccorporations import get_corporation_faction_id
     50 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     51 from starmap.util import SolarSystemMapInfo, ConstellationMapInfo, RegionMapInfo, MapJumpInfo, StarmapInterest, OverrideAlpha, OverrideColour, Pairwise, ScaleColour, SelectiveIndexedIterItems
     52 import time
     53 import cPickle
     54 from carbonui.uicore import uicore
     55 from eveservices.menu import GetMenuService
     56 from menu import MenuLabel
     57 SHOW_ALL_REGION_LABELS = 3
     58 SHOW_SELECTED_REGION_AND_NEIGHBOURS_LABELS = 2
     59 SHOW_SELECTED_REGION_LABEL = 1
     60 SHOW_NO_REGION_LABELS = 0
     61 SUNBASE = 7.5
     62 LINESTEP_CONSTELLATION = 20.0
     63 LINESTEP_REGION = 40.0
     64 doingDebug = 0
     65 SHOW_NONE = 0
     66 SHOW_SELECTION = 1
     67 SHOW_REGION = 2
     68 SHOW_NEIGHBORS = 3
     69 SHOW_ALL = 4
     70 PARTICLE_EFFECT = 'res:/Graphics/Effect/Managed/Space/SpecialFX/Particles/Starmap.fx'
     71 PARTICLE_SPRITE_TEXTURE = 'res:/Texture/Particle/MapSprite.dds'
     72 OVERGLOW_FACTOR = 'OverGlowFactor'
     73 DISTANCE_RANGE = 'distanceRange'
     74 DEFAULT_STAR_PARTICLE_COLOR = (0.1, 0.1, 0.1, 1.0)
     75 NEUTRAL_COLOR = (0.25, 0.25, 0.25, 1.0)
     76 PICK_RADIUS = 400.0
     77 PICK_RADIUS_NEAR = 100.0
     78 PICK_RADIUS_FAR = 400.0
     79 REGION_LABEL_SCALE = 10.0
     80 MAP_FLATTEN_ANIM_TIME = 750.0
     81 MAP_ROTATION = (0.0, math.radians(180.0), 0.0)
     82 MAP_XYZW_ROTATION = (1.0, 0.0, 0.0, 0.0)
     83 MAP_XYZW_INV_ROTATION = (-1.0, 0.0, 0.0, 0.0)
     84 HEX_TILE_SIZE = 60
     85 DEFAULT_SOLAR_SYSTEM_ID = 30005204
     86 
     87 def GetUserUiSetting(name, default):
     88     return settings.user.ui.Get(name, default)
     89 
     90 
     91 def GetCharUiSetting(name, default):
     92     return settings.char.ui.Get(name, default)
     93 
     94 
     95 def SetUserUiSetting(name, value):
     96     return settings.user.ui.Set(name, value)
     97 
     98 
     99 def SetCharUiSetting(name, value):
    100     return settings.char.ui.Set(name, value)
    101 
    102 
    103 class StarMapSvc(Service):
    104     __guid__ = 'svc.starmap'
    105     __notifyevents__ = ['OnServerMapDataPush',
    106      'OnAvoidanceItemsChanged',
    107      'OnMapReset',
    108      'OnUIScalingChange',
    109      'OnAutopilotUpdated',
    110      'OnDestinationChange',
    111      'ProcessSessionReset',
    112      'OnSessionReset',
    113      'OnCharacterSessionChanged']
    114     __servicename__ = 'starmap'
    115     __displayname__ = 'Star Map Client Service'
    116     __dependencies__ = ['clientPathfinderService',
    117      'map',
    118      'sceneManager',
    119      'viewState',
    120      'autoPilot',
    121      'loading']
    122     __startupdependencies__ = ['settings',
    123      'solarsystemInterferenceSvc',
    124      'insurgencyCampaignSvc',
    125      'corruptionSuppressionSvc']
    126     __update_on_reload__ = 0
    127 
    128     def Run(self, memStream = None):
    129         self.HINT_LOCATION_HEADERS = (localization.GetByLabel('UI/Common/LocationTypes/Region'),
    130          localization.GetByLabel('UI/Common/Constellation'),
    131          localization.GetByLabel('UI/Common/SolarSystem'),
    132          '')
    133         self.state = SERVICE_START_PENDING
    134         self.LogInfo('Starting Map Client Svc')
    135         self.changingPerspective = False
    136         self.Reset()
    137         self.state = SERVICE_RUNNING
    138         self.ClearMapCache()
    139         self.doingLogoff = False
    140 
    141     def ClearMapCache(self):
    142         self.starMapCache = None
    143         self.knownSolarSystems = None
    144         self.knownConstellations = None
    145         self.knownRegions = None
    146         self.mapJumps = None
    147         self.LogInfo('Starmap cache cleared')
    148 
    149     def Stop(self, memStream = None):
    150         if trinity.device is None:
    151             return
    152         self.LogInfo('Map svc')
    153         self.Reset()
    154 
    155     def Open(self, interestID = None, starColorMode = None, *args):
    156         OpenMap(interestID=interestID, starColorMode=starColorMode)
    157 
    158     def OnAvoidanceItemsChanged(self):
    159         if self.viewState.IsViewActive('starmap'):
    160             starColorMode = GetUserUiSetting('starscolorby', mapcommon.STARMODE_SECURITY)
    161             if starColorMode == mapcommon.STARMODE_AVOIDANCE:
    162                 self.SetStarColorMode(mapcommon.STARMODE_AVOIDANCE)
    163 
    164     def OnUIScalingChange(self, *args):
    165         viewStateSvc = self.viewState
    166         if viewStateSvc.IsViewActive('starmap'):
    167             viewStateSvc.ToggleSecondaryView('starmap')
    168             viewStateSvc.ToggleSecondaryView('starmap')
    169 
    170     def OnMapReset(self):
    171         self.Reset()
    172 
    173     def ProcessSessionReset(self):
    174         SetCharUiSetting('autopilot_waypoints', self.GetWaypoints())
    175         self.doingLogoff = True
    176 
    177     def OnSessionReset(self):
    178         self.Reset()
    179         self.doingLogoff = False
    180 
    181     def OnCharacterSessionChanged(self, oldCharacterID, newCharacterID):
    182         if oldCharacterID is None and newCharacterID is not None:
    183             self.UpdateRoute()
    184 
    185     @telemetry.ZONE_METHOD
    186     def CleanUp(self):
    187         cachedDestinationPath = self.destinationPath
    188         self.Reset()
    189         self.destinationPath = cachedDestinationPath
    190         for child in uicore.layer.starmap.children[:]:
    191             if child.name == '__cursor' or child.name == 'myloc' or child.name == 'myDest':
    192                 child.Close()
    193 
    194         scene = self.sceneManager.GetRegisteredScene('starmap')
    195         if scene:
    196             del scene.objects[:]
    197             scene.curveSets.remove(self.curveSet)
    198             self.curveSet = None
    199         self.sceneManager.UnregisterScene('starmap')
    200         self.sceneManager.UnregisterCamera(evecamera.CAM_STARMAP)
    201         self.mylocation = None
    202 
    203     @telemetry.ZONE_METHOD
    204     def Reset(self):
    205         self.LogInfo('MapSvc Reset')
    206         self.securityInfo = None
    207         self.destinationPath = [None]
    208         self.interest = None
    209         self.currentSolarsystemID = None
    210         self.currentSolarsystem = None
    211         self.solarsystemBracketsLoaded = None
    212         self.solarsystemHierarchyData = {}
    213         self.expandingHint = None
    214         rangeCircleTF = getattr(self, 'rangeCircleTF', None)
    215         if rangeCircleTF:
    216             for each in rangeCircleTF.curveSets[:]:
    217                 rangeCircleTF.curveSets.remove(each)
    218 
    219         self.rangeCircleTF = None
    220         self.rangeLineSet = None
    221         if hasattr(self, 'mapRoot') and self.mapRoot is not None:
    222             del self.mapRoot.children[:]
    223         self.mapRoot = None
    224         if hasattr(self, 'hexMap') and self.hexMap is not None:
    225             self.hexMap.tilePool = []
    226             self.hexMap = None
    227         self.particleIDToSystemIDMap = None
    228         self.solarSystemIDToParticleID = None
    229         self.currentLineColour = {}
    230         self.mapconnectionscache = None
    231         self.autoPilotRoute = None
    232         self.genericRoute = None
    233         self.genericRoutePath = None
    234         self.flattened = GetUserUiSetting('mapFlattened', 1)
    235         self.wasConnectionViewMode = None
    236         self.regionLabels = None
    237         self.regionLabelParent = None
    238         self.solarsystemsCache = None
    239         self.lineIdAndToSystemIdByFromSystemId = None
    240         self.allianceSolarSystems = {'s': {},
    241          'c': {}}
    242         self.ClearLabels()
    243         toClose = getattr(self, 'labels', {})
    244         for each in toClose.itervalues():
    245             each.Close()
    246 
    247         self.labels = {}
    248         self.labeltrackersTF = None
    249         self.landmarkTF = None
    250         self.labeltrackers = {}
    251         self.mapStars = None
    252         self.starParticles = None
    253         self.solarSystemJumpLineSet = None
    254         self.cursor = None
    255         toClose = getattr(self, 'uicursor', None)
    256         if toClose:
    257             toClose.Close()
    258         self.uicursor = None
    259         self.minimizedWindows = []
    260         self.stationCountCache = None
    261         self.warFactionByOwner = None
    262 
    263     def GetInterest(self):
    264         if self.interest is None:
    265             self.interest = StarmapInterest(session.regionid, session.constellationid, session.solarsystemid2)
    266         return self.interest
    267 
    268     def OnServerMapDataPush(self, tricolors, data):
    269         self.viewState.ActivateView('starmap')
    270         processedData = {}
    271         for systemID, blobSize, colorScale, descriptionText, overrideColor in data:
    272             if overrideColor == (None, None, None):
    273                 processedData[systemID] = (blobSize,
    274                  colorScale,
    275                  descriptionText,
    276                  None)
    277             else:
    278                 processedData[systemID] = (blobSize,
    279                  colorScale,
    280                  descriptionText,
    281                  trinity.TriColor(*overrideColor))
    282 
    283         self.HighlightSolarSystems(processedData, [ trinity.TriColor(r, g, b) for r, g, b in tricolors ])
    284 
    285     def PickSolarSystemID(self):
    286         if self.starParticles is None:
    287             return
    288         projection, view, viewport = uix.GetFullscreenProjectionViewAndViewport()
    289         x, y = int(uicore.uilib.x * uicore.desktop.dpiScaling), int(uicore.uilib.y * uicore.desktop.dpiScaling)
    290         particleID = trinity.PickParticle(self.starParticles, x, y, self.mapStars.worldTransform, view, projection, viewport, self.GetStarPickRadius())
    291         return self.particleIDToSystemIDMap.get(particleID, None)
    292 
    293     def PickParticle(self):
    294         if self.starParticles is None:
    295             return
    296         try:
    297             projection, view, viewport = uix.GetFullscreenProjectionViewAndViewport()
    298         except AttributeError:
    299             return
    300 
    301         x, y = uicore.ScaleDpi(uicore.uilib.x), uicore.ScaleDpi(uicore.uilib.y)
    302         particleID = trinity.PickParticle(self.starParticles, x, y, self.mapStars.worldTransform, view, projection, viewport, self.GetStarPickRadius())
    303         if particleID != -1:
    304             return particleID
    305         else:
    306             return
    307 
    308     def GetItemMenu(self, itemID):
    309         item = self.map.GetItem(itemID, retall=True)
    310         if not item:
    311             return []
    312         m = []
    313         itemLabel = MenuLabel('UI/Map/StarMap/ItemMenuLabel', {'loc': itemID,
    314          'item': item.typeID})
    315         m.append((itemLabel, self.SetInterest, (item.itemID,)))
    316         parentID = self.map.GetParent(item.itemID)
    317         while parentID != const.locationUniverse:
    318             parent = self.map.GetItem(parentID)
    319             if parent is not None:
    320                 parentLabel = MenuLabel('UI/Map/StarMap/ItemMenuParentLabel', {'loc': parentID,
    321                  'item': parent.typeID})
    322                 m.append((parentLabel, self.SetInterest, (parentID,)))
    323             parentID = self.map.GetParent(parentID)
    324 
    325         m.append(None)
    326         m += GetMenuService().CelestialMenu(itemID, mapItem=item)
    327         m.append(None)
    328         m.append((MenuLabel('UI/Map/StarMap/CenterOnScreen'), self.SetInterest, (itemID, 1)))
    329         return m
    330 
    331     @telemetry.ZONE_METHOD
    332     def MakeBroadcastBracket(self, gbType, itemID, charID):
    333         if gbType != 'TravelTo':
    334             raise NotImplementedError
    335         if self.mapRoot is None:
    336             return
    337         sysname = cfg.evelocations.Get(itemID).name.encode('utf-8')
    338         tracker = trinity.EveTransform()
    339         tracker.name = '__fleetbroadcast_%s' % sysname
    340         self.mapRoot.children.append(tracker)
    341         loc = self.map.GetItem(itemID)
    342         pos = (loc.x * STARMAP_SCALE, loc.y * STARMAP_SCALE, loc.z * STARMAP_SCALE)
    343         tracker.translation = pos
    344         anchor = Bracket(parent=uicore.layer.starmap, state=uiconst.UI_DISABLED, width=1, height=1, align=uiconst.NOALIGN, name='fleetBroadcastAnchor_%s' % sysname)
    345         anchor.itemID = itemID
    346         anchor.display = True
    347         anchor.trackTransform = tracker
    348         iconPath = fleetBroadcastConst.iconsLargeByBroadcastType[fleetBroadcastConst.BROADCAST_TRAVEL_TO]
    349         icon = eveIcon.Icon(icon=iconPath, parent=anchor, idx=0, pos=(0, 0, 32, 32), align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL)
    350         icon.name = 'fleetBroadcastIcon_%s' % sysname
    351         icon.hint = fleetbr.GetCaption_TravelTo(charID, itemID, itemID)
    352         icon.GetMenu = fleetbr.MenuGetter('TravelTo', charID, itemID)
    353 
    354         def Cleanup(*args):
    355             try:
    356                 self.mapRoot.children.fremove(tracker)
    357             except (AttributeError, ValueError):
    358                 sys.exc_clear()
    359 
    360         icon.OnClose = Cleanup
    361         return anchor
    362 
    363     def GetCloudNumFromItemID(self, itemID):
    364         if itemID in self.solarSystemIDToParticleID:
    365             return self.solarSystemIDToParticleID[itemID]
    366 
    367     def GetItemIDFromParticleID(self, particleID):
    368         solarSystemID = None
    369         if self.particleIDToSystemIDMap:
    370             solarSystemID = self.particleIDToSystemIDMap[particleID]
    371         return solarSystemID
    372 
    373     @telemetry.ZONE_METHOD
    374     def UpdateHint(self, nav = None):
    375         if getattr(self, 'doinghint', 0):
    376             return
    377         self.doinghint = 1
    378         if self.starParticles is None:
    379             self.doinghint = 0
    380             return
    381         projection, view, viewport = uix.GetFullscreenProjectionViewAndViewport()
    382         x, y = uicore.ScaleDpi(uicore.uilib.x), uicore.ScaleDpi(uicore.uilib.y)
    383         particleID = trinity.PickParticle(self.starParticles, x, y, self.mapStars.worldTransform, view, projection, viewport, self.GetStarPickRadius())
    384         if getattr(self, 'lastpick', None) == particleID:
    385             self.doinghint = 0
    386             return
    387         hint = ''
    388         if particleID in self.particleIDToSystemIDMap:
    389             itemID = self.particleIDToSystemIDMap[particleID]
    390             item = self.map.GetItem(itemID)
    391             hint = item.itemName
    392             hierarchy = self.map.GetParentLocationID(itemID)
    393             if hierarchy:
    394                 locs = []
    395                 for locationID in hierarchy[1:]:
    396                     if locationID is not None:
    397                         if locationID not in locs:
    398                             locs.append(locationID)
    399 
    400                 if len(locs):
    401                     cfg.evelocations.Prime(locs)
    402                 hintParts = []
    403                 for i, locationID in enumerate(hierarchy[1:]):
    404                     if locationID is not None:
    405                         hintParts.appen('%s %s' % (cfg.evelocations.Get(locationID).name, self.HINT_LOCATION_HEADERS[i]))
    406 
    407                 hint = ' - '.join(hintParts)
    408         self.lastpick = particleID
    409         if nav:
    410             nav.hint = hint
    411         self.doinghint = 0
    412 
    413     def RemoveChild(self, tf, childname):
    414         for each in tf.children[:]:
    415             if each.name == childname:
    416                 tf.children.remove(each)
    417 
    418     @telemetry.ZONE_METHOD
    419     def ShowJumpDriveRange(self):
    420         if getattr(self, 'mylocation', None):
    421             for each in self.mylocation.trackerTransform.children[:]:
    422                 if each.name == 'jumpDriveRange':
    423                     self.mylocation.trackerTransform.children.remove(each)
    424 
    425         else:
    426             return
    427         if not IsKnownSpaceRegion(session.regionid):
    428             return
    429         if not InShipInSpace():
    430             return
    431         shipID = eveCfg.GetActiveShip()
    432         dogmaLM = sm.GetService('clientDogmaIM').GetDogmaLocation()
    433         driveRange = dogmaLM.GetAttributeValue(shipID, const.attributeJumpDriveRange)
    434         if driveRange is None or driveRange == 0:
    435             return
    436         scale = 2.0 * driveRange * const.LIGHTYEAR * STARMAP_SCALE
    437         sphere = trinity.Load('res:/dx9/model/UI/JumpRangeBubble.red')
    438         sphere.scaling = (scale, scale, scale)
    439         sphere.name = 'jumpDriveRange'
    440         if self.IsFlat():
    441             sphere.display = False
    442         self.mylocation.trackerTransform.children.append(sphere)
    443 
    444     def RemoveMyLocation(self):
    445         self.RemoveChild(self.mapRoot, '__mylocation')
    446         if getattr(self, 'mylocationBracket', None):
    447             self.mylocationBracket.Close()
    448             self.mylocationBracket = None
    449             self.mylocation = None
    450 
    451     @telemetry.ZONE_METHOD
    452     def ShowWhereIAm(self):
    453         if self.mapRoot is None:
    454             return
    455         if not IsValidDestination(session.regionid):
    456             return
    457         if not IsKnownSpaceRegion(session.regionid):
    458             self.RemoveMyLocation()
    459         else:
    460             locationid = session.solarsystemid2
    461             if getattr(self, 'mylocation', None) is None:
    462                 self.RemoveMyLocation()
    463                 tracker = trinity.EveTransform()
    464                 tracker.name = '__mylocation'
    465                 self.mapRoot.children.append(tracker)
    466                 label = self.GetCurrLocationBracket()
    467                 label.Startup('myloc', locationid, None, tracker, None, 1)
    468                 label.clipChildren = False
    469                 labeltext = eveLabel.EveHeaderSmall(text=localization.GetByLabel('UI/Map/StarMap/lblYouAreHere'), parent=label, left=210, align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, idx=0)
    470                 sm.GetService('ui').BlinkSpriteA(labeltext, 1.0, 750, None, passColor=0, minA=0.5)
    471                 self.labeltext = labeltext
    472                 self.mylocationBracket = label
    473             else:
    474                 tracker = self.mylocation.trackerTransform
    475             pos = self.knownSolarSystems[locationid].scaledCenter
    476             tracker.translation = pos
    477             bp = sm.GetService('michelle').GetBallpark()
    478             if bp is not None:
    479                 ship = bp.GetBall(session.shipid)
    480                 if ship is not None:
    481                     shipPos = geo2.Vector(ship.x, ship.y, ship.z)
    482                     shipPos *= STARMAP_SCALE
    483                     pos += shipPos
    484                     tracker.translation = pos
    485             self.mylocation = utillib.KeyVal(locationID=locationid, trackerTransform=tracker)
    486         self.ShowDestination()
    487         self.ShowJumpDriveRange()
    488 
    489     @telemetry.ZONE_METHOD
    490     def ShowDestination(self):
    491         if not self.viewState.IsViewActive('starmap'):
    492             return
    493         waypoints = self.GetWaypoints()
    494         self.mydestination = getattr(self, 'mydestination', [])
    495         if len(self.mydestination) == 0:
    496             if len(waypoints) == 0:
    497                 return
    498         else:
    499             for waypoint in self.mydestination:
    500                 waypoint.label.Close()
    501                 self.mapRoot.children.fremove(waypoint.tracker)
    502 
    503         self.mydestination = []
    504         lastWaypoint = session.solarsystemid2
    505         totalJumps = 0
    506         if len(waypoints) > 0:
    507             currentExtractWaypoint = waypoints[0]
    508             waypointIndex = 0
    509             waypointDestinationList = []
    510             currentDestinationList = [lastWaypoint]
    511             for locationID in self.destinationPath:
    512                 currentDestinationList.append(locationID)
    513                 if locationID == currentExtractWaypoint:
    514                     waypointDestinationList.append(currentDestinationList)
    515                     currentDestinationList = [locationID]
    516                     waypointIndex += 1
    517                     if waypointIndex == len(waypoints):
    518                         break
    519                     currentExtractWaypoint = waypoints[waypointIndex]
    520 
    521         else:
    522             waypointDestinationList = []
    523         waypointLabels = {}
    524         for waypointIndex, waypointID in enumerate(waypoints):
    525             destinations = []
    526             if waypointIndex < len(waypointDestinationList):
    527                 for destination in waypointDestinationList[waypointIndex]:
    528                     if idCheckers.IsSolarSystem(destination):
    529                         destinations.append(destination)
    530 
    531             targetItemName = cfg.evelocations.Get(waypointID).locationName
    532             wpIdx = waypointIndex + 1
    533             if not len(destinations):
    534                 wpLabel = localization.GetByLabel('UI/Map/StarMap/ShowDestinationWaypointUnreachable', waypointNumber=wpIdx, targetName=targetItemName)
    535             else:
    536                 totalJumps = totalJumps + len(destinations) - 1
    537                 wpLabel = localization.GetByLabel('UI/Map/StarMap/ShowDestinationWaypoint', waypointNumber=wpIdx, targetName=targetItemName, jumps=totalJumps)
    538             tracker = trinity.EveTransform()
    539             tracker.name = '__waypoint_%d' % waypointIndex
    540             if self.mapRoot:
    541                 self.mapRoot.children.append(tracker)
    542             label = self.GetCurrLocationBracket()
    543             label.Startup('myDest', waypointID, const.groupSolarSystem, tracker, None, 1)
    544             label.clipChildren = False
    545             if idCheckers.IsStation(waypointID):
    546                 waypointID = cfg.stations.Get(waypointID).solarSystemID
    547             if waypointID in waypointLabels:
    548                 labeltext = waypointLabels[waypointID]
    549                 labeltext.text += '\n%s' % wpLabel
    550             else:
    551                 labeltext = eveLabel.EveHeaderSmall(text=wpLabel, parent=label, left=210, top=5, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, idx=0)
    552                 waypointLabels[waypointID] = labeltext
    553             if waypointID == session.solarsystemid2:
    554                 labeltext.top = 20
    555             labeltext.SetRGB(1.0, 1.0, 0.0)
    556             sm.GetService('ui').BlinkSpriteA(labeltext, 1.0, 750, None, passColor=0, minA=0.5)
    557             location = cfg.evelocations.Get(waypointID)
    558             pos = (location.x * STARMAP_SCALE, location.y * STARMAP_SCALE, location.z * STARMAP_SCALE)
    559             tracker.translation = pos
    560             self.mydestination.append(utillib.KeyVal(waypointID=waypointID, tracker=tracker, label=label))
    561             label.state = uiconst.UI_DISABLED
    562 
    563     def GetCurrLocationBracket(self):
    564         currentLocation = MapLabel(parent=uicore.layer.starmap, name='currentlocation', pos=(0, 0, 280, 20), align=uiconst.NOALIGN, state=uiconst.UI_PICKCHILDREN, dock=False)
    565         Fill(parent=currentLocation, name='white', pos=(154, 11, 48, 1), state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.25), align=uiconst.TOPLEFT)
    566         Sprite(parent=currentLocation, name='frame', pos=(0, 0, 32, 32), align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/StarMapSvc/currentLocation.png')
    567         return currentLocation
    568 
    569     def IsFlat(self):
    570         return self.flattened
    571 
    572     @telemetry.ZONE_METHOD
    573     def Unflatten(self):
    574         registeredScene = self.sceneManager.GetRegisteredScene('starmap')
    575         if not self.flattened or registeredScene is None:
    576             return
    577         try:
    578             uicore.desktop.state = uiconst.UI_DISABLED
    579             start = blue.os.GetSimTime()
    580             cameraParent = self.GetCameraParent()
    581             current = self.mapRoot.rotationCurve.curve.GetQuaternionAt(start)
    582             key = list(self.mapRoot.rotationCurve.curve.keys[0])
    583             key[1] = (current.x,
    584              current.y,
    585              current.z,
    586              current.w)
    587             self.mapRoot.rotationCurve.curve.keys[0] = tuple(key)
    588             key = list(self.mapRoot.rotationCurve.curve.keys[1])
    589             key[0] = 1
    590             key[1] = MAP_XYZW_ROTATION
    591             self.mapRoot.rotationCurve.curve.keys[1] = tuple(key)
    592             self.mapRoot.rotationCurve.curve.OnKeysChanged()
    593             self.mapRoot.rotationCurve.ResetStart()
    594             redrawRoute = False
    595             if self.autoPilotRoute or self.genericRoute:
    596                 redrawRoute = True
    597                 self.ClearRoute('autoPilotRoute')
    598             redrawGenericRoute = False
    599             if self.genericRoute:
    600                 redrawGenericRoute = True
    601                 self.ClearRoute('genericRoute')
    602             if self.rollCamera:
    603                 self.rollCamera = False
    604                 self.starmapCamera.OrbitParent(0.0, 10.0)
    605             self.UpdateHexMap(isFlat=False)
    606             if getattr(self, 'mylocation', None):
    607                 for each in self.mylocation.trackerTransform.children[:]:
    608                     if each.name == 'jumpDriveRange':
    609                         each.display = True
    610 
    611             posEnd = self.interestEndPos
    612             posBegin = cameraParent.translation
    613             self.regionLabelParent.display = False
    614             ndt = 0.0
    615             while ndt != 1.0:
    616                 ndt = max(0.0, min(blue.os.TimeDiffInMs(start, blue.os.GetSimTime()) / 1000.0, 1.0))
    617                 self.mapRoot.scaling = self.solarSystemJumpLineSet.scaling = (1.0, mathext.lerp(0.0001, 1.0, ndt), 1.0)
    618                 if posBegin and posEnd:
    619                     pos = geo2.Vec3Lerp(posBegin, posEnd, ndt)
    620                     cameraParent.translation = pos
    621                 lineSet = self.solarSystemJumpLineSet
    622                 for lineID, curveInfo in self.curvedLineInfoByLineID.iteritems():
    623                     midPos, offsetVec = curveInfo
    624                     scaledOffset = geo2.Vec3Scale(offsetVec, ndt)
    625                     lineSet.ChangeLineIntermediateCrt(lineID, geo2.Vec3Add(midPos, scaledOffset))
    626 
    627                 lineSet.SubmitChanges()
    628                 blue.pyos.synchro.Yield()
    629 
    630             for labelTransform in self.regionLabelParent.children:
    631                 x, y, z = labelTransform.scaling
    632                 labelTransform.scaling = (x, y * 0.0001, z)
    633 
    634             if GetUserUiSetting('rlabel_region', 1):
    635                 self.regionLabelParent.display = True
    636             self.flattened = 0
    637             SetUserUiSetting('mapFlattened', self.flattened)
    638             sm.ScatterEvent('OnFlattenModeChanged', self.flattened)
    639             if redrawRoute:
    640                 self.UpdateRoute()
    641             if redrawGenericRoute and self.genericRoutePath:
    642                 self.DrawRouteTo(targetID=self.genericRoutePath[-1], sourceID=self.genericRoutePath[0])
    643             self.OnCameraMoved()
    644         finally:
    645             uicore.desktop.state = uiconst.UI_NORMAL
    646 
    647     def GetCameraParent(self):
    648         return sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_STARMAP).GetCameraParent()
    649 
    650     @telemetry.ZONE_METHOD
    651     def Flatten(self, initing = False):
    652         if not initing:
    653             registeredScene = self.sceneManager.GetRegisteredScene('starmap')
    654             if self.flattened or registeredScene is None:
    655                 return
    656         try:
    657             uicore.desktop.state = uiconst.UI_DISABLED
    658             if initing:
    659                 duration = 0.0001
    660             else:
    661                 duration = 1.0
    662             start = blue.os.GetSimTime()
    663             cameraParent = self.GetCameraParent()
    664             camera = self.sceneManager.GetRegisteredCamera(evecamera.CAM_STARMAP)
    665             cY, cP, cR = geo2.QuaternionRotationGetYawPitchRoll(camera.rotationAroundParent)
    666             current = self.mapRoot.rotationCurve.GetQuaternionAt(start)
    667             key = list(self.mapRoot.rotationCurve.curve.keys[0])
    668             key[1] = (current.x,
    669              current.y,
    670              current.z,
    671              current.w)
    672             self.mapRoot.rotationCurve.curve.keys[0] = tuple(key)
    673             key = list(self.mapRoot.rotationCurve.curve.keys[1])
    674             key[0] = duration
    675             key[1] = geo2.QuaternionRotationSetYawPitchRoll(cY, cP - pi * 0.5, cR)
    676             self.mapRoot.rotationCurve.curve.keys[1] = tuple(key)
    677             self.mapRoot.rotationCurve.curve.OnKeysChanged()
    678             self.mapRoot.rotationCurve.ResetStart()
    679             redrawRoute = False
    680             if self.autoPilotRoute or self.genericRoute:
    681                 redrawRoute = True
    682                 self.ClearRoute('autoPilotRoute')
    683             redrawGenericRoute = False
    684             if self.genericRoute:
    685                 redrawGenericRoute = True
    686                 self.ClearRoute('genericRoute')
    687             curveQuat = geo2.QuaternionRotationSetYawPitchRoll(cY, cP - pi * 0.5, cR)
    688             camPos = cameraParent.translation
    689             posBegin = geo2.Vector(*camPos)
    690             reverseQuat = MAP_XYZW_INV_ROTATION
    691             localCam = geo2.QuaternionTransformVector(reverseQuat, posBegin)
    692             localCam = geo2.Vector(*localCam)
    693             localCam.y = 0.0
    694             posEnd = geo2.QuaternionTransformVector(curveQuat, localCam)
    695             self.regionLabelParent.display = False
    696             ndt = 0.0
    697             while ndt != 1.0:
    698                 ndt = max(0.0, min(blue.os.TimeDiffInMs(start, blue.os.GetSimTime()) / (duration * 1000.0), 1.0))
    699                 self.mapRoot.scaling = self.solarSystemJumpLineSet.scaling = (1.0, mathext.lerp(1.0, 0.0001, ndt), 1.0)
    700                 if posBegin and posEnd:
    701                     pos = geo2.Vec3Lerp(posBegin, posEnd, ndt)
    702                     cameraParent.translation = pos
    703                 lineSet = self.solarSystemJumpLineSet
    704                 for lineID, curveInfo in self.curvedLineInfoByLineID.iteritems():
    705                     midPos, offsetVec = curveInfo
    706                     scaledOffset = geo2.Vec3Scale(offsetVec, 1.0 - ndt)
    707                     lineSet.ChangeLineIntermediateCrt(lineID, geo2.Vec3Add(midPos, scaledOffset))
    708 
    709                 lineSet.SubmitChanges()
    710                 blue.pyos.synchro.Yield()
    711 
    712             for labelTransform in self.regionLabelParent.children:
    713                 x, y, z = labelTransform.scaling
    714                 labelTransform.scaling = (x, y * 10000.0, z)
    715 
    716             self.hexMap.Enable(True)
    717             if getattr(self, 'mylocation', None):
    718                 for each in self.mylocation.trackerTransform.children[:]:
    719                     if each.name == 'jumpDriveRange':
    720                         each.display = False
    721 
    722             if GetUserUiSetting('rlabel_region', 1):
    723                 self.regionLabelParent.display = True
    724             self.flattened = 1
    725             SetUserUiSetting('mapFlattened', self.flattened)
    726             self.UpdateHexMap(isFlat=True)
    727             sm.ScatterEvent('OnFlattenModeChanged', self.flattened)
    728             if redrawRoute:
    729                 self.UpdateRoute()
    730             if redrawGenericRoute and self.genericRoutePath:
    731                 self.DrawRouteTo(targetID=self.genericRoutePath[-1], sourceID=self.genericRoutePath[0])
    732             self.OnCameraMoved()
    733         finally:
    734             uicore.desktop.state = uiconst.UI_NORMAL
    735 
    736     def ToggleFlattenMode(self):
    737         if not self.changingPerspective:
    738             try:
    739                 self.changingPerspective = True
    740                 flattened = GetUserUiSetting('mapFlattened', 1)
    741                 if flattened:
    742                     self.Unflatten()
    743                 else:
    744                     self.Flatten()
    745             finally:
    746                 self.changingPerspective = False
    747 
    748     @telemetry.ZONE_METHOD
    749     def DrawPoints(self, parent):
    750         self.mapStars = trinity.EveTransform()
    751         self.mapStars.name = '__mapStars'
    752         tex = trinity.TriTextureParameter()
    753         tex.name = 'TexMap'
    754         tex.resourcePath = PARTICLE_SPRITE_TEXTURE
    755         overglowFactor = trinity.Tr2FloatParameter()
    756         overglowFactor.name = OVERGLOW_FACTOR
    757         overglowFactor.value = 0.0
    758         self.overglowFactor = overglowFactor
    759         distanceRangeStars = trinity.Tr2Vector4Parameter()
    760         distanceRangeStars.name = DISTANCE_RANGE
    761         distanceRangeStars.value = (0, 1, 0, 0)
    762         self.distanceRangeStars = distanceRangeStars
    763         self.starParticles = trinity.Tr2RuntimeInstanceData()
    764         self.starParticles.SetElementLayout([(trinity.PARTICLE_ELEMENT_TYPE.POSITION, 0, 3), (trinity.PARTICLE_ELEMENT_TYPE.CUSTOM, 0, 1), (trinity.PARTICLE_ELEMENT_TYPE.CUSTOM, 1, 4)])
    765         mesh = trinity.Tr2InstancedMesh()
    766         mesh.geometryResPath = 'res:/Graphics/Generic/UnitPlane/UnitPlane.gr2'
    767         mesh.instanceGeometryResource = self.starParticles
    768         area = trinity.Tr2MeshArea()
    769         area.effect = trinity.Tr2Effect()
    770         area.effect.effectFilePath = PARTICLE_EFFECT
    771         area.effect.resources.append(tex)
    772         area.effect.parameters.append(overglowFactor)
    773         area.effect.parameters.append(distanceRangeStars)
    774         mesh.additiveAreas.append(area)
    775         self.mapStars.mesh = mesh
    776         distanceRangeLines = trinity.Tr2Vector4Parameter()
    777         distanceRangeLines.name = DISTANCE_RANGE
    778         distanceRangeLines.value = (0, 1, 0, 0)
    779         self.distanceRangeLines = distanceRangeLines
    780         self.solarSystemJumpLineSet.lineEffect.parameters.append(self.distanceRangeLines)
    781         self.particleIDToSystemIDMap = {}
    782         self.solarSystemIDToParticleID = {}
    783         self.particleColors = []
    784         particleCounter = itertools.count()
    785         starParticleData = []
    786         for systemID, system in self.GetKnownUniverseSolarSystems().iteritems():
    787             particleID = particleCounter.next()
    788             self.solarSystemIDToParticleID[systemID] = particleID
    789             self.particleIDToSystemIDMap[particleID] = systemID
    790             self.particleColors.append(list(system.star.color))
    791             starParticleData.append((system.scaledCenter, SUNBASE, system.star.color))
    792 
    793         self.starParticles.SetData(starParticleData)
    794         self.starParticles.UpdateBoundingBox()
    795         mesh.minBounds = self.starParticles.aabbMin
    796         mesh.maxBounds = self.starParticles.aabbMax
    797         parent.children.append(self.mapStars)
    798 
    799     @telemetry.ZONE_METHOD
    800     def GetStarMapCache(self):
    801         if self.starMapCache is None:
    802             res = blue.ResFile()
    803             starMapResPath = 'res:/staticdata/starMapCache.pickle'
    804             if not res.open('%s' % starMapResPath):
    805                 self.LogError('Could not load Starmap Cache data file: %s' % starMapResPath)
    806             else:
    807                 try:
    808                     pickleData = res.Read()
    809                     self.starMapCache = cPickle.loads(pickleData)
    810                 finally:
    811                     res.Close()
    812 
    813         return self.starMapCache
    814 
    815     @telemetry.ZONE_METHOD
    816     def GetKnownUniverseSolarSystems(self):
    817         if self.knownSolarSystems is None:
    818             self.knownSolarSystems = {}
    819             for systemID, system in self.GetStarMapCache()['solarSystems'].iteritems():
    820                 if not IsKnownSpaceSystem(systemID):
    821                     continue
    822                 if not IsValidDestination(systemID):
    823                     continue
    824                 center = system['center']
    825                 scaledCenter = geo2.Scale(geo2.Vector(*center), STARMAP_SCALE)
    826                 solarSystemInfo = SolarSystemMapInfo()
    827                 solarSystemInfo.center = center
    828                 solarSystemInfo.scaledCenter = scaledCenter
    829                 solarSystemInfo.regionID = system['regionID']
    830                 solarSystemInfo.constellationID = system['constellationID']
    831                 solarSystemInfo.star = SUN_DATA[system['sunTypeID']]
    832                 solarSystemInfo.factionID = system['factionID']
    833                 solarSystemInfo.neighbours = system['neighbours']
    834                 solarSystemInfo.planetCountByType = system['planetCountByType']
    835                 solarSystemInfo.planetItemIDs = system['planetItemIDs']
    836                 self.knownSolarSystems[systemID] = solarSystemInfo
    837 
    838         return self.knownSolarSystems
    839 
    840     @telemetry.ZONE_METHOD
    841     def GetKnownUniverseRegions(self):
    842         if self.knownRegions is None:
    843             self.knownRegions = {}
    844             for regionID, region in self.GetStarMapCache()['regions'].iteritems():
    845                 if not IsKnownSpaceRegion(regionID):
    846                     continue
    847                 if not IsValidDestination(regionID):
    848                     continue
    849                 regionInfo = RegionMapInfo()
    850                 regionInfo.neighbours = region['neighbours']
    851                 regionInfo.solarSystemIDs = region['solarSystemIDs']
    852                 regionInfo.constellationIDs = region['constellationIDs']
    853                 regionInfo.scaledCenter = geo2.Scale(geo2.Vector(*region['center']), STARMAP_SCALE)
    854                 self.knownRegions[regionID] = regionInfo
    855 
    856         return self.knownRegions
    857 
    858     @telemetry.ZONE_METHOD
    859     def GetKnownUniverseConstellations(self):
    860         if self.knownConstellations is None:
    861             self.knownConstellations = {}
    862             for constellationID, constellation in self.GetStarMapCache()['constellations'].iteritems():
    863                 if not IsKnownSpaceConstellation(constellationID):
    864                     continue
    865                 if not IsValidDestination(constellationID):
    866                     continue
    867                 constellationInfo = ConstellationMapInfo()
    868                 constellationInfo.regionID = constellation['regionID']
    869                 constellationInfo.neighbours = constellation['neighbours']
    870                 constellationInfo.solarSystemIDs = constellation['solarSystemIDs']
    871                 constellationInfo.scaledCenter = geo2.Scale(geo2.Vector(*constellation['center']), STARMAP_SCALE)
    872                 self.knownConstellations[constellationID] = constellationInfo
    873 
    874         return self.knownConstellations
    875 
    876     @telemetry.ZONE_METHOD
    877     def IterateJumps(self):
    878         if self.mapJumps is None:
    879             self.mapJumps = []
    880             for jump in self.GetStarMapCache()['jumps']:
    881                 fromSystemID = jump['fromSystemID']
    882                 toSystemID = jump['toSystemID']
    883                 if not (IsValidDestination(fromSystemID) and IsValidDestination(toSystemID)):
    884                     continue
    885                 fromSystem = self.GetKnownSolarSystem(fromSystemID)
    886                 toSystem = self.GetKnownSolarSystem(toSystemID)
    887                 fromToDirection = geo2.Scale(geo2.Vector(*geo2.Vec3Normalize(geo2.Vec3Subtract(fromSystem.scaledCenter, toSystem.scaledCenter))), 8.0)
    888                 jumpInfo = MapJumpInfo()
    889                 jumpInfo.jumpType = jump['jumpType']
    890                 jumpInfo.fromSystemID = fromSystemID
    891                 jumpInfo.toSystemID = toSystemID
    892                 jumpInfo.adjustedFromVector = geo2.Vec3Add(fromSystem.scaledCenter, fromToDirection)
    893                 jumpInfo.adjustedToVector = geo2.Vec3Subtract(toSystem.scaledCenter, fromToDirection)
    894                 self.mapJumps.append(jumpInfo)
    895                 yield jumpInfo
    896 
    897         else:
    898             for jump in self.mapJumps:
    899                 yield jump
    900 
    901     def GetKnownSolarSystem(self, solarSystemID):
    902         return self.GetKnownUniverseSolarSystems().get(solarSystemID)
    903 
    904     def GetKnownConstellation(self, constellationID):
    905         return self.GetKnownUniverseConstellations().get(constellationID)
    906 
    907     def GetKnownRegion(self, regionID):
    908         return self.GetKnownUniverseRegions().get(regionID)
    909 
    910     def CreateHexmap(self):
    911         hexMapRoot = trinity.EveTransform()
    912         hexMapRoot.name = '__hexMapRoot'
    913         hexMapRoot.translation = (0.0, 20000.0, 0.0)
    914         self.hexMap = HexMapController(hexMapRoot, self.GetKnownUniverseSolarSystems().iteritems())
    915         self.mapRoot.children.append(hexMapRoot)
    916 
    917     def CreateCursor(self):
    918         self.cursor = trinity.EveTransform()
    919         self.cursor.name = '__cursorTF'
    920         self.mapRoot.children.append(self.cursor)
    921         self.uicursor = BracketCore(parent=uicore.layer.starmap, align=uiconst.NOALIGN)
    922         self.uicursor.name = '__cursor'
    923         self.uicursor.width = uicore.uilib.desktop.width * 2
    924         self.uicursor.height = uicore.uilib.desktop.height * 2
    925         self.uicursor.state = uiconst.UI_HIDDEN
    926         self.uicursor.solarsystemID = None
    927         icon = eveIcon.Icon(icon='ui_38_16_255', parent=self.uicursor, pos=(0, 0, 16, 16), align=uiconst.CENTER, state=uiconst.UI_DISABLED, pickRadius=5, idx=0)
    928         self.uicursor.icon = icon
    929         icon.state = uiconst.UI_NORMAL
    930         icon.DelegateEvents(uicore.layer.starmap)
    931         icon.LoadTooltipPanel = self.LoadSolarSystemTooltipPanel
    932         self.uicursor.trackTransform = self.cursor
    933         self.uicursor.dock = False
    934 
    935     def LoadSolarSystemTooltipPanel(self, tooltipPanel, *args):
    936         tooltipPanel.LoadGeneric2ColumnTemplate()
    937         tooltipPanel.state = uiconst.UI_NORMAL
    938         mapSvc = sm.GetService('map')
    939         starmapSvc = sm.GetService('starmap')
    940         particleID = self.uicursor.particleID
    941         itemID = self.uicursor.solarsystemID
    942         mapData = mapSvc.GetItem(itemID)
    943         if mapData is None:
    944             return
    945         securityColor = mapSvc.GetSystemColor(itemID)
    946         typeID = None
    947         groupID = None
    948         if mapData:
    949             displayName = mapData.itemName
    950             typeID = mapData.typeID
    951             groupID = evetypes.GetGroupID(mapData.typeID)
    952         if groupID is None:
    953             return
    954         tooltipPanel.AddLabelLarge(text=displayName, bold=True)
    955         tooltipPanel.AddCell(cellObject=InfoIcon(typeID=typeID, itemID=itemID, align=uiconst.TOPRIGHT, left=-3))
    956         tooltipPanel.state = uiconst.UI_NORMAL
    957         securityStatus = mapSvc.GetSecurityStatus(itemID)
    958         if securityStatus is not None:
    959             securityIconText = sm.GetService('securitySvc').get_security_modifier_icon_text(itemID)
    960             tooltipPanel.AddLabelMedium(text=localization.GetByLabel('Tooltips/Map/SecurityStatus'))
    961             securityStatusText = str(securityStatus) + securityIconText
    962             tooltipPanel.AddLabelMedium(text=securityStatusText, align=uiconst.CENTERRIGHT, color=securityColor, cellPadding=(10, 0, 0, 0), state=uiconst.UI_NORMAL)
    963         data = starmapSvc.GetStarData()
    964         if particleID in data:
    965             hintFunc, hintArgs = data[particleID]
    966             particleHint = hintFunc(*hintArgs)
    967             if particleHint:
    968                 tooltipPanel.AddCell(Line(align=uiconst.TOTOP, color=(1, 1, 1, 0.2)), colSpan=tooltipPanel.columns, cellPadding=(-11, 3, -11, 3))
    969                 starColorModeLabel = maputils.GetActiveStarColorModeLabel()
    970                 if starColorModeLabel:
    971                     tooltipPanel.AddLabelMedium(text=starColorModeLabel, bold=True, colSpan=tooltipPanel.columns)
    972                 if isinstance(particleHint, (list, tuple)):
    973                     for each in particleHint:
    974                         tooltipPanel.AddLabelSmall(text=each, state=uiconst.UI_NORMAL, colSpan=tooltipPanel.columns)
    975 
    976                 else:
    977                     tooltipPanel.AddLabelSmall(text=particleHint, state=uiconst.UI_NORMAL, colSpan=tooltipPanel.columns)
    978         uthread.new(self.UpdateTooltipPosition, tooltipPanel)
    979 
    980     def UpdateTooltipPosition(self, tooltipPanel):
    981         while not tooltipPanel.destroyed:
    982             RefreshPanelPosition(tooltipPanel)
    983             blue.synchro.Yield()
    984 
    985     def CreateJumpLineSet(self, scene):
    986         lineSet = self.map.CreateCurvedLineSet(effectPath=mapcommon.LINESET_3D_EFFECT_STARMAP)
    987         transform = trinity.EveTransform()
    988         curveBinding = trinity.TriValueBinding()
    989         curveBinding.sourceObject = self.mapRoot.rotationCurve
    990         curveBinding.sourceAttribute = 'currentValue'
    991         curveBinding.destinationObject = transform
    992         curveBinding.destinationAttribute = 'rotation'
    993         curveSet = trinity.TriCurveSet()
    994         curveSet.bindings.append(curveBinding)
    995         scene.curveSets.append(curveSet)
    996         self.curveSet = curveSet
    997         curveSet.Play()
    998         transform.children.append(lineSet)
    999         scene.objects.append(transform)
   1000         self.solarSystemJumpLineSet = lineSet
   1001 
   1002     def CreateScene(self):
   1003         scene = trinity.EveSpaceScene()
   1004         self.mapRoot = trinity.EveRootTransform()
   1005         self.mapRoot.name = 'universe'
   1006         self.mapRoot.display = True
   1007         initialRotation = geo2.QuaternionRotationSetYawPitchRoll(*MAP_ROTATION)
   1008         rotationCurve = trinity.Tr2CurveQuaternion()
   1009         rotationCurve.AddKey(0, initialRotation)
   1010         rotationCurve.AddKey(1, initialRotation)
   1011         self.mapRoot.rotationCurve = trinity.Tr2RotationAdapter()
   1012         self.mapRoot.rotationCurve.curve = rotationCurve
   1013         scene.objects.append(self.mapRoot)
   1014         return scene
   1015 
   1016     def CreateCamera(self):
   1017         self.starmapCamera = camera = StarmapCamera()
   1018         camera.idleMove = 0
   1019         camera.friction = 10.0
   1020         camera.translationFromParent = GetUserUiSetting('starmapTFP', 0.6 * ZOOM_MAX_STARMAP)
   1021         if camera.translationFromParent < 0:
   1022             camera.translationFromParent = -camera.translationFromParent
   1023         if not self.IsFlat():
   1024             camera.OrbitParent(0.0, 20.0)
   1025         return camera
   1026 
   1027     def CreateLandmarkRoot(self):
   1028         landmarkTF = trinity.EveTransform()
   1029         landmarkTF.name = '__landmarkTF'
   1030         self.mapRoot.children.append(landmarkTF)
   1031         self.landmarkTF = landmarkTF
   1032 
   1033     def CreateLabelRoot(self):
   1034         labeltrackersTF = trinity.EveTransform()
   1035         labeltrackersTF.name = '__labeltrackersTF'
   1036         self.mapRoot.children.append(labeltrackersTF)
   1037         self.labeltrackersTF = labeltrackersTF
   1038 
   1039     def CreateLocalCameraParent(self):
   1040         localCameraParent = trinity.EveTransform()
   1041         localCameraParent.name = '__localCameraParent'
   1042         self.mapRoot.children.append(localCameraParent)
   1043         self.localCameraParent = localCameraParent
   1044 
   1045     def SetMapPerspective(self, camera):
   1046         mapFlattened = GetUserUiSetting('mapFlattened', 1)
   1047         if mapFlattened == 1:
   1048             self.Flatten(initing=True)
   1049             self.rollCamera = True
   1050         else:
   1051             camera.OrbitParent(0.0, 20.0)
   1052             self.rollCamera = False
   1053 
   1054     @telemetry.ZONE_METHOD
   1055     def InitMap(self):
   1056         startTime = time.time()
   1057         self.LogInfo('MapSvc: InitStarMap')
   1058         initMapText = localization.GetByLabel('UI/Map/StarMap/InitializingMap')
   1059         gettingDataText = localization.GetByLabel('UI/Map/StarMap/GettingData')
   1060         self.StartLoadingBar('starmap_init', initMapText, gettingDataText, 4)
   1061         scene = self.CreateScene()
   1062         camera = self.CreateCamera()
   1063         self.UpdateLoadingBar('starmap_init', initMapText, gettingDataText, 1, 4)
   1064         self.CreateLandmarkRoot()
   1065         self.CreateLabelRoot()
   1066         self.CreateLocalCameraParent()
   1067         self.CreateJumpLineSet(scene)
   1068         self.CreateCursor()
   1069         self.CreateHexmap()
   1070         self.UpdateLoadingBar('starmap_init', initMapText, gettingDataText, 2, 4)
   1071         self.DrawPoints(self.mapRoot)
   1072         self.DrawSystemJumpLines()
   1073         self.allianceJumpLines = []
   1074         uthread.new(self.DrawAllJumpBridges)
   1075         self.MakeRegionLabels()
   1076         self.starLegend = []
   1077         self.tileLegend = []
   1078         if self.regionLabelParent:
   1079             self.regionLabelParent.display = 0
   1080         self.sceneManager.RegisterCamera(camera)
   1081         self.sceneManager.RegisterScene(scene, 'starmap')
   1082         self.SetMapPerspective(camera)
   1083         self.RegisterStarColorModes()
   1084         self.sceneManager.SetRegisteredScenes('starmap')
   1085         self.sceneManager.SetSecondaryCamera(evecamera.CAM_STARMAP)
   1086         self.UpdateLoadingBar('starmap_init', initMapText, gettingDataText, 3, 4)
   1087         self.SetStarColorMode()
   1088         self.UpdateLines(updateColor=1, hint='InitStarMap')
   1089         self.UpdateRoute()
   1090         self.CheckAllLabels('InitStarMap')
   1091         self.UpdateHexMap()
   1092         self.ShowWhereIAm()
   1093         self.SetInterest(session.solarsystemid2)
   1094         self.ShowCursorInterest(self.GetInterest().solarSystemID)
   1095         self.OnCameraMoved()
   1096         self.StopLoadingBar('starmap_init')
   1097         self.LogInfo('Initializing the starmap took %f' % (time.time() - startTime))
   1098 
   1099     def GetStarPickRadius(self):
   1100         range = ZOOM_MAX_STARMAP - ZOOM_MIN_STARMAP
   1101         dist = self.starmapCamera.translationFromParent - ZOOM_MIN_STARMAP
   1102         return PICK_RADIUS_NEAR + (PICK_RADIUS_FAR - PICK_RADIUS_NEAR) * (dist / range)
   1103 
   1104     def GetZoomLevel(self):
   1105         zoom = self.starmapCamera.translationFromParent - ZOOM_MIN_STARMAP / (ZOOM_MAX_STARMAP - ZOOM_MIN_STARMAP)
   1106         return max(0.0, min(1.0, zoom))
   1107 
   1108     def GetUICursor(self):
   1109         return self.uicursor
   1110 
   1111     def ShowCursorInterest(self, solarsystemID, particleID = None):
   1112         if solarsystemID and IsKnownSpaceSystem(solarsystemID) and IsValidDestination(solarsystemID):
   1113             self.cursor.translation = self.GetKnownSolarSystem(solarsystemID).scaledCenter
   1114             self.uicursor.solarsystemID = solarsystemID
   1115             self.uicursor.particleID = particleID
   1116             self.uicursor.display = True
   1117             RefreshTooltipForOwner(self.uicursor.icon)
   1118         elif self.uicursor:
   1119             self.uicursor.solarsystemID = None
   1120             self.uicursor.particleID = None
   1121             self.uicursor.display = False
   1122 
   1123     def IsRegionLabelVisible(self, regionID, regionOfInterest, regionLabelSelection):
   1124         if regionLabelSelection == SHOW_ALL_REGION_LABELS:
   1125             return True
   1126         if IsKnownSpaceRegion(regionOfInterest):
   1127             if regionLabelSelection == SHOW_SELECTED_REGION_LABEL:
   1128                 return regionID == regionOfInterest
   1129             if regionLabelSelection == SHOW_SELECTED_REGION_AND_NEIGHBOURS_LABELS:
   1130                 currentNeighbours = self.GetKnownRegion(regionOfInterest).neighbours
   1131                 return regionID == regionOfInterest or regionID in currentNeighbours
   1132         return False
   1133 
   1134     @telemetry.ZONE_METHOD
   1135     def CheckAllLabels(self, hint = ''):
   1136         if getattr(self, 'checkingalllabels', 0) or self.mapRoot is None:
   1137             return
   1138         self.checkingalllabels = 1
   1139         labelsToShow = []
   1140         labelsToRemove = self.labels.keys()
   1141         regionOfInterest, constellationOfInterest, systemOfInterest = self.GetInterest()
   1142         showSolarSystemNames = GetUserUiSetting('label_solarsystem', 1)
   1143         showConstellationNames = GetUserUiSetting('label_constellation', 1)
   1144         regionLabelSelection = GetUserUiSetting('rlabel_region', 1)
   1145         if regionLabelSelection == SHOW_NO_REGION_LABELS:
   1146             if self.regionLabelParent:
   1147                 self.regionLabelParent.display = 0
   1148         else:
   1149             if self.regionLabelParent:
   1150                 self.regionLabelParent.display = 1
   1151             if self.regionLabels:
   1152                 for regionID in self.GetKnownUniverseRegions():
   1153                     showLabel = self.IsRegionLabelVisible(regionID, regionOfInterest, regionLabelSelection)
   1154                     self.regionLabels[regionID].SetDisplay(showLabel)
   1155 
   1156         if GetUserUiSetting('label_landmarknames', 1):
   1157             for landmarkID in self.map.GetLandmarks().iterkeys():
   1158                 labelsToShow.append(landmarkID * -1)
   1159 
   1160         if systemOfInterest is not None and IsKnownSpaceSystem(systemOfInterest):
   1161             if showSolarSystemNames:
   1162                 labelsToShow += [systemOfInterest] + self.GetKnownSolarSystem(systemOfInterest).neighbours
   1163             constellationID = self.GetKnownSolarSystem(systemOfInterest).constellationID
   1164             if showConstellationNames and IsKnownSpaceConstellation(constellationID):
   1165                 labelsToShow.append(constellationID)
   1166         elif constellationOfInterest is not None and IsKnownSpaceConstellation(constellationOfInterest):
   1167             if showConstellationNames:
   1168                 labelsToShow += [constellationOfInterest] + self.GetKnownConstellation(constellationOfInterest).neighbours
   1169             if showSolarSystemNames:
   1170                 labelsToShow += self.GetKnownConstellation(constellationOfInterest).solarSystemIDs
   1171         elif showConstellationNames and IsKnownSpaceRegion(regionOfInterest):
   1172             labelsToShow += self.GetKnownRegion(regionOfInterest).constellationIDs
   1173         if showSolarSystemNames:
   1174             for wayPointID in self.GetDestinationPath():
   1175                 if wayPointID not in labelsToShow and wayPointID is not None:
   1176                     labelsToShow.append(wayPointID)
   1177 
   1178         if hasattr(self, 'focusLabel'):
   1179             if self.focusLabel is not None and self.focusLabel not in labelsToShow:
   1180                 labelsToShow.append(self.focusLabel)
   1181         new = [ x for x in labelsToShow if x not in labelsToRemove and not idCheckers.IsStation(x) ]
   1182         old = [ x for x in labelsToRemove if x not in labelsToShow ]
   1183         self.ClearLabels(old)
   1184         self.CreateLabels(new)
   1185         self.CheckLabelDist()
   1186         self.checkingalllabels = 0
   1187 
   1188     def CheckLabelDist(self):
   1189         if self.mapRoot is None:
   1190             return
   1191         uthread.new(self.CheckCloudLabels, 'checkLabelDist')
   1192 
   1193     @telemetry.ZONE_METHOD
   1194     def OnCameraMoved(self):
   1195         if self.IsFlat():
   1196             self.distanceRangeStars.value = (0, 0, 0, 0)
   1197             self.distanceRangeLines.value = (0, 0, 0, 0)
   1198             return
   1199         camera = self.sceneManager.GetRegisteredCamera(evecamera.CAM_STARMAP)
   1200         if camera is None:
   1201             return
   1202         geoView = camera.viewMatrix.transform
   1203         aabbMin = self.starParticles.aabbMin
   1204         aabbMax = self.starParticles.aabbMax
   1205         p = geo2.Vec3Transform(aabbMin, geoView)
   1206         znear = zfar = geo2.Vec3Length(p)
   1207 
   1208         def Update(x, y, z, znear, zfar):
   1209             p = geo2.Vec3Transform((x, y, z), geoView)
   1210             dist = geo2.Vec3Length(p)
   1211             return (min(znear, dist), max(zfar, dist))
   1212 
   1213         znear, zfar = Update(aabbMin[0], aabbMax[1], aabbMin[2], znear, zfar)
   1214         znear, zfar = Update(aabbMin[0], aabbMin[1], aabbMax[2], znear, zfar)
   1215         znear, zfar = Update(aabbMin[0], aabbMax[1], aabbMax[2], znear, zfar)
   1216         znear, zfar = Update(aabbMax[0], aabbMin[1], aabbMin[2], znear, zfar)
   1217         znear, zfar = Update(aabbMax[0], aabbMax[1], aabbMin[2], znear, zfar)
   1218         znear, zfar = Update(aabbMax[0], aabbMin[1], aabbMax[2], znear, zfar)
   1219         znear, zfar = Update(aabbMax[0], aabbMax[1], aabbMax[2], znear, zfar)
   1220         znear = max(0, znear)
   1221         if zfar <= znear:
   1222             zfar = znear + 1
   1223         self.distanceRangeStars.value = (znear,
   1224          1.0 / (zfar - znear),
   1225          0,
   1226          0)
   1227         self.distanceRangeLines.value = (znear,
   1228          1.0 / (zfar - znear),
   1229          0,
   1230          0)
   1231 
   1232     @telemetry.ZONE_METHOD
   1233     def CheckCloudLabels(self, reason = ''):
   1234         if doingDebug == 1:
   1235             self.LogInfo('checkloudlabels ', reason)
   1236         if getattr(self, 'checkinglabels', 0):
   1237             return
   1238         setattr(self, 'checkinglabels', 1)
   1239         sel = self.GetInterest()
   1240         dst = self.GetDestination()
   1241         for label in self.labels.itervalues():
   1242             if label is not None and not label.destroyed:
   1243                 if len(label.children):
   1244                     if label.sr.id in sel or label.sr.id == getattr(self, 'highlightLabel', -1) or label.sr.id == dst:
   1245                         label.children[0].opacity = 1.0
   1246                     else:
   1247                         label.children[0].opacity = 0.7
   1248 
   1249         setattr(self, 'checkinglabels', 0)
   1250 
   1251     def GetStarData(self):
   1252         return getattr(self, 'starData', {})
   1253 
   1254     def GetPickRay(self, x, y):
   1255         dev = trinity.device
   1256         proj, view, vp = uix.GetFullscreenProjectionViewAndViewport()
   1257         ray, start = dev.GetPickRayFromViewport(x, y, vp, view.transform, proj.transform)
   1258         return utillib.KeyVal(normal=ray, startPos=start)
   1259 
   1260     @telemetry.ZONE_METHOD
   1261     def TranslateCamera(self, x, y, dx, dy):
   1262         self.interestEndPos = None
   1263         camera = self.sceneManager.GetRegisteredCamera(evecamera.CAM_STARMAP)
   1264         cameraParent = self.GetCameraParent()
   1265         toRay = self.GetPickRay(x, y)
   1266         fromRay = self.GetPickRay(x - dx, y - dy)
   1267         pos = cameraParent.translation
   1268         planePoint = pos
   1269         pickPlane = geo2.PlaneFromPointNormal(planePoint, camera.viewVec)
   1270         toPoint = geo2.PlaneIntersectLine(pickPlane, toRay.startPos, toRay.startPos + geo2.Vector(*toRay.normal) * 1000000.0)
   1271         if toPoint is None:
   1272             return
   1273         fromPoint = geo2.PlaneIntersectLine(pickPlane, fromRay.startPos, fromRay.startPos + geo2.Vector(*fromRay.normal) * 1000000.0)
   1274         if fromPoint is None:
   1275             return
   1276         offset = geo2.Vector(*fromPoint) - toPoint
   1277         cameraParent.translation = geo2.Vec3Add(cameraParent.translation, offset)
   1278         uthread.new(self.CheckLabelDist)
   1279 
   1280     def GetWorldPosFromLocalCoord(self, vector = None, flatten = True):
   1281         pos = geo2.Vector(*(vector or self.localCameraParent.translation))
   1282         if flatten and self.IsFlat():
   1283             pos.y = 0.0
   1284         curveQuat = self.mapRoot.rotationCurve.currentValue
   1285         pos = geo2.QuaternionTransformVector(curveQuat, pos)
   1286         return geo2.Vector(*pos)
   1287 
   1288     @telemetry.ZONE_METHOD
   1289     def SetInterest(self, itemID = None, forceframe = None, forcezoom = None):
   1290         if forceframe is None:
   1291             forceframe = GetUserUiSetting('mapautoframe', 1)
   1292         if forcezoom is None:
   1293             forcezoom = GetUserUiSetting('mapautozoom', 0)
   1294         self.LogInfo('Map Setinterest ', itemID)
   1295         if doingDebug == 1:
   1296             self.LogInfo('setinterest ', itemID, forceframe)
   1297         if self.mapRoot is None:
   1298             return
   1299         dollyEndval = None
   1300         camDuration = None
   1301         interest = self.GetInterest()
   1302         if not IsKnownSpaceSystem(itemID) or not IsValidDestination(itemID):
   1303             itemID = DEFAULT_SOLAR_SYSTEM_ID
   1304         itemID = itemID or interest.solarSystemID or interest.constellationID or interest.regionID or session.regionid
   1305         endPos = self.GetWorldPosFromLocalCoord(flatten=True)
   1306         self.interestEndPos = self.GetWorldPosFromLocalCoord(flatten=False)
   1307         if itemID is None:
   1308             return
   1309         if itemID == const.locationUniverse:
   1310             dollyEndval = 20000.0
   1311         elif itemID < 0:
   1312             lm = self.map.GetLandmark(itemID * -1)
   1313             scaledCenter = geo2.Scale(geo2.Vector(*lm.position), STARMAP_SCALE)
   1314             self.localCameraParent.translation = scaledCenter
   1315             endPos = self.GetWorldPosFromLocalCoord(flatten=True)
   1316             self.interestEndPos = self.GetWorldPosFromLocalCoord(flatten=False)
   1317         else:
   1318             self.UpdateLines(itemID, hint='SetInterest')
   1319             scaledCenter = (0.0, 0.0, 0.0)
   1320             if idCheckers.IsSolarSystem(itemID):
   1321                 system = self.GetKnownSolarSystem(itemID)
   1322                 scaledCenter = system.scaledCenter
   1323                 self.interest = StarmapInterest(system.regionID, system.constellationID, itemID)
   1324             elif idCheckers.IsConstellation(itemID):
   1325                 constellation = self.GetKnownConstellation(itemID)
   1326                 scaledCenter = constellation.scaledCenter
   1327                 self.interest = StarmapInterest(constellation.regionID, itemID, None)
   1328             elif idCheckers.IsRegion(itemID) and self.regionLabels:
   1329                 scaledCenter = self.GetKnownRegion(itemID).scaledCenter
   1330                 self.interest = StarmapInterest(itemID, None, None)
   1331                 for regionID in self.knownRegions:
   1332                     self.regionLabels[regionID].SetHighlight(False)
   1333 
   1334                 if IsKnownSpaceRegion(itemID):
   1335                     self.regionLabels[itemID].SetHighlight(True)
   1336             scaledCenter = geo2.Vector(scaledCenter[0], 0.0 if self.IsFlat() else scaledCenter[1], scaledCenter[2])
   1337             camera = self.sceneManager.GetRegisteredCamera(evecamera.CAM_STARMAP)
   1338             dollyEndval = camera.translationFromParent
   1339             if forceframe and forcezoom:
   1340                 if idCheckers.IsSolarSystem(itemID):
   1341                     dollyEndval = ZOOM_MIN_STARMAP + (ZOOM_MAX_STARMAP - ZOOM_MIN_STARMAP) * 0.05
   1342                 else:
   1343                     item = self.map.GetItem(itemID)
   1344                     mx = abs(item.xMin) + item.xMax
   1345                     my = abs(item.yMin) + item.yMax
   1346                     mz = abs(item.zMin) + item.zMax
   1347                     size = geo2.Scale(geo2.Vector(mx, my, mz), STARMAP_SCALE)
   1348                     radius = max(*size) * 0.5
   1349                     camangle = camera.fieldOfView * 0.5
   1350                     dollyEndval = radius / sin(camangle) * cos(camangle)
   1351             self.localCameraParent.translation = scaledCenter
   1352             endPos = self.GetWorldPosFromLocalCoord()
   1353             self.interestEndPos = self.GetWorldPosFromLocalCoord(flatten=False)
   1354             cameraParent = self.GetCameraParent()
   1355             mapPos = geo2.Vector(*cameraParent.translation)
   1356             camDuration = max(0.25, min(1.0, geo2.Vec3Length(endPos - mapPos) * 1e-05))
   1357         if self.mapRoot is None:
   1358             return
   1359         if forceframe:
   1360             uthread.new(self.MoveInterest, endPos, (camDuration or 0.2) * 1000.0)
   1361             if forcezoom and dollyEndval is not None:
   1362                 self.Dolly(dollyEndval, camDuration or 0.2)
   1363         self.CheckAllLabels('SetInterest')
   1364         self.UpdateLines()
   1365 
   1366     @telemetry.ZONE_METHOD
   1367     def MoveInterest(self, posEnd, time = 500.0):
   1368         uicore.desktop.state = uiconst.UI_DISABLED
   1369         count = 50
   1370         while getattr(self, 'moving', False) and count:
   1371             blue.pyos.synchro.SleepWallclock(100)
   1372             count -= 1
   1373 
   1374         try:
   1375             self.moving = True
   1376             cameraParent = self.GetCameraParent()
   1377             startPos = cameraParent.translation
   1378             posBegin = geo2.Vector(*startPos)
   1379             start = blue.os.GetWallclockTime()
   1380             ndt = 0.0
   1381             while ndt != 1.0:
   1382                 ndt = max(0.0, min(blue.os.TimeDiffInMs(start, blue.os.GetWallclockTime()) / time, 1.0))
   1383                 if posBegin and posEnd:
   1384                     pos = geo2.Vec3Lerp(posBegin, posEnd, ndt)
   1385                     cameraParent.translation = pos
   1386                 blue.pyos.synchro.Yield()
   1387 
   1388         except AttributeError:
   1389             pass
   1390         finally:
   1391             uicore.desktop.state = uiconst.UI_NORMAL
   1392             self.moving = False
   1393 
   1394     def Dolly(self, end, length = 2.0):
   1395         camera = self.sceneManager.GetRegisteredCamera(evecamera.CAM_STARMAP)
   1396         beg = camera.translationFromParent
   1397         end = camera.CheckTranslationFromParent(end)
   1398         camera.PanCamera(beg, end, time=length, source='starmap')
   1399         self.CheckLabelDist()
   1400 
   1401     @telemetry.ZONE_METHOD
   1402     def MakeRegionLabels(self):
   1403         self.LogInfo('MakeRegionLabels')
   1404         regionLabelParent = trinity.EveTransform()
   1405         regionLabelParent.display = 0
   1406         self.mapRoot.children.append(regionLabelParent)
   1407         regionLabelParent.name = '__regionLabels'
   1408         self.regionLabels = {}
   1409         for regionID, regionItem in self.GetKnownUniverseRegions().iteritems():
   1410             regionName = StripTags(cfg.evelocations.Get(regionID).name, stripOnly=['localized'])
   1411             label = TransformableLabel(regionName, regionLabelParent, size=127)
   1412             label.transform.translation = regionItem.scaledCenter
   1413             label.transform.scaling = geo2.Scale(geo2.Vector(*label.transform.scaling), REGION_LABEL_SCALE)
   1414             label.SetDisplay(False)
   1415             self.regionLabels[regionID] = label
   1416 
   1417         self.regionLabelParent = regionLabelParent
   1418 
   1419     def DrawRouteTo(self, targetID, verbose = 1, sourceID = None):
   1420         self.LogInfo('DrawRouteTo ', targetID)
   1421         if targetID == session.solarsystemid2:
   1422             self.ClearRoute('genericRoute')
   1423             return
   1424         if targetID in [session.solarsystemid2, session.constellationid, session.regionid]:
   1425             return []
   1426         targetName = cfg.evelocations.Get(targetID).name
   1427         routeList = self.ShortestGeneralPath(targetID, sourceID=sourceID)
   1428         self.ClearRoute('genericRoute')
   1429         route = MapRoute()
   1430         route.DrawRoute(routeList, flattened=self.flattened, rotationQuaternion=self.GetCurrentStarmapRotation())
   1431         self.genericRoute = route
   1432         scene = self.sceneManager.GetRegisteredScene('starmap')
   1433         scene.objects.append(route.model)
   1434         if not len(routeList):
   1435             if self.viewState.IsViewActive('starmap'):
   1436                 if verbose == 1:
   1437                     prompt_player_fsd_dialog('Command', {'command': localization.GetByLabel('UI/Map/StarMap/NoPathFoundTo', targetItem=targetName)})
   1438             return []
   1439         self.CheckAllLabels('DrawRouteTo')
   1440         if self.viewState.IsViewActive('starmap'):
   1441             if verbose == 1:
   1442                 jumps = len(routeList) - 1
   1443                 routeType = self.clientPathfinderService.GetAutopilotRouteType()
   1444                 if sourceID:
   1445                     sourceItemName = cfg.evelocations.Get(sourceID).name
   1446                     if routeType == ROUTE_TYPE_SHORTEST:
   1447                         if idCheckers.IsRegion(targetID):
   1448                             labelText = localization.GetByLabel('UI/Map/StarMap/TheShortestRouteFromToTakesRegionJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1449                         else:
   1450                             labelText = localization.GetByLabel('UI/Map/StarMap/TheShortestRouteFromToTakesJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1451                     elif routeType == ROUTE_TYPE_SAFE:
   1452                         if idCheckers.IsRegion(targetID):
   1453                             labelText = localization.GetByLabel('UI/Map/StarMap/TheSafestRouteFromToTakesRegionJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1454                         else:
   1455                             labelText = localization.GetByLabel('UI/Map/StarMap/TheSafestRouteFromToTakesJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1456                     elif routeType == ROUTE_TYPE_UNSAFE:
   1457                         if idCheckers.IsRegion(targetID):
   1458                             labelText = localization.GetByLabel('UI/Map/StarMap/TheUnSafestRouteFromToTakesRegionJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1459                         else:
   1460                             labelText = localization.GetByLabel('UI/Map/StarMap/TheUnSafestRouteFromToTakesJumps', sourceItem=sourceItemName, targetItem=targetName, jumps=jumps)
   1461                     else:
   1462                         labelText = localization.GetByLabel('UI/Map/StarMap/NoKnownRouteFromTo')
   1463                     prompt_player_fsd_dialog('Command', {'command': labelText})
   1464                 else:
   1465                     if routeType == ROUTE_TYPE_SHORTEST:
   1466                         if idCheckers.IsRegion(targetID):
   1467                             labelText = localization.GetByLabel('UI/Map/StarMap/TheShortestRouteToTakesRegionJumps', targetItem=targetName, jumps=jumps)
   1468                         else:
   1469                             labelText = localization.GetByLabel('UI/Map/StarMap/TheShortestRouteToTakesJumps', targetItem=targetName, jumps=jumps)
   1470                     elif routeType == ROUTE_TYPE_SAFE:
   1471                         if idCheckers.IsRegion(targetID):
   1472                             labelText = localization.GetByLabel('UI/Map/StarMap/TheSafestRouteToTakesRegionJumps', targetItem=targetName, jumps=jumps)
   1473                         else:
   1474                             labelText = localization.GetByLabel('UI/Map/StarMap/TheSafestRouteToTakesJumps', targetItem=targetName, jumps=jumps)
   1475                     elif routeType == ROUTE_TYPE_UNSAFE:
   1476                         if idCheckers.IsRegion(targetID):
   1477                             labelText = localization.GetByLabel('UI/Map/StarMap/TheUnSafestRouteToTakesJumps', targetItem=targetName, jumps=jumps)
   1478                         else:
   1479                             labelText = localization.GetByLabel('UI/Map/StarMap/TheUnSafestRouteToTakesRegionJumps', targetItem=targetName, jumps=jumps)
   1480                     else:
   1481                         labelText = localization.GetByLabel('UI/Map/StarMap/NoKnownRouteTo')
   1482                     prompt_player_fsd_dialog('Command', {'command': labelText})
   1483         self.genericRoutePath = routeList
   1484         self.UpdateLines(updateColor=1)
   1485         return routeList
   1486 
   1487     def RemoveGenericPath(self):
   1488         self.genericRoutePath = None
   1489         self.ClearRoute('genericRoute')
   1490         self.UpdateLines(updateColor=True)
   1491 
   1492     def ClearRoute(self, routeName = 'autoPilotRoute'):
   1493         route = getattr(self, routeName, None)
   1494         if route:
   1495             scene = self.sceneManager.GetRegisteredScene('starmap')
   1496             if route.model in scene.objects:
   1497                 scene.objects.fremove(route.model)
   1498             setattr(self, routeName, None)
   1499 
   1500     def ShortestGeneralPath(self, targetID, sourceID = None):
   1501         if sourceID is None:
   1502             sourceID = session.solarsystemid2
   1503         if idCheckers.IsConstellation(targetID):
   1504             targets = self.map.GetLocationChildren(targetID)
   1505         elif idCheckers.IsRegion(targetID):
   1506             targets = []
   1507             for constellationID in self.map.GetLocationChildren(targetID):
   1508                 targets.extend(self.map.GetLocationChildren(constellationID))
   1509 
   1510         else:
   1511             targets = [targetID]
   1512         paths = []
   1513         for target in targets:
   1514             routeList = self.clientPathfinderService.GetAutopilotPathBetween(sourceID, target)
   1515             if routeList:
   1516                 paths.append(routeList)
   1517 
   1518         if not len(paths):
   1519             return []
   1520         return min(paths, key=lambda p: len(p))
   1521 
   1522     def GetAllFactions(self):
   1523         return list(cfg.mapFactionsOwningSolarSystems)
   1524 
   1525     def GetAllianceSolarSystems(self):
   1526         self.allianceSolarSystems = {}
   1527         allianceSystemCache = sm.RemoteSvc('stationSvc').GetAllianceSystems()
   1528         for x in allianceSystemCache:
   1529             self.allianceSolarSystems[x.solarSystemID] = x.allianceID
   1530 
   1531         occupationStatesBySolarsystemByWarzone = sm.GetService('fwWarzoneSvc').GetAllOccupationStates()
   1532         for occupationStatesBySolarsystem in occupationStatesBySolarsystemByWarzone.itervalues():
   1533             for solarsystemID, occupationState in occupationStatesBySolarsystem.iteritems():
   1534                 self.allianceSolarSystems[solarsystemID] = occupationState.occupierID
   1535 
   1536         return self.allianceSolarSystems
   1537 
   1538     def GetAllFactionsAndAlliances(self):
   1539         factions = self.GetAllFactions()
   1540         alliances = self.GetAllianceSolarSystems().values()
   1541         return list(set(factions + alliances))
   1542 
   1543     def GetDestination(self):
   1544         if self.destinationPath != [None]:
   1545             return self.destinationPath[-1]
   1546 
   1547     def GetDestinationPath(self):
   1548         if not len(self.destinationPath):
   1549             return [None]
   1550         return self.destinationPath[:]
   1551 
   1552     def GetFactionOrAllianceColor(self, entityID):
   1553         if not hasattr(self, 'factionOrAllianceColors'):
   1554             self.factionOrAllianceColors = {}
   1555         if entityID not in self.factionOrAllianceColors:
   1556             col = trinity.TriColor()
   1557             hue = entityID * 12.345 * 3.0
   1558             s = entityID % 2 * 0.5 + 0.5
   1559             col.SetHSV(hue % 360.0, s, 1.0)
   1560             self.factionOrAllianceColors[entityID] = col
   1561         return self.factionOrAllianceColors[entityID]
   1562 
   1563     def GetLineIDForJumpBetweenSystems(self, fromSystemID, toSystemID):
   1564         for lineID, _toSystemID in self.lineIdAndToSystemIdByFromSystemId[fromSystemID]:
   1565             if _toSystemID == toSystemID:
   1566                 return lineID
   1567         else:
   1568             raise RuntimeError("Did not find a lineID for a jump between '%s' and '%s'" % (self.map.GetItem(fromSystemID).itemName, self.map.GetItem(toSystemID).itemName))
   1569 
   1570     def GetLineIDsForSystemID(self, sysID):
   1571         return [ i[0] for i in self.lineIdAndToSystemIdByFromSystemId[sysID] ]
   1572 
   1573     def GetLineIDsForSystemList(self, solarSystemIDs):
   1574         result = []
   1575         for solarSystemID in solarSystemIDs:
   1576             result.extend(self.GetLineIDsForSystemID(solarSystemID))
   1577 
   1578         return result
   1579 
   1580     @telemetry.ZONE_METHOD
   1581     def DrawSystemJumpLines(self):
   1582         self.jumpLineInfoByLineID = {}
   1583         self.lineIdAndToSystemIdByFromSystemId = defaultdict(list)
   1584         self.curvedLineInfoByLineID = {}
   1585         lineSet = self.solarSystemJumpLineSet
   1586         self.jumpLineIDsByJumpType = [[], [], []]
   1587         for jump in self.IterateJumps():
   1588             jumpColor = JUMP_COLORS[jump.jumpType]
   1589             lineID = lineSet.AddStraightLine(jump.adjustedFromVector, jumpColor, jump.adjustedToVector, jumpColor, 2)
   1590             jumpToSystemID = jump.toSystemID
   1591             jumpFromSystemID = jump.fromSystemID
   1592             jumpLineInfo = utillib.KeyVal(lineID=lineID, toID=jumpToSystemID, toPos=jump.adjustedToVector, toColor=jumpColor, fromID=jumpFromSystemID, fromPos=jump.adjustedFromVector, fromColor=jumpColor)
   1593             self.jumpLineIDsByJumpType[jump.jumpType].append(lineID)
   1594             self.jumpLineInfoByLineID[lineID] = jumpLineInfo
   1595             self.currentLineColour[lineID] = (jumpColor, jumpColor)
   1596             self.lineIdAndToSystemIdByFromSystemId[jumpFromSystemID].append((lineID, jumpToSystemID))
   1597             self.lineIdAndToSystemIdByFromSystemId[jumpToSystemID].append((lineID, jumpFromSystemID))
   1598 
   1599         lineSet.SubmitChanges()
   1600 
   1601     def DrawAllJumpBridges(self):
   1602         self.allJumpBridges = []
   1603         self.myJumpBridges = []
   1604         jumpBridgesGates, hasAccessTo, hasNoAccessTo = sm.GetService('map').GetJumpBridgesWithMyAccess()
   1605         jumpBridgeColorAccess = ScaleColour(mapcommon.JUMPBRIDGE_COLOR, mapcommon.JUMPBRIDGE_COLOR_SCALE)
   1606         jumpBridgeColorNoAccess = ScaleColour(mapcommon.JUMPBRIDGE_COLOR_NO_ACCESS, mapcommon.JUMPBRIDGE_COLOR_SCALE)
   1607         lineSet = self.solarSystemJumpLineSet
   1608         for structureA, structureB in jumpBridgesGates:
   1609             solarSystemA = structureA.solarSystemID
   1610             solarSystemB = structureB.solarSystemID
   1611             if not idCheckers.IsSolarSystem(solarSystemA) or not idCheckers.IsSolarSystem(solarSystemB):
   1612                 self.LogWarn("DrawAllJumpBridges had entry that wasn't a solarsystem:", solarSystemA, solarSystemB)
   1613                 continue
   1614             if not IsValidDestination(solarSystemA) or not IsValidDestination(solarSystemB):
   1615                 continue
   1616             toPos = self.GetKnownSolarSystem(solarSystemA).scaledCenter
   1617             fromPos = self.GetKnownSolarSystem(solarSystemB).scaledCenter
   1618             worldUp = geo2.Vector(0.0, 1.0, 0.0)
   1619             linkVec = geo2.Vec3Subtract(toPos, fromPos)
   1620             normLinkVec = geo2.Vec3Normalize(linkVec)
   1621             rightVec = geo2.Vec3Cross(worldUp, normLinkVec)
   1622             upVec = geo2.Vec3Cross(rightVec, normLinkVec)
   1623             offsetVec = geo2.Vec3Scale(geo2.Vec3Normalize(upVec), geo2.Vec3Length(linkVec) * mapcommon.JUMPBRIDGE_CURVE_SCALE)
   1624             midPos = geo2.Vec3Scale(geo2.Vec3Add(toPos, fromPos), 0.5)
   1625             splinePos = geo2.Vec3Add(midPos, offsetVec)
   1626             hasAccessToA = structureA.structureID in hasAccessTo
   1627             hasAccessToB = structureB.structureID in hasAccessTo
   1628             colorA = jumpBridgeColorAccess if hasAccessToA else jumpBridgeColorNoAccess
   1629             colorB = jumpBridgeColorAccess if hasAccessToB else jumpBridgeColorNoAccess
   1630             animationColor = jumpBridgeColorAccess if hasAccessToA or hasAccessToB else jumpBridgeColorNoAccess
   1631             lineID = lineSet.AddCurvedLineCrt(toPos, colorA, fromPos, colorB, splinePos, 2)
   1632             lineSet.ChangeLineAnimation(lineID, animationColor, mapcommon.JUMPBRIDGE_ANIMATION_SPEED, 1)
   1633             info = utillib.KeyVal(lineID=lineID, toID=solarSystemA, toPos=toPos, toColor=colorA, fromID=solarSystemB, fromPos=fromPos, fromColor=colorB)
   1634             if settings.char.ui.Get('pathFinder_includeJumpGates', False):
   1635                 self.lineIdAndToSystemIdByFromSystemId[solarSystemB].append((lineID, solarSystemA))
   1636                 self.lineIdAndToSystemIdByFromSystemId[solarSystemA].append((lineID, solarSystemB))
   1637             self.allJumpBridges.append(lineID)
   1638             if hasAccessToA or hasAccessToB:
   1639                 self.myJumpBridges.append(lineID)
   1640             self.currentLineColour[lineID] = (colorA, colorB)
   1641             self.jumpLineInfoByLineID[lineID] = info
   1642             self.curvedLineInfoByLineID[lineID] = (midPos, offsetVec)
   1643 
   1644         lineSet.SubmitChanges()
   1645 
   1646     def GetHiliteItem(self, hiliteID):
   1647         hiliteItem = None
   1648         if not IsValidDestination(hiliteID):
   1649             return
   1650         if idCheckers.IsSolarSystem(hiliteID) and IsKnownSpaceSystem(hiliteID):
   1651             hiliteItem = self.GetKnownSolarSystem(hiliteID)
   1652         elif idCheckers.IsConstellation(hiliteID) and IsKnownSpaceConstellation(hiliteID):
   1653             hiliteItem = self.GetKnownConstellation(hiliteID)
   1654         elif idCheckers.IsRegion(hiliteID) and IsKnownSpaceRegion(hiliteID):
   1655             hiliteItem = self.GetKnownRegion(hiliteID)
   1656         return hiliteItem
   1657 
   1658     @telemetry.ZONE_METHOD
   1659     def UpdateLines(self, hiliteID = None, updateColor = False, showlines = None, hint = '', path = None):
   1660         if not sm.GetService('viewState').IsViewActive('starmap'):
   1661             return
   1662         if showlines is None:
   1663             showlines = GetUserUiSetting('showlines', SHOW_ALL)
   1664         interest = self.GetInterest()
   1665         if showlines == SHOW_NONE:
   1666             self.SetJumpLineAlpha(0.0)
   1667         else:
   1668             if hiliteID is None:
   1669                 hiliteID = interest.solarSystemID or interest.constellationID or interest.regionID
   1670             if showlines == SHOW_ALL:
   1671                 self.SetJumpLineAlpha(0.5)
   1672             else:
   1673                 self.SetJumpLineAlpha(0.0)
   1674                 if showlines > SHOW_SELECTION and IsKnownSpaceRegion(interest.regionID):
   1675                     regionsToShow = [interest.regionID]
   1676                     if showlines == SHOW_NEIGHBORS:
   1677                         regionsToShow = regionsToShow + self.GetKnownRegion(interest.regionID).neighbours
   1678                     self.SetJumpLineAlpha(0.0)
   1679                     regionIDs = self.map.ExpandItems(regionsToShow)
   1680                     lineIDs = self.GetLineIDsForSystemList(regionIDs)
   1681                     self.SetJumpLineAlpha(0.5, lineIDs)
   1682             if idCheckers.IsSolarSystem(hiliteID) and IsKnownSpaceSystem(hiliteID):
   1683                 lineIDs = self.GetLineIDsForSystemID(hiliteID)
   1684                 self.SetJumpLineAlpha(1.0, lineIDs)
   1685                 lineIDs = self.GetLineIDsForSystemList(self.GetHiliteItem(hiliteID).neighbours)
   1686                 self.SetJumpLineAlpha(0.6, lineIDs)
   1687             elif idCheckers.IsConstellation(hiliteID) and IsKnownSpaceConstellation(hiliteID):
   1688                 lineIDs = self.GetLineIDsForSystemList(self.GetHiliteItem(hiliteID).solarSystemIDs)
   1689                 self.SetJumpLineAlpha(1.0, lineIDs)
   1690             elif idCheckers.IsRegion(hiliteID) and IsKnownSpaceRegion(hiliteID):
   1691                 lineIDs = self.GetLineIDsForSystemList(self.GetHiliteItem(hiliteID).solarSystemIDs)
   1692                 self.SetJumpLineAlpha(1.0, lineIDs)
   1693         if updateColor:
   1694             self.UpdateLineColor()
   1695         showAllianceLines = GetUserUiSetting('map_alliance_jump_lines', 1)
   1696         self.SetJumpLineAlpha(1.0 if showAllianceLines else 0.0, self.allianceJumpLines)
   1697         showJumpBridges = GetUserUiSetting('showJumpBridges', 0)
   1698         if showJumpBridges == 1:
   1699             self.SetJumpLineAlpha(1.0, self.allJumpBridges)
   1700         else:
   1701             toHide = set(self.allJumpBridges) - set(self.myJumpBridges)
   1702             self.SetJumpLineAlpha(0.0, toHide)
   1703             self.SetJumpLineAlpha(1.0, self.myJumpBridges)
   1704         if path:
   1705             self.ShowPath(path)
   1706         if self.genericRoutePath:
   1707             self.ShowPath(self.genericRoutePath)
   1708         self.ShowDestinationPath()
   1709         self.solarSystemJumpLineSet.SubmitChanges()
   1710 
   1711     @telemetry.ZONE_METHOD
   1712     def SetJumpLineAlpha(self, alpha, lineIDs = None):
   1713         lineSet = self.solarSystemJumpLineSet
   1714         if lineIDs is None:
   1715             lineIDs = self.jumpLineInfoByLineID.iterkeys()
   1716         for lineID in lineIDs:
   1717             fromColor, toColor = self.currentLineColour[lineID]
   1718             self.ChangeLineColor(lineSet, lineID, OverrideAlpha(fromColor, alpha), OverrideAlpha(toColor, alpha))
   1719 
   1720     @telemetry.ZONE_METHOD
   1721     def ChangeLineColor(self, lineSet, lineID, fromColor, toColor):
   1722         if lineID in self.allianceJumpLines:
   1723             overlayColor = fromColor
   1724             lineSet.ChangeLineAnimation(lineID, overlayColor, mapcommon.JUMPBRIDGE_ANIMATION_SPEED, 1)
   1725         oldFromColor, oldToColor = self.currentLineColour[lineID]
   1726         newFromColor = OverrideColour(oldFromColor, fromColor)
   1727         newToColor = OverrideColour(oldToColor, toColor)
   1728         self.currentLineColour[lineID] = (newFromColor, newToColor)
   1729         lineSet.ChangeLineColor(lineID, newFromColor, newToColor)
   1730 
   1731     @telemetry.ZONE_METHOD
   1732     def SetJumpLineColor(self, color, lineIDs = None):
   1733         lineSet = self.solarSystemJumpLineSet
   1734         if lineIDs is None:
   1735             lineIDs = self.jumpLineInfoByLineID.iterkeys()
   1736         for lineID in lineIDs:
   1737             self.ChangeLineColor(lineSet, lineID, color, color)
   1738 
   1739     @telemetry.ZONE_METHOD
   1740     def SetJumpLineColors(self, lineIDs, fromColor, toColor):
   1741         lineSet = self.solarSystemJumpLineSet
   1742         for lineID in lineIDs:
   1743             self.ChangeLineColor(lineSet, lineID, fromColor, toColor)
   1744 
   1745     @telemetry.ZONE_METHOD
   1746     def SetJumpLineColorAt(self, lineID, atID, color):
   1747         lineSet = self.solarSystemJumpLineSet
   1748         fromColor, toColor = self.currentLineColour[lineID]
   1749         if atID == info.fromID:
   1750             fromColor = OverrideColour(fromColor, color)
   1751         else:
   1752             toColor = OverrideColour(toColor, color)
   1753         self.ChangeLineColor(lineSet, lineID, fromColor, toColor)
   1754 
   1755     @telemetry.ZONE_METHOD
   1756     def SetJumpLineAlphaAt(self, lineID, atID, alpha):
   1757         lineSet = self.solarSystemJumpLineSet
   1758         fromColor, toColor = self.currentLineColour[lineID]
   1759         if atID == info.fromID:
   1760             fromColor = OverrideAlpha(fromColor, alpha)
   1761         else:
   1762             toColor = OverrideAlpha(toColor, alpha)
   1763         self.ChangeLineColor(lineSet, lineID, fromColor, toColor)
   1764 
   1765     @telemetry.ZONE_METHOD
   1766     def SetStarParticleAlpha(self, alpha, particleIDs = None):
   1767         particleSystem = self.starParticles
   1768         if particleIDs is None:
   1769             particleItemsIterator = enumerate(self.particleColors)
   1770         else:
   1771             particleItemsIterator = SelectiveIndexedIterItems(self.particleColors, particleIDs)
   1772         for key, color in particleItemsIterator:
   1773             particleSystem.SetItemElement(key, 2, OverrideAlpha(color, alpha))
   1774 
   1775     @telemetry.ZONE_METHOD
   1776     def SetStarParticleColor(self, newColor, particleIDs = None):
   1777         particleSystem = self.starParticles
   1778         if particleIDs is None:
   1779             particleItemsIterator = enumerate(self.particleColors)
   1780         else:
   1781             particleItemsIterator = SelectiveIndexedIterItems(self.particleColors, particleIDs)
   1782         for key, originalColor in particleItemsIterator:
   1783             c = OverrideColour(originalColor, newColor)
   1784             particleSystem.SetItemElement(key, 2, c)
   1785 
   1786     @telemetry.ZONE_METHOD
   1787     def SetStarParticleSize(self, size, particleIDs = None):
   1788         particleSystem = self.starParticles
   1789         if particleIDs is None:
   1790             particleIDs = xrange(len(self.particleColors))
   1791         for id in particleIDs:
   1792             particleSystem.SetItemElement(id, 1, size)
   1793 
   1794     @telemetry.ZONE_METHOD
   1795     def UpdateLineColor(self):
   1796         colorMode = GetUserUiSetting('mapcolorby', mapcommon.COLORMODE_UNIFORM)
   1797         if colorMode == mapcommon.COLORMODE_UNIFORM:
   1798             for jumpType in JUMP_TYPES:
   1799                 lineIDs = self.jumpLineIDsByJumpType[jumpType]
   1800                 self.SetJumpLineColor(JUMP_COLORS[jumpType][:3], lineIDs)
   1801 
   1802             self.SetJumpLineColor(ScaleColour(mapcommon.JUMPBRIDGE_COLOR, mapcommon.JUMPBRIDGE_COLOR_SCALE), self.allianceJumpLines)
   1803         elif colorMode == mapcommon.COLORMODE_REGION:
   1804             if not hasattr(self, 'regionJumpColorList'):
   1805                 self.regionJumpColorList = []
   1806                 for info in self.jumpLineInfoByLineID.itervalues():
   1807                     fromRegionID = self.GetKnownSolarSystem(info.fromID).regionID
   1808                     toRegionID = self.GetKnownSolarSystem(info.toID).regionID
   1809                     fromColor = self.GetRegionColor(fromRegionID)
   1810                     toColor = self.GetRegionColor(toRegionID)
   1811                     self.regionJumpColorList.append(([info.lineID], (fromColor.r, fromColor.g, fromColor.b), (toColor.r, toColor.g, toColor.b)))
   1812 
   1813             for lineID, formColor, toColor in self.regionJumpColorList:
   1814                 self.SetJumpLineColors(lineID, formColor, toColor)
   1815 
   1816         elif colorMode == mapcommon.COLORMODE_STANDINGS:
   1817             colorByFaction = {}
   1818             for factionID in self.GetAllFactionsAndAlliances():
   1819                 colorByFaction[factionID] = self.GetColorByStandings(factionID)
   1820 
   1821             allianceSolarSystems = self.GetAllianceSolarSystems()
   1822             for info in self.jumpLineInfoByLineID.itervalues():
   1823                 fromColor = colorByFaction.get(self._GetFactionIDFromSolarSystem(allianceSolarSystems, info.fromID), mapcommon.COLOR_STANDINGS_NEUTRAL)
   1824                 toColor = colorByFaction.get(self._GetFactionIDFromSolarSystem(allianceSolarSystems, info.toID), mapcommon.COLOR_STANDINGS_NEUTRAL)
   1825                 self.SetJumpLineColors([info.lineID], fromColor, toColor)
   1826 
   1827     @telemetry.ZONE_METHOD
   1828     def GetColorByStandings(self, factionID):
   1829         if factionID == session.allianceid:
   1830             return mapcommon.COLOR_STANDINGS_GOOD
   1831         standingSvc = sm.GetService('standing')
   1832         standings = [standingSvc.GetStanding(session.charid, factionID) or 0, standingSvc.GetStanding(session.corpid, factionID) or 0, standingSvc.GetStanding(session.allianceid, factionID) or 0]
   1833         standings = [ s for s in standings if s != 0 ]
   1834         standing = 0 if len(standings) == 0 else max(standings)
   1835         if standing == 0:
   1836             color = mapcommon.COLOR_STANDINGS_NEUTRAL
   1837         elif standing > 0:
   1838             color = mapcommon.COLOR_STANDINGS_GOOD
   1839         else:
   1840             color = mapcommon.COLOR_STANDINGS_BAD
   1841         return color
   1842 
   1843     def _GetFactionIDFromSolarSystem(self, allianceSolarSystems, solarSystemID):
   1844         if solarSystemID in allianceSolarSystems:
   1845             return allianceSolarSystems[solarSystemID]
   1846         else:
   1847             return self.GetKnownSolarSystem(solarSystemID).factionID
   1848 
   1849     def ShowPath(self, path):
   1850         if path:
   1851             linesToHighlight = []
   1852             for fromID, toID in Pairwise(path):
   1853                 linesToHighlight.append(self.GetLineIDForJumpBetweenSystems(fromID, toID))
   1854 
   1855             self.SetJumpLineColor((1.0, 0.5, 0.0, 0.8), linesToHighlight)
   1856 
   1857     def SetColourGradientToLineBetweenSystems(self, fromID, toID, fromColor, toColor):
   1858         lineSet = self.solarSystemJumpLineSet
   1859         lineSetID = self.GetLineIDForJumpBetweenSystems(fromID, toID)
   1860         jumpInfo = self.jumpLineInfoByLineID[lineSetID]
   1861         if fromID == jumpInfo.fromID:
   1862             self.ChangeLineColor(lineSet, lineSetID, fromColor, toColor)
   1863         else:
   1864             self.ChangeLineColor(lineSet, lineSetID, toColor, fromColor)
   1865 
   1866     @telemetry.ZONE_METHOD
   1867     def ShowDestinationPath(self):
   1868 
   1869         def GetSystemColorBasedOnSecRating(ssID):
   1870             c = self.map.GetModifiedSystemColor(ssID)
   1871             return (c[0],
   1872              c[1],
   1873              c[2],
   1874              1.0)
   1875 
   1876         if self.destinationPath[0] is not None:
   1877             destPath = [ locationID for locationID in self.destinationPath if idCheckers.IsSolarSystem(locationID) ]
   1878             if len(destPath) == 0:
   1879                 return
   1880             if destPath[0] != session.solarsystemid2 and IsKnownSpaceSystem(session.solarsystemid2):
   1881                 destPath = [session.solarsystemid2] + destPath
   1882             for fromID, toID in Pairwise(destPath):
   1883                 if fromID == toID:
   1884                     continue
   1885                 self.SetColourGradientToLineBetweenSystems(fromID, toID, GetSystemColorBasedOnSecRating(fromID), GetSystemColorBasedOnSecRating(toID))
   1886 
   1887     @telemetry.ZONE_METHOD
   1888     def HighlightNeighborStars(self, solarSystemID = None):
   1889         interest = self.GetInterest()
   1890         if solarSystemID is None:
   1891             solarSystemID = interest.solarSystemID
   1892         self.SetStarParticleAlpha(0.5)
   1893         self.SetStarParticleAlpha(1.0, [self.solarSystemIDToParticleID[solarSystemID]])
   1894         systemsByDistance = self.clientPathfinderService.GetSystemsWithinJumpRange(solarSystemID, 1, 3)
   1895         for distance, systemIDs in systemsByDistance.iteritems():
   1896             if distance == 1:
   1897                 alpha = 0.8
   1898             else:
   1899                 alpha = 0.7
   1900             pointIDs = [ self.solarSystemIDToParticleID[systemID] for systemID in systemIDs ]
   1901             self.SetStarParticleAlpha(alpha, pointIDs)
   1902 
   1903         self.starParticles.UpdateData()
   1904 
   1905     def RegisterStarColorModes(self):
   1906         self.starColorHandlers = {mapcommon.STARMODE_ASSETS: (localization.GetByLabel('UI/Map/StarMap/ShowAssets'), starModeHandler.ColorStarsByAssets),
   1907          mapcommon.STARMODE_VISITED: (localization.GetByLabel('UI/Map/StarMap/ShowSystemsVisited'), starModeHandler.ColorStarsByVisited),
   1908          mapcommon.STARMODE_SECURITY: (localization.GetByLabel('UI/Map/StarMap/SecurityStatus'), starModeHandler.ColorStarsBySecurity),
   1909          mapcommon.STARMODE_INDEX_STRATEGIC: (localization.GetByLabel('UI/Map/StarMap/Strategic'),
   1910                                               starModeHandler.ColorStarsByDevIndex,
   1911                                               const.attributeDevIndexSovereignty,
   1912                                               localization.GetByLabel('UI/Map/StarMap/Strategic')),
   1913          mapcommon.STARMODE_INDEX_MILITARY: (localization.GetByLabel('UI/Map/StarMap/Military'),
   1914                                              starModeHandler.ColorStarsByDevIndex,
   1915                                              const.attributeDevIndexMilitary,
   1916                                              localization.GetByLabel('UI/Map/StarMap/Military')),
   1917          mapcommon.STARMODE_INDEX_INDUSTRY: (localization.GetByLabel('UI/Map/StarMap/Industry'),
   1918                                              starModeHandler.ColorStarsByDevIndex,
   1919                                              const.attributeDevIndexIndustrial,
   1920                                              localization.GetByLabel('UI/Map/StarMap/Industry')),
   1921          mapcommon.STARMODE_SOV_CHANGE: (localization.GetByLabel('UI/Map/StarMap/RecentSovereigntyChanges'), starModeHandler.ColorStarsBySovChanges, mapcommon.SOV_CHANGES_ALL),
   1922          mapcommon.STARMODE_SOV_GAIN: (localization.GetByLabel('UI/Map/StarMap/SovereigntyGain'), starModeHandler.ColorStarsBySovChanges, mapcommon.SOV_CHANGES_SOV_GAIN),
   1923          mapcommon.STARMODE_SOV_LOSS: (localization.GetByLabel('UI/Map/StarMap/SovereigntyLoss'), starModeHandler.ColorStarsBySovChanges, mapcommon.SOV_CHANGES_SOV_LOST),
   1924          mapcommon.STARMODE_SOV_STANDINGS: (localization.GetByLabel('UI/Map/StarMap/Standings'), starModeHandler.ColorStarsByFactionStandings),
   1925          mapcommon.STARMODE_FACTION: (localization.GetByLabel('UI/Map/StarMap/SovereigntyMap'), starModeHandler.ColorStarsByFaction),
   1926          mapcommon.STARMODE_FACTIONEMPIRE: (localization.GetByLabel('UI/Map/StarMap/SovereigntyMap'), starModeHandler.ColorStarsByFaction),
   1927          mapcommon.STARMODE_MILITIA: (localization.GetByLabel('UI/Map/StarMap/FactionalWarfare'), starModeHandler.ColorStarsByMilitia),
   1928          mapcommon.STARMODE_REGION: (localization.GetByLabel('UI/Map/StarMap/ColorStarsByRegion'), starModeHandler.ColorStarsByRegion),
   1929          mapcommon.STARMODE_CARGOILLEGALITY: (localization.GetByLabel('UI/Map/StarMap/MyCargoIllegality'), starModeHandler.ColorStarsByCargoIllegality),
   1930          mapcommon.STARMODE_PLAYERCOUNT: (localization.GetByLabel('UI/Map/StarMap/ShowPilotsInSpace'), starModeHandler.ColorStarsByNumPilots),
   1931          mapcommon.STARMODE_PLAYERDOCKED: (localization.GetByLabel('UI/Map/StarMap/ShowPilotsDocked'), starModeHandler.ColorStarsByNumPilots),
   1932          mapcommon.STARMODE_STATIONCOUNT: (localization.GetByLabel('UI/Map/StarMap/ShowStationCount'), starModeHandler.ColorStarsByStationCount),
   1933          mapcommon.STARMODE_DUNGEONS: (localization.GetByLabel('UI/Map/StarMap/ShowDeadspaceComplexes'), starModeHandler.ColorStarsByDungeons),
   1934          mapcommon.STARMODE_DUNGEONSAGENTS: (localization.GetByLabel('UI/Map/StarMap/ShowAgentSites'), starModeHandler.ColorStarsByDungeons),
   1935          mapcommon.STARMODE_JUMPS1HR: (localization.GetByLabel('UI/Map/StarMap/ShowRecentJumps'), starModeHandler.ColorStarsByJumps1Hour),
   1936          mapcommon.STARMODE_SHIPKILLS1HR: (localization.GetByLabel('UI/Map/StarMap/ShowShipsDestroyed'),
   1937                                            starModeHandler.ColorStarsByKills,
   1938                                            const.mapHistoryStatKills,
   1939                                            1),
   1940          mapcommon.STARMODE_SHIPKILLS24HR: (localization.GetByLabel('UI/Map/StarMap/ShowShipsDestroyed'),
   1941                                             starModeHandler.ColorStarsByKills,
   1942                                             const.mapHistoryStatKills,
   1943                                             24),
   1944          mapcommon.STARMODE_MILITIAKILLS1HR: (localization.GetByLabel('UI/Map/StarMap/ShowMilitiaShipsDestroyed'),
   1945                                               starModeHandler.ColorStarsByKills,
   1946                                               const.mapHistoryStatFacWarKills,
   1947                                               1),
   1948          mapcommon.STARMODE_MILITIAKILLS24HR: (localization.GetByLabel('UI/Map/StarMap/ShowMilitiaShipsDestroyed'),
   1949                                                starModeHandler.ColorStarsByKills,
   1950                                                const.mapHistoryStatFacWarKills,
   1951                                                24),
   1952          mapcommon.STARMODE_PODKILLS1HR: (localization.GetByLabel('UI/Map/StarMap/ShowMilitiaShipsDestroyed'), starModeHandler.ColorStarsByPodKills),
   1953          mapcommon.STARMODE_PODKILLS24HR: (localization.GetByLabel('UI/Map/StarMap/ShowMilitiaShipsDestroyed'), starModeHandler.ColorStarsByPodKills),
   1954          mapcommon.STARMODE_FACTIONKILLS1HR: (localization.GetByLabel('UI/Map/StarMap/ShowFactionShipsDestroyed'), starModeHandler.ColorStarsByFactionKills),
   1955          mapcommon.STARMODE_BOOKMARKED: (localization.GetByLabel('UI/Map/StarMap/ShowBookmarks'), starModeHandler.ColorStarsByBookmarks),
   1956          mapcommon.STARMODE_CYNOSURALFIELDS: (localization.GetByLabel('UI/Map/StarMap/ActiveCynosuralFields'), starModeHandler.ColorStarsByCynosuralFields),
   1957          mapcommon.STARMODE_CORPOFFICES: (localization.GetByLabel('UI/Map/StarMap/ShowAssets'),
   1958                                           starModeHandler.ColorStarsByCorpAssets,
   1959                                           'offices',
   1960                                           localization.GetByLabel('UI/Map/StarMap/Offices')),
   1961          mapcommon.STARMODE_CORPIMPOUNDED: (localization.GetByLabel('UI/Map/StarMap/ShowAssets'),
   1962                                             starModeHandler.ColorStarsByCorpAssets,
   1963                                             'impounded',
   1964                                             localization.GetByLabel('UI/Map/StarMap/Impounded')),
   1965          mapcommon.STARMODE_CORPPROPERTY: (localization.GetByLabel('UI/Map/StarMap/ShowAssets'),
   1966                                            starModeHandler.ColorStarsByCorpAssets,
   1967                                            'property',
   1968                                            localization.GetByLabel('UI/Map/StarMap/Property')),
   1969          mapcommon.STARMODE_CORPDELIVERIES: (localization.GetByLabel('UI/Map/StarMap/ShowAssets'),
   1970                                              starModeHandler.ColorStarsByCorpAssets,
   1971                                              'deliveries',
   1972                                              localization.GetByLabel('UI/Map/StarMap/Deliveries')),
   1973          mapcommon.STARMODE_CORPWRAPS: (localization.GetByLabel('UI/Map/StarMap/ShowAssetWraps'),
   1974                                         starModeHandler.ColorStarsByCorpAssets,
   1975                                         'assetwraps',
   1976                                         localization.GetByLabel('UI/Corporations/Assets/AssetSafety')),
   1977          mapcommon.STARMODE_FRIENDS_FLEET: (localization.GetByLabel('UI/Map/StarMap/FindAssociates'), starModeHandler.ColorStarsByFleetMembers),
   1978          mapcommon.STARMODE_FRIENDS_CORP: (localization.GetByLabel('UI/Map/StarMap/FindAssociates'), starModeHandler.ColorStarsByCorpMembers),
   1979          mapcommon.STARMODE_FRIENDS_AGENT: (localization.GetByLabel('UI/Map/StarMap/FindAssociates'), starModeHandler.ColorStarsByMyAgents),
   1980          mapcommon.STARMODE_JUMP_CLONES: (localization.GetByLabel('UI/Map/StarMap/ShowJumpClones'), starModeHandler.ColorStarsByJumpClones),
   1981          mapcommon.STARMODE_AVOIDANCE: (localization.GetByLabel('UI/Map/StarMap/AvoidanceSystems'), starModeHandler.ColorStarsByAvoidedSystems),
   1982          mapcommon.STARMODE_REAL: (localization.GetByLabel('UI/Map/StarMap/ActualColor'), starModeHandler.ColorStarsByRealSunColor),
   1983          mapcommon.STARMODE_SERVICE: (localization.GetByLabel('UI/Map/StarMap/FindStationServices'), starModeHandler.ColorStarsByServices),
   1984          mapcommon.STARMODE_PISCANRANGE: (localization.GetByLabel('UI/Map/StarMap/PlanetScanRange'), starModeHandler.ColorStarsByPIScanRange),
   1985          mapcommon.STARMODE_MYCOLONIES: (localization.GetByLabel('UI/Map/StarMap/MyColonies'), starModeHandler.ColorStarsByMyColonies),
   1986          mapcommon.STARMODE_PLANETTYPE: (localization.GetByLabel('UI/Map/StarMap/ShowSystemsByPlanetTypes'), starModeHandler.ColorStarsByPlanetType),
   1987          mapcommon.STARMODE_INCURSION: (localization.GetByLabel('UI/Map/StarMap/Incursions'), starModeHandler.ColorStarsByIncursions),
   1988          mapcommon.STARMODE_SYSTEM_INTERFERENCE: (localization.GetByLabel('UI/Map/MapPallet/SolarSystemInterference'), starModeHandler.ColorStarsByInterference, self.solarsystemInterferenceSvc),
   1989          mapcommon.STARMODE_ROAMING_WEATHER: (localization.GetByLabel('UI/Map/StarMap/RoamingWeather'), starModeHandler.ColorStarsByRoamingWeather),
   1990          mapcommon.STARMODE_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, None),
   1991          mapcommon.STARMODE_MANUFACTURING_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, industry.MANUFACTURING),
   1992          mapcommon.STARMODE_RESEARCHTIME_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, industry.RESEARCH_TIME),
   1993          mapcommon.STARMODE_RESEARCHMATERIAL_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, industry.RESEARCH_MATERIAL),
   1994          mapcommon.STARMODE_COPY_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, industry.COPYING),
   1995          mapcommon.STARMODE_INVENTION_JOBS24HOUR: (localization.GetByLabel('UI/Map/StarMap/JobsLast24Hours'), starModeHandler.ColorStarsByJobs24Hours, industry.INVENTION),
   1996          mapcommon.STARMODE_INDUSTRY_MANUFACTURING_COST_INDEX: (localization.GetByLabel('UI/Map/StarMap/IndustryCostModifer'), starModeHandler.ColorStarsByIndustryCostModifier, industry.MANUFACTURING),
   1997          mapcommon.STARMODE_INDUSTRY_RESEARCHTIME_COST_INDEX: (localization.GetByLabel('UI/Map/StarMap/IndustryCostModifer'), starModeHandler.ColorStarsByIndustryCostModifier, industry.RESEARCH_TIME),
   1998          mapcommon.STARMODE_INDUSTRY_RESEARCHMATERIAL_COST_INDEX: (localization.GetByLabel('UI/Map/StarMap/IndustryCostModifer'), starModeHandler.ColorStarsByIndustryCostModifier, industry.RESEARCH_MATERIAL),
   1999          mapcommon.STARMODE_INDUSTRY_COPY_COST_INDEX: (localization.GetByLabel('UI/Map/StarMap/IndustryCostModifer'), starModeHandler.ColorStarsByIndustryCostModifier, industry.COPYING),
   2000          mapcommon.STARMODE_INDUSTRY_INVENTION_COST_INDEX: (localization.GetByLabel('UI/Map/StarMap/IndustryCostModifer'), starModeHandler.ColorStarsByIndustryCostModifier, industry.INVENTION),
   2001          mapcommon.STARMODE_INSURGENCY: (localization.GetByLabel('UI/PirateInsurgencies/dashboardCaption'),
   2002                                          starModeHandler.ColorStarsByInsurgencyInvolvement,
   2003                                          self.insurgencyCampaignSvc,
   2004                                          self.corruptionSuppressionSvc),
   2005          mapcommon.STARMODE_INSURGENCY_CORRUPTION: (localization.GetByLabel('UI/PirateInsurgencies/dashboardCaption'),
   2006                                                     starModeHandler.ColorStarsByInsurgencyCorruption,
   2007                                                     self.insurgencyCampaignSvc,
   2008                                                     self.corruptionSuppressionSvc),
   2009          mapcommon.STARMODE_INSURGENCY_SUPPRESSION: (localization.GetByLabel('UI/PirateInsurgencies/dashboardCaption'),
   2010                                                      starModeHandler.ColorStarsByInsurgencySuppression,
   2011                                                      self.insurgencyCampaignSvc,
   2012                                                      self.corruptionSuppressionSvc)}
   2013         if session.role & ROLE_GML:
   2014             self.starColorHandlers[mapcommon.STARMODE_INCURSIONGM] = (localization.GetByLabel('UI/Map/StarMap/IncursionsGm'), starModeHandler.ColorStarsByIncursionsGM)
   2015 
   2016     @telemetry.ZONE_METHOD
   2017     def SetStarColorMode(self, starColorMode = None):
   2018         if starColorMode is None:
   2019             starColorMode = GetUserUiSetting('starscolorby', mapcommon.STARMODE_SECURITY)
   2020         self.LogInfo('SetStarColorMode ', starColorMode)
   2021         self.starData = {}
   2022         self.starLegend = []
   2023         mode = starColorMode[0] if isinstance(starColorMode, tuple) else starColorMode
   2024         definition = self.starColorHandlers.get(mode, (localization.GetByLabel('UI/Map/StarMap/ActualColor'), starModeHandler.ColorStarsByRealSunColor))
   2025         desc, colorFunc, args = definition[0], definition[1], definition[2:]
   2026         self.StartLoadingBar('set_star_color', localization.GetByLabel('UI/Map/StarMap/GettingData'), desc, 2)
   2027         blue.pyos.synchro.SleepWallclock(1)
   2028         colorInfo = utillib.KeyVal(solarSystemDict={}, colorList=None, overglowFactor=0.0, legend=set())
   2029         colorFunc(colorInfo, starColorMode, *args)
   2030         self.starLegend = list(colorInfo.legend)
   2031         self.UpdateLoadingBar('set_star_color', desc, localization.GetByLabel('UI/Map/StarMap/GettingData'), 1, 2)
   2032         blue.pyos.synchro.SleepWallclock(1)
   2033         self.HighlightSolarSystems(colorInfo.solarSystemDict, colorInfo.colorList, colorInfo.overglowFactor)
   2034         self.StopLoadingBar('set_star_color')
   2035 
   2036     def _BuildWarFactionByOwner(self, stations):
   2037         self.warFactionByOwner = {}
   2038         for stationRow in stations:
   2039             ownerID = stationRow.ownerID
   2040             if ownerID not in self.warFactionByOwner:
   2041                 factionID = get_corporation_faction_id(ownerID)
   2042                 if factionID and IsAnyFWFaction(factionID):
   2043                     self.warFactionByOwner[ownerID] = factionID
   2044 
   2045     def GetWarFactionByOwner(self, stations):
   2046         if self.warFactionByOwner is None:
   2047             self._BuildWarFactionByOwner(stations)
   2048         return self.warFactionByOwner
   2049 
   2050     def GetRegionColor(self, regionID):
   2051         if not hasattr(self, 'regionColorCache'):
   2052             self.regionColorCache = {}
   2053         if regionID not in self.regionColorCache:
   2054             color = trinity.TriColor()
   2055             color.SetHSV(float(regionID) * 21 % 360.0, 0.5, 0.8)
   2056             color.a = 0.75
   2057             self.regionColorCache[regionID] = color
   2058         return self.regionColorCache[regionID]
   2059 
   2060     def GetColorCurve(self, colorList):
   2061         colorCurve = trinity.Tr2CurveColor()
   2062         colorListDivisor = float(len(colorList) - 1)
   2063         for colorID, colorValue in enumerate(colorList):
   2064             time = float(colorID) / colorListDivisor
   2065             if isinstance(colorValue, trinity.TriColor):
   2066                 colorValue = (colorValue.r,
   2067                  colorValue.g,
   2068                  colorValue.b,
   2069                  colorValue.a)
   2070             colorCurve.AddKey(time, colorValue, trinity.Tr2CurveInterpolation.LINEAR)
   2071 
   2072         return colorCurve
   2073 
   2074     def GetColorCurveValue(self, colorCurve, time):
   2075         return colorCurve.GetValueAt(time)
   2076 
   2077     @telemetry.ZONE_METHOD
   2078     def HighlightSolarSystems(self, solarSystemDict, colorList = None, overglowFactor = 0.0):
   2079         self.starData = {}
   2080         colorCurve = self.GetColorCurve(colorList or self.GetDefaultColorList())
   2081         self.overglowFactor.value = overglowFactor
   2082         particleSizeToParticleIDs = defaultdict(list)
   2083         particleColorToParticleIDs = defaultdict(list)
   2084         for particleID, solarSystemID in self.particleIDToSystemIDMap.iteritems():
   2085             starColor = NEUTRAL_COLOR
   2086             starSize = SUNBASE
   2087             if solarSystemID in solarSystemDict and solarSystemDict[solarSystemID] is not None:
   2088                 size, age, commentCallback, uniqueColor = solarSystemDict[solarSystemID]
   2089                 size *= SUNBASE
   2090                 if uniqueColor is None:
   2091                     col = self.GetColorCurveValue(colorCurve, age)
   2092                 else:
   2093                     col = uniqueColor
   2094                 if commentCallback:
   2095                     self.starData[particleID] = commentCallback
   2096                 if isinstance(col, trinity.TriColor):
   2097                     starColor = (col.r,
   2098                      col.g,
   2099                      col.b,
   2100                      1.0)
   2101                 else:
   2102                     starColor = col
   2103                 starSize = size
   2104             particleSizeToParticleIDs[starSize].append(particleID)
   2105             particleColorToParticleIDs[starColor].append(particleID)
   2106 
   2107         for starSize, particleIDs in particleSizeToParticleIDs.iteritems():
   2108             self.SetStarParticleSize(starSize, tuple(particleIDs))
   2109 
   2110         for starColor, particleIDs in particleColorToParticleIDs.iteritems():
   2111             self.SetStarParticleColor(starColor, tuple(particleIDs))
   2112 
   2113         self.starParticles.UpdateData()
   2114         self.mapStars.display = 1
   2115 
   2116     def GetDefaultColorList(self):
   2117         return [(1.0, 0.0, 0.0, 1.0), (1.0, 1.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0)]
   2118 
   2119     @telemetry.ZONE_METHOD
   2120     def HighlightSolarSystemsBulk(self, solarSystemList, size, colorList = None):
   2121         self.starData = {}
   2122         if colorList is None:
   2123             colorList = (1.0, 0.0, 0.0)
   2124         else:
   2125             colorList = (colorList[0].r, colorList[0].g, colorList[0].b)
   2126         particles2highlight = []
   2127         for solarSystemID, comment in solarSystemList:
   2128             particleID = self.GetCloudNumFromItemID(solarSystemID)
   2129             particles2highlight.append(particleID)
   2130             if comment:
   2131                 if len(comment):
   2132                     self.starData[particleID] = comment
   2133 
   2134         self.SetStarParticleColor(NEUTRAL_COLOR[:3])
   2135         self.SetStarParticleColor(colorList, particles2highlight)
   2136         self.starParticles.UpdateData()
   2137         self.mapStars.display = 1
   2138 
   2139     def GetRegionLabel(self, labelID):
   2140         return self.regionLabels[labelID]
   2141 
   2142     def GetRouteType(self, label = False):
   2143         pfRouteType = GetUserUiSetting('pfRouteType', 'safe')
   2144         if label:
   2145             return {'shortest': localization.GetByLabel('UI/Map/StarMap/Shortest'),
   2146              'safe': localization.GetByLabel('UI/Map/StarMap/Safest'),
   2147              'unsafe': localization.GetByLabel('UI/Map/StarMap/LessSecure')}.get(pfRouteType, localization.GetByLabel('UI/Common/Unknown')).lower()
   2148         return pfRouteType
   2149 
   2150     def _IsDestinationValid(self, destinationID):
   2151         if not IsValidDestination(destinationID):
   2152             return False
   2153         if idCheckers.IsStation(destinationID) and destinationID in cfg.stations:
   2154             stationInfo = sm.GetService('ui').GetStationStaticInfo(destinationID)
   2155             if IsDeprecatedStation(stationInfo.stationTypeID):
   2156                 return False
   2157             destinationSolarSystemID = stationInfo.solarSystemID
   2158             if IsTriglavianSystem(destinationSolarSystemID) and not IsTriglavianSystem(session.solarsystemid2):
   2159                 return False
   2160             isDestinationInSameSolarSystem = destinationSolarSystemID == session.solarsystemid2
   2161             isDestinationInKnownSpace = IsKnownSpaceSystem(destinationSolarSystemID)
   2162             return bool(isDestinationInSameSolarSystem or isDestinationInKnownSpace)
   2163         if IsTriglavianSystem(destinationID) and not IsTriglavianSystem(session.solarsystemid2):
   2164             return False
   2165         if destinationID in self.GetKnownUniverseSolarSystems():
   2166             return True
   2167         return sm.GetService('structureDirectory').GetStructureInfo(destinationID) is not None
   2168 
   2169     def OnDestinationChange(self, solarSystemID, clearOtherWaypoints, first):
   2170         sm.GetService('autoPilot').SetOff('Waypoints set remotely.')
   2171         self.SetWaypoint(solarSystemID, clearOtherWaypoints, first)
   2172 
   2173     @telemetry.ZONE_METHOD
   2174     def SetWaypoint(self, destinationID, clearOtherWaypoints = False, first = False, origin = None):
   2175         waypoints = self.GetWaypoints()
   2176         if not self._IsDestinationValid(destinationID):
   2177             prompt_player_fsd_dialog('Command', {'command': localization.GetByLabel('UI/Map/StarMap/CantSetWaypoint')})
   2178             return
   2179         if clearOtherWaypoints:
   2180             if len(waypoints):
   2181                 pass
   2182             waypoints = []
   2183         if destinationID in waypoints:
   2184             prompt_player_fsd_dialog('WaypointAlreadySet')
   2185             return
   2186         if destinationID == session.constellationid:
   2187             prompt_player_fsd_dialog('WaypointAlreadyInConstellation')
   2188             return
   2189         if destinationID == session.regionid:
   2190             prompt_player_fsd_dialog('WaypointAlreadyInRegion')
   2191             return
   2192         if first:
   2193             waypoints.insert(0, destinationID)
   2194         else:
   2195             waypoints.append(destinationID)
   2196         SetCharUiSetting('autopilot_waypoints', waypoints)
   2197         self.UpdateRoute()
   2198         self.ShowWhereIAm()
   2199         self.autoPilot.VerifyJumpGatesInRoute()
   2200         if clearOtherWaypoints:
   2201             sm.ScatterEvent('OnClientEvent_DestinationSet', destinationID)
   2202         current_location_id = session.solarsystemid2
   2203         if session.stationid:
   2204             current_location_id = session.stationid
   2205         if session.structureid:
   2206             current_location_id = session.structureid
   2207         send_set_waypoint_analytics_event(current_location_id, destinationID, clearOtherWaypoints, origin, sm.GetService('publicGatewaySvc'))
   2208 
   2209     def SetWaypoints(self, waypoints):
   2210         self.LogInfo('SetWaypoints')
   2211         SetCharUiSetting('autopilot_waypoints', waypoints)
   2212         self.UpdateRoute()
   2213         self.autoPilot.VerifyJumpGatesInRoute()
   2214 
   2215     def GetWaypoints(self):
   2216         waypoints = GetCharUiSetting('autopilot_waypoints', [])
   2217         for waypoint in waypoints:
   2218             if not self._IsDestinationValid(waypoint):
   2219                 return []
   2220 
   2221         return waypoints
   2222 
   2223     @telemetry.ZONE_METHOD
   2224     def ClearWaypoints(self, locationID = None):
   2225         self.LogInfo('Map: ClearWaypoints')
   2226         if locationID is not None:
   2227             waypoints = self.GetWaypoints()
   2228             if locationID in waypoints:
   2229                 waypoints.remove(locationID)
   2230                 SetCharUiSetting('autopilot_waypoints', waypoints)
   2231                 self.UpdateRoute()
   2232                 self.ShowWhereIAm()
   2233                 self.UpdateLines(hint='ClearWaypoints', updateColor=True)
   2234                 sm.ScatterEvent('OnDestinationCleared')
   2235                 return
   2236             self.LogError('Utried to remove waypoint %s  that was not in waypoint list %s ' % (locationID, waypoints))
   2237         else:
   2238             waypoints = []
   2239             self.destinationPath = [None]
   2240         SetCharUiSetting('autopilot_waypoints', waypoints)
   2241         if not self.doingLogoff:
   2242             sm.ScatterEvent('OnDestinationSet', self.destinationPath[0])
   2243         if self.mapRoot:
   2244             self.ClearRoute('autoPilotRoute')
   2245             self.UpdateLines(hint='ClearWaypoints', updateColor=True)
   2246             self.ShowDestination()
   2247             self.CheckAllLabels('ClearWaypoints')
   2248         sm.ScatterEvent('OnDestinationCleared')
   2249 
   2250     def RemoveWaypointIfFirst(self, locationID):
   2251         waypoints = self.GetWaypoints()
   2252         if waypoints and waypoints[0] == locationID:
   2253             self.ClearWaypoints(locationID)
   2254 
   2255     @telemetry.ZONE_METHOD
   2256     def GetRouteFromWaypoints(self, waypoints, startSystem = None):
   2257         if startSystem is None:
   2258             startSystem = session.solarsystemid2
   2259         if not IsKnownSpaceSystem(startSystem):
   2260             fullWaypointList = waypoints
   2261         else:
   2262             fullWaypointList = [startSystem] + waypoints
   2263         if len(fullWaypointList) <= 1:
   2264             return fullWaypointList
   2265         self.LogInfo('Calling pathfinder with waypoint list', str(waypoints))
   2266         destinationPath = self.clientPathfinderService.GetWaypointPath(fullWaypointList)
   2267         return destinationPath or []
   2268 
   2269     @telemetry.ZONE_METHOD
   2270     def GetRouteBetween(self, fromID, toID):
   2271         self.LogInfo('Getting route between %s and %s', fromID, toID)
   2272         route = self.clientPathfinderService.GetAutopilotPathBetween(fromID, toID)
   2273         return route or []
   2274 
   2275     @telemetry.ZONE_METHOD
   2276     def UpdateRoute(self, updateLabels = 1, fakeUpdate = 0, autopilotSaysRouteDone = False):
   2277         if not updateLabels:
   2278             if getattr(self, 'doingRouteUpdate', 0) == 1:
   2279                 return
   2280         self.doingRouteUpdate = 1
   2281         waypoints = self.GetWaypoints()
   2282         self.LogInfo('UpdateRoute - waypoints ', waypoints)
   2283         if len(waypoints):
   2284             for each in [session.structureid,
   2285              session.stationid,
   2286              session.solarsystemid2,
   2287              session.constellationid,
   2288              session.regionid]:
   2289                 if waypoints[0] == each:
   2290                     waypoints = waypoints[1:]
   2291                     SetCharUiSetting('autopilot_waypoints', waypoints)
   2292                     if GetUserUiSetting('autopilot_stop_at_each_waypoint', 0) == 0:
   2293                         if self.autoPilot.GetState():
   2294                             self.autoPilot.SetOff('  - waypoint reached')
   2295                     break
   2296 
   2297         self.ClearRoute('autoPilotRoute')
   2298         if not len(waypoints):
   2299             self.destinationPath = [None]
   2300             if self.viewState.IsViewActive('starmap'):
   2301                 self.UpdateLines(hint='UpdateRoute')
   2302             self.ShowDestination()
   2303             sm.ScatterEvent('OnDestinationSet', None)
   2304             self.LogInfo('UpdateRoute done no wp')
   2305             self.doingRouteUpdate = 0
   2306             return
   2307         if not fakeUpdate or not hasattr(self, 'destinationPath') or self.destinationPath[0] != session.solarsystemid:
   2308             self.LogInfo('Getting route from waypoints')
   2309             destinationPath = self.GetRouteFromWaypoints(waypoints)
   2310         else:
   2311             destinationPath = self.destinationPath[1:]
   2312         if not len(destinationPath):
   2313             if len(self.destinationPath) and (idCheckers.IsSolarSystem(self.destinationPath[0]) or self.destinationPath[0] is None or autopilotSaysRouteDone):
   2314                 self.destinationPath = [None]
   2315                 if self.viewState.IsViewActive('starmap'):
   2316                     self.UpdateLines(hint='UpdateRoute2')
   2317                 self.ShowDestination()
   2318                 sm.ScatterEvent('OnDestinationSet', None)
   2319                 self.LogInfo('UpdateRoute done no route to wp')
   2320                 self.doingRouteUpdate = 0
   2321                 return
   2322             destinationPath = self.destinationPath
   2323         self.destinationPath = destinationPath
   2324         if self.destinationPath[0] == session.solarsystemid2:
   2325             self.LogWarn('self destination path 0 is own solarsystem, picking next node instead. Path: ', self.destinationPath)
   2326             self.destinationPath = self.destinationPath[1:]
   2327             if not len(self.destinationPath):
   2328                 self.destinationPath = [None]
   2329         if self.viewState.IsViewActive('starmap'):
   2330             if updateLabels:
   2331                 route = MapRoute()
   2332                 pathOnlySolarSystems = [ locationID for locationID in destinationPath if idCheckers.IsSolarSystem(locationID) ]
   2333                 route.DrawRoute([session.solarsystemid2] + pathOnlySolarSystems, flattened=self.flattened, rotationQuaternion=self.GetCurrentStarmapRotation())
   2334                 self.autoPilotRoute = route
   2335                 scene = self.sceneManager.GetRegisteredScene('starmap')
   2336                 scene.objects.append(route.model)
   2337                 self.ShowDestination()
   2338                 self.CheckAllLabels('UpdateRoute')
   2339             self.UpdateLines(hint='UpdateRoute3', updateColor=True)
   2340         if updateLabels:
   2341             sm.ScatterEvent('OnDestinationSet', self.destinationPath[0])
   2342         self.LogInfo('UpdateRoute done')
   2343         self.doingRouteUpdate = 0
   2344 
   2345     def GetCurrentStarmapRotation(self):
   2346         if len(self.mapRoot.rotationCurve.curve.keys) > 0:
   2347             return self.mapRoot.rotationCurve.curve.keys[-1][1]
   2348         else:
   2349             return None
   2350 
   2351     @telemetry.ZONE_METHOD
   2352     def SetTileMode(self, tileMode):
   2353         SetUserUiSetting('map_tile_mode', tileMode)
   2354         SetUserUiSetting('map_tile_no_tiles', 0)
   2355         sm.ScatterEvent('OnLoadWMCPSettings', 'mapsettings_tiles')
   2356         if not self.IsFlat() and GetUserUiSetting('map_tile_show_unflattened', 0) == 0:
   2357             self.Flatten()
   2358         self.UpdateHexMap()
   2359 
   2360     @telemetry.ZONE_METHOD
   2361     def UpdateHexMap(self, isFlat = None):
   2362         showHexMap = GetUserUiSetting('map_tile_no_tiles', 1) == 0
   2363         showUnflattened = GetUserUiSetting('map_tile_show_unflattened', 0)
   2364         self.tileLegend = []
   2365         if isFlat is None:
   2366             isFlat = self.IsFlat()
   2367         if showHexMap and (showUnflattened or isFlat):
   2368             systemToAllianceMap = self.GetAllianceSolarSystems()
   2369             changeList = []
   2370             if GetUserUiSetting('map_tile_activity', 0) == 1:
   2371                 changeList = sm.GetService('sov').GetRecentActivity()
   2372             tileMode = GetUserUiSetting('map_tile_mode', TILE_MODE_SOVEREIGNTY)
   2373             colorByStandings = tileMode == TILE_MODE_STANDIGS
   2374             self.hexMap.LayoutTiles(HEX_TILE_SIZE, systemToAllianceMap, changeList, colorByStandings)
   2375             self.hexMap.Enable()
   2376             showOutlines = GetUserUiSetting('map_tile_show_outlines', 1) == 1
   2377             self.hexMap.EnableOutlines(showOutlines)
   2378             self.tileLegend = self.hexMap.legend
   2379         else:
   2380             self.hexMap.Enable(False)
   2381 
   2382     def HighlightTiles(self, dataList, colorList):
   2383         self.hexMap.HighlightTiles(dataList, colorList)
   2384 
   2385     def GetLegend(self, name):
   2386         return getattr(self, name + 'Legend', [])
   2387 
   2388     @telemetry.ZONE_METHOD
   2389     def CreateLabels(self, labelids):
   2390         self.LogInfo('Map Create ', len(labelids), ' labels')
   2391         for labelID in labelids:
   2392             if labelID in self.labels:
   2393                 continue
   2394             if labelID in self.labels:
   2395                 label = self.labels[labelID]
   2396                 if label is not None and not label.destroyed:
   2397                     continue
   2398                 else:
   2399                     del self.labels[labelID]
   2400             self.AddLabel(labelID)
   2401 
   2402     @telemetry.ZONE_METHOD
   2403     def ClearLabels(self, labelids = 'all'):
   2404         labels = getattr(self, 'labels', {})
   2405         if labelids == 'all':
   2406             labelids = labels.keys()
   2407         for labelID in labelids:
   2408             if labelID in labels:
   2409                 label = labels[labelID]
   2410                 if label is not None and not label.destroyed:
   2411                     label.Close()
   2412                 del labels[labelID]
   2413             if self.labeltrackers[labelID] in self.labeltrackersTF.children:
   2414                 self.labeltrackersTF.children.remove(self.labeltrackers[labelID])
   2415 
   2416     def AddLabel(self, itemID):
   2417         if itemID > 0:
   2418             iteminfo = self.map.GetItem(itemID)
   2419             tracker = self.AddTracker(iteminfo.itemName, itemID, iteminfo.x, iteminfo.y, iteminfo.z)
   2420             itemName = iteminfo.itemName
   2421             itemID = iteminfo.itemID
   2422             typeID = iteminfo.typeID
   2423         else:
   2424             lm = self.map.GetLandmark(itemID * -1)
   2425             landmarkName = maputils.GetNameFromMapCache(lm.landmarkNameID, 'landmark')
   2426             tracker = self.AddTracker(landmarkName, itemID, *lm.position)
   2427             itemName = landmarkName
   2428             itemID = itemID
   2429             typeID = const.typeMapLandmark
   2430         if not itemName:
   2431             return
   2432         label = MapLabel(parent=uicore.layer.starmap, name=itemName, align=uiconst.NOALIGN, state=uiconst.UI_PICKCHILDREN, dock=False, width=300, height=32)
   2433         label.Startup(itemName, itemID, typeID, tracker, None)
   2434         self.labels[itemID] = label
   2435 
   2436     @telemetry.ZONE_METHOD
   2437     def AddTracker(self, name, itemID, x = 0.0, y = 0.0, z = 0.0, factor = None):
   2438         if itemID in self.labeltrackers and self.labeltrackers[itemID] not in self.labeltrackersTF.children:
   2439             self.labeltrackersTF.children.append(self.labeltrackers[itemID])
   2440             return self.labeltrackers[itemID]
   2441         tracker = trinity.EveTransform()
   2442         trackPos = (x * STARMAP_SCALE, y * STARMAP_SCALE, z * STARMAP_SCALE)
   2443         tracker.translation = trackPos
   2444         self.labeltrackersTF.children.append(tracker)
   2445         self.labeltrackers[itemID] = tracker
   2446         return tracker
   2447 
   2448     def StartLoadingBar(self, key, tile, action, total):
   2449         if getattr(self, 'loadingBarActive', None) is None:
   2450             self.loading.ProgressWnd(tile, action, 0, total)
   2451             self.loadingBarActive = key
   2452 
   2453     def UpdateLoadingBar(self, key, tile, action, part, total):
   2454         if getattr(self, 'loadingBarActive', None) == key:
   2455             self.loading.ProgressWnd(tile, action, part, total)
   2456 
   2457     def StopLoadingBar(self, key):
   2458         if getattr(self, 'loadingBarActive', None) == key:
   2459             self.loading.StopCycle()
   2460             self.loadingBarActive = None
   2461 
   2462     def _IsOutsideKnownSpaceWithInsufficientWaypoints(self):
   2463         return not IsKnownSpaceSystem(session.solarsystemid2) and len(self.destinationPath) == 1
   2464 
   2465     def GetAutopilotRoute(self):
   2466         if self.destinationPath == [None] or self._IsOutsideKnownSpaceWithInsufficientWaypoints():
   2467             return
   2468         else:
   2469             return self.destinationPath[:]
   2470 
   2471     def OnAutopilotUpdated(self):
   2472         self.UpdateRoute()