infoPanelRoute.py (34467B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\infoPanels\infoPanelRoute.py 2 import random 3 import weakref 4 from collections import deque 5 import eveformat 6 import evelink.client 7 import localization 8 import log 9 import threadutils 10 import uthread 11 import uthread2 12 import utillib 13 from carbon.client.script.environment.AudioUtil import PlaySound 14 from carbon.common.script.util import timerstuff 15 from carbonui import uiconst, TextColor 16 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText 17 from carbonui.control.slider import Slider 18 from carbonui.primitives.container import Container 19 from carbonui.primitives.containerAutoSize import ContainerAutoSize 20 from carbonui.primitives.fill import Fill 21 from carbonui.primitives.sprite import Sprite 22 from carbonui.uianimations import animations 23 from carbonui.uicore import uicore 24 from eve.client.script.ui import eveColor 25 from eve.client.script.ui.control import eveLabel 26 from carbonui.control.button import Button 27 from eve.client.script.ui.shared.autopilotSettings import AutopilotSettings 28 from eve.client.script.ui.shared.infoPanels.InfoPanelBase import InfoPanelBase 29 from eve.client.script.ui.util import searchUtil, uix 30 from eve.client.script.ui.shared.infoPanels.const import infoPanelConst, infoPanelUIConst 31 from eve.common.lib import appConst as const 32 from eve.common.script.search.const import ResultType 33 from eve.common.script.sys import eveCfg, idCheckers 34 from evePathfinder.pathfinderconst import ROUTE_TYPE_SAFE, ROUTE_TYPE_SHORTEST, ROUTE_TYPE_UNSAFE 35 from eveformat.client.location import GetLawlessSystemSecStatusColor 36 from eveservices.menu import GetMenuService 37 from pirateinsurgency.client.dashboard.const import CORRUPTION_STAGES 38 from player_messaging.client.ui_message import prompt_player_fsd_dialog 39 from stackless_response_router.exceptions import TimeoutException, UnpackException 40 from stargate.client.localGates import FindLocalStargate 41 from uihider import UiHiderMixin 42 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst 43 ROUTE_MARKERSIZE = 8 44 ROUTE_MARKERGAP = 2 45 ROUTE_MARKERTYPE_NORMAL = 0 46 ROUTE_MARKERTYPE_STATION = 1 47 ROUTE_MARKERTYPE_WAYPOINT = 2 48 ROUTE_MARKERTYPE_INVASION = 3 49 ROUTE_MARKERTYPE_INSURGENCY = 4 50 NEOCOM_PANELWIDTH = 328 51 FRAME_WIDTH = 20 52 FRAME_SEPERATION = 10 53 IDLE_ROUTEMARKER_ALPHA = 1.0 54 55 def _GetCurrentDestinationLabel(destination_name): 56 if destination_name is None: 57 return localization.GetByLabel('UI/Inflight/NoDestination') 58 destination_label = localization.GetByLabel('UI/Neocom/Autopilot/CurrentDestination') 59 return sm.GetService('infoPanel').GetSolarSystemTrace(destination_name, destination_label) 60 61 62 class InfoPanelRoute(UiHiderMixin, InfoPanelBase): 63 default_name = 'InfoPanelRoute' 64 panelTypeID = infoPanelConst.PANEL_ROUTE 65 label = 'UI/InfoWindow/TabNames/Route' 66 default_iconTexturePath = 'res:/UI/Texture/Classes/InfoPanels/Route.png' 67 hasSettings = True 68 uniqueUiName = pConst.UNIQUE_NAME_INFO_PANEL_ROUTE 69 __notifyevents__ = ['OnDestinationSet', 70 'OnUIRefresh', 71 'OnAutoPilotOn', 72 'OnAutoPilotOff'] 73 74 def ApplyAttributes(self, attributes): 75 super(InfoPanelRoute, self).ApplyAttributes(attributes) 76 self.headerButton.uniqueUiName = pConst.UNIQUE_NAME_AUTOPILOT_SETTINGS 77 sm.RegisterNotify(self) 78 self.routeData = None 79 self.sliderLabel = None 80 self.toAnimate = [] 81 self.utilMenu = None 82 self.header = self.headerCls(parent=self.headerCont, align=uiconst.CENTERLEFT) 83 self.headerCompact = self.headerCls(name='headerCompact', parent=self.headerCompactCont, align=uiconst.CENTERLEFT, state=uiconst.UI_NORMAL) 84 self.headerTrigIcon = TriglavianWarningIcon(parent=self.headerCompactCont, align=uiconst.CENTERRIGHT, idx=0) 85 self.UpdateHeaderTrigIconDisplay() 86 self.noDestinationLabel = eveLabel.EveLabelMedium(name='noDestinationLabel', parent=self.mainCont, text=localization.GetByLabel('UI/Inflight/NoDestination'), align=uiconst.TOTOP, state=uiconst.UI_HIDDEN) 87 self.currentParent = NextWaypointPanel(parent=self.mainCont, align=uiconst.TOTOP) 88 self.markersParent = Container(name='markersParent', parent=self.mainCont, align=uiconst.TOTOP) 89 self.endParent = DestinationWaypointPanel(parent=self.mainCont, align=uiconst.TOTOP) 90 91 def GetSettingsMenu(self, parent): 92 self.utilMenu = weakref.ref(parent) 93 self.AddSearchBox(parent) 94 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/AutopilotActive'), sm.GetService('autoPilot').GetState(), callback=self.OnCheckBoxAutopilotActive, state=uiconst.UI_DISABLED if eveCfg.IsDocked() else uiconst.UI_NORMAL) 95 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/ShowRoutePathInSpace'), settings.user.ui.Get('routeVisualizationEnabled', True), callback=sm.GetService('gameui').routeVisualizer.ToggleRouteVisualization) 96 pfRouteType = sm.GetService('clientPathfinderService').GetAutopilotRouteType() 97 parent.AddRadioButton(localization.GetByLabel('UI/Map/MapPallet/cbPreferShorter'), pfRouteType == ROUTE_TYPE_SHORTEST, callback=(self.OnRadioBtnRouteType, 'shortest'), uniqueUiName=pConst.UNIQUE_NAME_ROUTE_SHORTER) 98 parent.AddRadioButton(localization.GetByLabel('UI/Map/MapPallet/cbPreferSafer'), pfRouteType == ROUTE_TYPE_SAFE, callback=(self.OnRadioBtnRouteType, 'safe'), uniqueUiName=pConst.UNIQUE_NAME_ROUTE_SAFER) 99 parent.AddRadioButton(localization.GetByLabel('UI/Map/MapPallet/cbPreferRisky'), pfRouteType == ROUTE_TYPE_UNSAFE, callback=(self.OnRadioBtnRouteType, 'unsafe')) 100 sliderCont = Container(name='sliderCont', parent=parent, align=uiconst.TOTOP, height=18, padding=(17, 0, 0, 0)) 101 self.securitySlider = Slider(parent=sliderCont, align=uiconst.TOLEFT, width=100, name='pfPenalty', state=uiconst.UI_NORMAL, minValue=1, maxValue=100, labelDecimalPlaces=0, value=settings.char.ui.Get('pfPenalty', 50.0), on_dragging=self.OnSecuritySlider, callback=self.OnSecuritySliderEnd, hint=localization.GetByLabel('UI/Map/MapPallet/hintSecurityPeneltySlider'), padLeft=5) 102 self.sliderLabel = eveLabel.EveLabelSmall(parent=sliderCont, align=uiconst.TOALL, padLeft=5, top=3) 103 self.UpdateSliderLabel(self.securitySlider.value) 104 parent.AddSpace() 105 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/IncludeJumpGates'), settings.char.ui.Get('pathFinder_includeJumpGates', 0), callback=self.OnCheckBoxUseJumpGates, uniqueUiName=pConst.UNIQUE_NAME_ROUTE_INCLUDE_JUMP_GATES) 106 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/cbAdvoidPodkill'), settings.char.ui.Get('pfAvoidPodKill', 0), callback=self.OnCheckBoxAvoidPodKill) 107 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/cbAvoidTriglavianTales'), settings.char.ui.Get('pfAvoidTriglavianTales', 0), callback=self.OnCheckBoxAvoidTriglavianTales) 108 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/cbAvoidEdencomSystems'), settings.char.ui.Get('pfAvoidEdencomSystems', 0), callback=self.OnCheckBoxAvoidEdencomSystems) 109 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/cbAdvoidSystemsOnList'), settings.char.ui.Get('pfAvoidSystems', 1), callback=self.OnCheckBoxAvoidSystems) 110 parent.AddCheckBox(localization.GetByLabel('UI/Map/MapPallet/cbDisableAtEachWaypoint'), settings.user.ui.Get('autopilot_stop_at_each_waypoint', 0) == 0, callback=self.OnCheckBoxDisableAtEachWaypoint) 111 parent.AddDivider() 112 starmapSvc = sm.GetService('starmap') 113 waypoints = starmapSvc.GetWaypoints() 114 if len(waypoints) > 0: 115 parent.AddButton(localization.GetByLabel('UI/Neocom/ClearAllAutopilotWaypoints'), starmapSvc.ClearWaypoints, toggleMode=False) 116 if len(waypoints) > 1: 117 parent.AddButton(localization.GetByLabel('UI/Map/MapPallet/OptimizeRoute'), sm.GetService('autoPilot').OptimizeRoute, toggleMode=False) 118 parent.AddButton(localization.GetByLabel('UI/Map/MapPallet/ManageRoute'), AutopilotSettings.Open, toggleMode=False) 119 120 def AddSearchBox(self, parent): 121 container = parent.AddContainer(padding=6) 122 inpt = SingleLineEditText(name='searchbox', parent=container, align=uiconst.TOPLEFT, width=220, maxLength=64, hintText=localization.GetByLabel('UI/Map/MapPallet/lblSearchForLocation'), OnReturn=lambda *args: self.SearchForLocation(inpt, container, *args)) 123 Button(parent=container, align=uiconst.TOPLEFT, left=inpt.width + 4, label=localization.GetByLabel('UI/Map/MapPallet/btnSearchForLocation'), func=self.SearchForLocation, args=(inpt, container)) 124 parent.AddDivider() 125 126 def SearchForLocation(self, inputField, container, *args): 127 searchText = inputField.GetValue().strip() 128 groupIDList = [ResultType.solar_system, 129 ResultType.constellation, 130 ResultType.region, 131 ResultType.station, 132 ResultType.structure_with_inlined_data] 133 searchUtil.GetResultsInNewWindow(searchText, groupIDList, searchWndName='addressBookSearch') 134 container.parent.Close() 135 136 def OnRadioBtnRouteType(self, routeType): 137 sm.GetService('clientPathfinderService').SetAutopilotRouteType(routeType) 138 139 def OnCheckBoxAutopilotActive(self): 140 if eveCfg.IsDocked(): 141 return 142 autoPilotSvc = sm.GetService('autoPilot') 143 if autoPilotSvc.GetState(): 144 autoPilotSvc.SetOff() 145 else: 146 autoPilotSvc.SetOn() 147 148 def OnCheckBoxShowRoutePath(self): 149 pass 150 151 def OnCheckBoxAvoidPodKill(self): 152 val = not settings.char.ui.Get('pfAvoidPodKill', 0) 153 if val: 154 prompt_player_fsd_dialog('MapAutoPilotAvoidPodkillZones') 155 sm.GetService('clientPathfinderService').SetPodKillAvoidance(val) 156 157 def OnCheckBoxAvoidTriglavianTales(self): 158 val = not settings.char.ui.Get('pfAvoidTriglavianTales', 0) 159 if val: 160 prompt_player_fsd_dialog('MapAutoPilotAvoidTriglavianTales') 161 sm.GetService('clientPathfinderService').SetTriglavianTaleAvoidance(val) 162 163 def OnCheckBoxAvoidEdencomSystems(self): 164 val = not settings.char.ui.Get('pfAvoidEdencomSystems', 0) 165 if val: 166 prompt_player_fsd_dialog('MapAutoPilotAvoidEdencomSystems') 167 sm.GetService('clientPathfinderService').SetEdencomSystemsAvoidance(val) 168 169 def OnCheckBoxAvoidSystems(self): 170 val = not settings.char.ui.Get('pfAvoidSystems', 0) 171 if val: 172 prompt_player_fsd_dialog('MapAutoPilotAvoidSystems') 173 sm.GetService('clientPathfinderService').SetSystemAvoidance(val) 174 175 def OnCheckBoxDisableAtEachWaypoint(self): 176 val = not settings.user.ui.Get('autopilot_stop_at_each_waypoint', 0) 177 settings.user.ui.Set('autopilot_stop_at_each_waypoint', val) 178 179 def OnCheckBoxUseJumpGates(self): 180 val = not settings.char.ui.Get('pathFinder_includeJumpGates', 0) 181 settings.char.ui.Set('pathFinder_includeJumpGates', val) 182 sm.ScatterEvent('OnMapShowsJumpGatesChanged') 183 184 def OnSecuritySlider(self, slider): 185 self.UpdateSliderLabel(slider.value) 186 187 def OnSecuritySliderEnd(self, slider): 188 sm.GetService('clientPathfinderService').SetSecurityPenaltyFactor(slider.value) 189 self.UpdateSliderLabel(slider.value) 190 191 def UpdateSliderLabel(self, value): 192 if self.sliderLabel: 193 self.sliderLabel.text = '%s %i' % (localization.GetByLabel('UI/Map/MapPallet/lblSecurityPenelity'), value) 194 195 def ConstructNormal(self): 196 self.UpdateRoute() 197 198 def ConstructCompact(self): 199 self.UpdateHeaderText() 200 self.UpdateHeaderTrigIconDisplay() 201 202 def UpdateHeaderTrigIconDisplay(self): 203 starMapSvc = sm.GetService('starmap') 204 nextDestination = None 205 if self.routeData is None: 206 self.routeData = starMapSvc.GetAutopilotRoute() 207 if not self.routeData or self.routeData == [None]: 208 self.routeData = starMapSvc.GetWaypoints() 209 try: 210 if len(self.routeData): 211 nextDestination = self.routeData[0] 212 except KeyError: 213 self.headerTrigIcon.display = False 214 return 215 216 should_display_trig_warning = ShowTriglavianWarning(nextDestination) 217 self.headerTrigIcon.display = should_display_trig_warning 218 header_label_width = infoPanelUIConst.PANELWIDTH - infoPanelUIConst.LEFTPAD 219 if should_display_trig_warning: 220 header_label_width -= self.headerTrigIcon.width 221 self.headerCompact.SetRightAlphaFade(header_label_width, self.HEADER_FADE_WIDTH) 222 223 def OnDestinationSet(self, destination): 224 self.UpdateRoute(animate=bool(destination)) 225 226 def UpdateRoute(self, animate = False): 227 starMapSvc = sm.GetService('starmap') 228 self.routeData = starMapSvc.GetAutopilotRoute() 229 self.UpdateHeaderText() 230 if not session.solarsystemid2: 231 return 232 if self.mode != infoPanelConst.MODE_NORMAL: 233 return 234 if not self.routeData or self.routeData == [None]: 235 self.routeData = starMapSvc.GetWaypoints() 236 if not self.routeData: 237 if self.markersParent: 238 self.currentParent.Hide() 239 self.endParent.Hide() 240 self.markersParent.Hide() 241 self.noDestinationLabel.Show() 242 return 243 self.noDestinationLabel.Hide() 244 planetView = sm.GetService('viewState').IsViewActive('planet') 245 autoPilotActive = sm.GetService('autoPilot').GetState() 246 updatingRouteData = getattr(self, 'updatingRouteData', None) 247 if updatingRouteData == (autoPilotActive, planetView, self.routeData): 248 return 249 oldRouteIDs = [ child.solarSystemID for child in self.markersParent.children ] 250 self.toAnimate = [] 251 self.markersParent.Flush() 252 self.updatingRouteData = (autoPilotActive, planetView, self.routeData[:]) 253 self.currentParent.Show() 254 self.currentParent.item_id = self.routeData[0] 255 self.markersParent.Show() 256 routeIDs = [] 257 lastStationSystemID = None 258 for i, id in enumerate(self.routeData): 259 isLast = i == len(self.routeData) - 1 260 if idCheckers.IsSolarSystem(id) and not isLast and not idCheckers.IsSolarSystem(self.routeData[i + 1]): 261 continue 262 if idCheckers.IsSolarSystem(id) and lastStationSystemID == id: 263 continue 264 if idCheckers.IsStation(id): 265 lastStationSystemID = cfg.stations.Get(id).solarSystemID 266 else: 267 lastStationSystemID = None 268 routeIDs.append(id) 269 270 maxWidth = infoPanelUIConst.PANELWIDTH - self.mainCont.padLeft 271 markerX = 0 272 markerY = 0 273 waypoints = deque(sm.GetService('starmap').GetWaypoints()) 274 nextWaypoint = waypoints.popleft() if waypoints else None 275 lastSystemID = session.solarsystemid2 276 systemsIDsInRoute = [] 277 for i, destinationID in enumerate(routeIDs): 278 if destinationID == nextWaypoint: 279 isWaypoint = True 280 nextWaypoint = waypoints.popleft() if waypoints else None 281 else: 282 isWaypoint = False 283 if idCheckers.IsSolarSystem(destinationID): 284 isStation = False 285 solarSystemID = destinationID 286 elif idCheckers.IsStation(destinationID): 287 isStation = True 288 solarSystemID = cfg.stations.Get(destinationID).solarSystemID 289 else: 290 structure = sm.GetService('structureDirectory').GetStructureInfo(destinationID) 291 if structure is not None: 292 isStation = True 293 solarSystemID = structure.solarSystemID 294 else: 295 log.LogError('ConstructRoute: Unknown item. I can only handle solar systems, stations and structures. You gave me', destinationID) 296 continue 297 if solarSystemID != lastSystemID: 298 systemsIDsInRoute.append(solarSystemID) 299 lastSystemID = solarSystemID 300 if len(self.markersParent.children) > i: 301 systemIcon = self.markersParent.children[i] 302 systemIcon.left = markerX 303 systemIcon.top = markerY 304 systemIcon.numJumps = len(systemsIDsInRoute) 305 else: 306 systemIcon = AutopilotDestinationIcon(parent=self.markersParent, pos=(markerX, 307 markerY, 308 ROUTE_MARKERSIZE, 309 ROUTE_MARKERSIZE), solarSystemID=solarSystemID, destinationID=destinationID, idx=i, numJumps=len(systemsIDsInRoute)) 310 if i >= len(oldRouteIDs) or solarSystemID != oldRouteIDs[i]: 311 self.toAnimate.append(systemIcon) 312 if isStation: 313 systemIcon.SetMarkerType(ROUTE_MARKERTYPE_STATION) 314 elif isWaypoint: 315 systemIcon.SetMarkerType(ROUTE_MARKERTYPE_WAYPOINT) 316 elif ShowTriglavianWarning(destinationID): 317 systemIcon.SetMarkerType(ROUTE_MARKERTYPE_INVASION) 318 else: 319 systemIcon.SetMarkerType(ROUTE_MARKERTYPE_NORMAL) 320 systemIcon.SetSolarSystemAndDestinationID(solarSystemID, destinationID) 321 self.endParent.pointer_offset = markerX 322 markerParHeight = markerY + ROUTE_MARKERSIZE + ROUTE_MARKERGAP 323 if animate: 324 animations.MorphScalar(self.markersParent, 'height', self.markersParent.height, markerParHeight, duration=0.3) 325 else: 326 self.markersParent.height = markerParHeight 327 markerX += ROUTE_MARKERGAP + ROUTE_MARKERSIZE 328 if markerX + ROUTE_MARKERSIZE > maxWidth: 329 markerX = 0 330 markerY += ROUTE_MARKERGAP + ROUTE_MARKERSIZE 331 if len(routeIDs) > 1: 332 self.endParent.Show() 333 self.endParent.item_id = routeIDs[-1] 334 else: 335 self.endParent.Hide() 336 337 self.updatingRouteData = None 338 if animate: 339 uthread.new(self.AnimateRouteIn) 340 self.UpdateHeaderTrigIconDisplay() 341 342 def UpdateHeaderText(self): 343 starMapSvc = sm.GetService('starmap') 344 destination = starMapSvc.GetDestination() 345 routeData = starMapSvc.GetAutopilotRoute() 346 if self.mode == infoPanelConst.MODE_NORMAL: 347 numJumps = self._GetNumJumps(routeData) 348 if not destination: 349 subHeader = '' 350 elif idCheckers.IsWormholeSystem(session.solarsystemid2) or idCheckers.IsAbyssalSpaceSystem(session.solarsystemid2) or idCheckers.IsVoidSpaceSystem(session.solarsystemid2) or idCheckers.IsHiddenSpaceSystem(session.solarsystemid2): 351 if numJumps <= 1: 352 subHeader = localization.GetByLabel('UI/Market/MarketQuote/UnknownNumberOfJumps') 353 else: 354 subHeader = localization.GetByLabel('UI/Market/MarketQuote/MinimumPossibleNumberOfJumps', num=numJumps) 355 else: 356 subHeader = localization.GetByLabel('UI/Market/MarketQuote/NumberOfJumps', num=numJumps) 357 self.header.text = '%s <fontsize=12>%s' % (localization.GetByLabel('UI/InfoWindow/TabNames/Route'), subHeader) 358 elif routeData: 359 self.headerCompact.text = _GetCurrentDestinationLabel(routeData[0]) 360 else: 361 destination = starMapSvc.GetDestination() 362 self.headerCompact.text = _GetCurrentDestinationLabel(destination) 363 364 def OnStartModeChanged(self, oldMode): 365 uthread.new(self._OnStartModeChanged, oldMode) 366 367 def _OnStartModeChanged(self, oldMode): 368 if self.mode == infoPanelConst.MODE_NORMAL: 369 if oldMode: 370 animations.FadeOut(self.headerCompactCont, duration=0.3, sleep=True) 371 animations.FadeIn(self.headerCont, duration=0.3) 372 else: 373 self.headerCont.opacity = 1.0 374 self.headerCompactCont.opacity = 0.0 375 self.headerCompactCont.state = uiconst.UI_DISABLED 376 elif self.mode == infoPanelConst.MODE_COMPACT: 377 if oldMode: 378 animations.FadeOut(self.headerCont, duration=0.3, sleep=True) 379 animations.FadeIn(self.headerCompactCont, duration=0.3) 380 else: 381 self.headerCont.opacity = 0.0 382 self.headerCompactCont.opacity = 1.0 383 self.headerCompactCont.state = uiconst.UI_PICKCHILDREN 384 385 def AnimateRouteIn(self): 386 if not self.toAnimate: 387 return 388 random.shuffle(self.toAnimate) 389 kOffset = 0.6 / len(self.toAnimate) 390 for i, icon in enumerate(self.toAnimate): 391 animations.SpMaskIn(icon.icon, timeOffset=i * kOffset, loops=3, duration=0.05) 392 393 def _GetNumJumps(self, routeData): 394 if not routeData: 395 return 0 396 ids = [] 397 lastID = None 398 for routeID in routeData: 399 if idCheckers.IsStation(routeID): 400 routeID = cfg.stations.Get(routeID).solarSystemID 401 if routeID != lastID and idCheckers.IsSolarSystem(routeID): 402 ids.append(routeID) 403 lastID = routeID 404 405 numJumps = len(ids) 406 if ids and ids[0] == session.solarsystemid2: 407 numJumps -= 1 408 return numJumps 409 410 def OnUIRefresh(self): 411 self.UpdateRoute() 412 413 def OnAutoPilotOn(self): 414 if self.utilMenu and self.utilMenu(): 415 self.utilMenu().ReloadMenu() 416 417 def OnAutoPilotOff(self): 418 if self.utilMenu and self.utilMenu(): 419 self.utilMenu().ReloadMenu() 420 421 422 class AutopilotDestinationIcon(Container): 423 __guid__ = 'uicls.AutopilotDestinationIcon' 424 default_align = uiconst.TOPLEFT 425 default_state = uiconst.UI_NORMAL 426 isDragObject = True 427 default_pointerDirection = uiconst.POINT_BOTTOM_2 428 429 def ApplyAttributes(self, attributes): 430 Container.ApplyAttributes(self, attributes) 431 self.icon = Sprite(parent=self, pos=(0, 0, 10, 10), state=uiconst.UI_DISABLED, shadowOffset=(0, 1), shadowColor=(0, 0, 0, 0.2), outputMode=uiconst.OUTPUT_COLOR_AND_GLOW, glowBrightness=0.0) 432 self.markerType = None 433 self.solarSystemID = None 434 self.destinationID = None 435 self.hiliteTimer = None 436 self.fadingDisabled = False 437 self.lawless = False 438 self.numJumps = attributes.numJumps 439 440 def SetMarkerType(self, markerType): 441 if self.markerType == markerType: 442 return 443 if markerType == ROUTE_MARKERTYPE_WAYPOINT: 444 self.icon.LoadTexture('res:/UI/Texture/classes/LocationInfo/waypointMarker.png') 445 elif markerType == ROUTE_MARKERTYPE_STATION: 446 self.icon.LoadTexture('res:/UI/Texture/classes/LocationInfo/stationMarker.png') 447 elif markerType == ROUTE_MARKERTYPE_INVASION: 448 self.icon.LoadTexture('res:/UI/Texture/classes/LocationInfo/triglavianMarker.png') 449 elif markerType == ROUTE_MARKERTYPE_INSURGENCY: 450 self.icon.LoadTexture('res:/UI/Texture/classes/LocationInfo/triglavianMarker.png') 451 else: 452 self.icon.LoadTexture('res:/UI/Texture/classes/LocationInfo/normalMarker.png') 453 self.markerType = markerType 454 455 def SetSolarSystemAndDestinationID(self, solarSystemID, destinationID): 456 if self.solarSystemID == solarSystemID and self.destinationID == destinationID: 457 return 458 self.icon.SetRGBA(*eveColor.GUNMETAL_GREY) 459 animations.MorphScalar(self.icon, 'opacity', 1.0, 0.0, duration=1, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE, timeOffset=random.random()) 460 self.solarSystemID = solarSystemID 461 self.destinationID = destinationID 462 uthread2.StartTasklet(self.UpdateLawlessStatus, solarSystemID) 463 464 def UpdateLawlessStatus(self, solarSystemID): 465 c = sm.GetService('map').GetModifiedSystemColor(solarSystemID) 466 try: 467 corruptionStage = sm.GetService('corruptionSuppressionSvc').GetSystemCorruptionStage(solarSystemID) 468 except (TimeoutException, UnpackException): 469 corruptionStage = 0 470 471 if corruptionStage == CORRUPTION_STAGES: 472 self.lawless = True 473 if self.lawless: 474 secStatus = sm.GetService('map').GetSecurityStatus(solarSystemID) 475 c = GetLawlessSystemSecStatusColor(secStatus) 476 if self.markerType == ROUTE_MARKERTYPE_NORMAL: 477 self.SetMarkerType(ROUTE_MARKERTYPE_INSURGENCY) 478 animations.StopAnimation(self.icon, 'opacity') 479 self.icon.SetRGBA(c[0], c[1], c[2], IDLE_ROUTEMARKER_ALPHA) 480 481 def OnMouseEnter(self, *args): 482 PlaySound(uiconst.SOUND_BUTTON_HOVER) 483 if self.fadingDisabled: 484 return 485 animations.MorphScalar(self.icon, 'glowBrightness', self.icon.glowBrightness, 0.5, duration=uiconst.TIME_ENTRY) 486 if self.hiliteTimer is None: 487 self.hiliteTimer = timerstuff.AutoTimer(111, self.CheckIfMouseOver) 488 489 def CheckIfMouseOver(self, *args): 490 if uicore.uilib.mouseOver == self or self.fadingDisabled: 491 return 492 animations.MorphScalar(self.icon, 'glowBrightness', self.icon.glowBrightness, 0.0, duration=uiconst.TIME_ENTRY) 493 self.hiliteTimer = None 494 495 def OnMouseExit(self, *args): 496 self.CheckIfMouseOver() 497 498 def LoadTooltipPanel(self, tooltipPanel, *args): 499 tooltipPanel.LoadGeneric1ColumnTemplate() 500 if self.lawless: 501 traceText = sm.GetService('infoPanel').GetLawlessSolarSystemTrace(self.destinationID, traceFontSize=None) 502 else: 503 traceText = sm.GetService('infoPanel').GetSolarSystemTrace(self.destinationID, traceFontSize=None) 504 tooltipPanel.AddTextBodyLabel(text=traceText) 505 if not idCheckers.IsSolarSystem(self.destinationID): 506 if idCheckers.IsStation(self.destinationID) or sm.GetService('structureDirectory').GetStructureInfo(self.destinationID): 507 text = cfg.evelocations.Get(self.destinationID).name 508 tooltipPanel.AddTextBodyLabel(text=text) 509 if ShowTriglavianWarning(self.solarSystemID): 510 text = localization.GetByLabel('UI/Invasion/HUD/InvasionWarning') 511 tooltipPanel.AddTextBodyLabel(text=text) 512 if self.numJumps: 513 text = localization.GetByLabel('UI/Common/numberOfJumps', numJumps=self.numJumps) 514 tooltipPanel.AddTextDetailsLabel(text=text, color=TextColor.SECONDARY) 515 516 def GetMenu(self, *args): 517 if idCheckers.IsSolarSystem(self.destinationID): 518 return GetMenuService().GetMenuFromItemIDTypeID(self.destinationID, const.typeSolarSystem) 519 typeID = self.GetStationOrStructureTypeID(self.destinationID) 520 if typeID: 521 return GetMenuService().GetMenuFromItemIDTypeID(self.destinationID, typeID) 522 523 def OnClick(self, *args): 524 PlaySound(uiconst.SOUND_BUTTON_CLICK) 525 if idCheckers.IsSolarSystem(self.destinationID): 526 sm.GetService('info').ShowInfo(const.typeSolarSystem, self.destinationID) 527 typeID = self.GetStationOrStructureTypeID(self.destinationID) 528 if typeID: 529 sm.GetService('info').ShowInfo(typeID, self.destinationID) 530 531 def GetDragData(self, *args): 532 entry = utillib.KeyVal() 533 entry.__guid__ = 'xtriui.ListSurroundingsBtn' 534 entry.itemID = self.destinationID 535 entry.label = cfg.evelocations.Get(self.destinationID).name 536 if idCheckers.IsSolarSystem(self.destinationID): 537 entry.typeID = const.typeSolarSystem 538 else: 539 typeID = self.GetStationOrStructureTypeID(self.destinationID) 540 if typeID: 541 entry.typeID = typeID 542 return [entry] 543 544 def GetStationOrStructureTypeID(self, destinationID): 545 if idCheckers.IsStation(self.destinationID): 546 station = sm.StartService('ui').GetStationStaticInfo(self.destinationID) 547 return station.stationTypeID 548 structureInfo = sm.GetService('structureDirectory').GetStructureInfo(self.destinationID) 549 if structureInfo: 550 return structureInfo.typeID 551 552 def OnMouseDown(self, *args): 553 uthread.new(self.OnMouseDown_thread) 554 555 def OnMouseDown_thread(self): 556 destinationID = self.destinationID 557 if idCheckers.IsSolarSystem(destinationID): 558 typeID = const.typeSolarSystem 559 elif idCheckers.IsStation(destinationID): 560 station = sm.StartService('ui').GetStationStaticInfo(destinationID) 561 typeID = station.stationTypeID 562 else: 563 structure = sm.GetService('structureDirectory').GetStructureInfo(destinationID) 564 if structure is None: 565 return 566 typeID = structure.typeID 567 GetMenuService().TryExpandActionMenu(itemID=destinationID, clickedObject=self, typeID=typeID) 568 569 def GetRadialMenuIndicator(self, create = True, *args): 570 radialMenuSprite = getattr(self, 'radialMenuSprite', None) 571 if radialMenuSprite and not radialMenuSprite.destroyed: 572 return radialMenuSprite 573 if not create: 574 return 575 radialMenuSprite = Fill(name='radialMenuSprite', bgParent=self, padding=(-1, -1, -2, -2), color=(0.5, 0.5, 0.5, 0.8)) 576 self.radialMenuSprite = radialMenuSprite 577 return radialMenuSprite 578 579 def ShowRadialMenuIndicator(self, slimItem, *args): 580 mySprite = self.GetRadialMenuIndicator(create=True) 581 mySprite.display = True 582 self.icon.SetAlpha(1.0) 583 self.fadingDisabled = True 584 585 def HideRadialMenuIndicator(self, slimItem, *args): 586 mySprite = self.GetRadialMenuIndicator(create=False) 587 if mySprite: 588 mySprite.display = False 589 self.fadingDisabled = False 590 self.CheckIfMouseOver() 591 592 def GetTooltipPositionFallbacks(self): 593 return [uiconst.POINT_BOTTOM_1] 594 595 596 def ShowTriglavianWarning(solarSystemID): 597 return False 598 599 600 class WaypointPanel(ContainerAutoSize): 601 COLOR_BACKGROUND = (0.0, 0.0, 0.0, 0.3) 602 603 def __init__(self, item_id = None, link_hint = None, **kwargs): 604 self._item_id = item_id 605 self._waypoint_trace_label = None 606 self._link_hint = link_hint 607 super(WaypointPanel, self).__init__(alignMode=uiconst.TOTOP, **kwargs) 608 self.layout() 609 self._update() 610 611 def layout(self): 612 main_cont = ContainerAutoSize(parent=self, align=uiconst.TOTOP, alignMode=uiconst.TOTOP) 613 Fill(bgParent=main_cont, color=self.COLOR_BACKGROUND) 614 self._waypoint_trace_label = eveLabel.EveLabelMedium(parent=main_cont, align=uiconst.TOTOP, padding=8, state=uiconst.UI_NORMAL) 615 self._waypoint_trace_label.OnMouseDownWithUrl = self._on_mouse_down_with_url 616 self._trig_warning = TriglavianWarningIcon(parent=main_cont, align=uiconst.CENTERRIGHT, left=8) 617 618 @property 619 def item_id(self): 620 return self._item_id 621 622 @item_id.setter 623 def item_id(self, item_id): 624 if self._item_id == item_id: 625 return 626 self._item_id = item_id 627 self._update() 628 629 @property 630 def should_show_triglavian_warning(self): 631 return self.item_id is not None and ShowTriglavianWarning(self.item_id) 632 633 def _update(self): 634 if self._item_id is None: 635 text = localization.GetByLabel('UI/Inflight/NoDestination') 636 else: 637 text = eveformat.center(sm.GetService('infoPanel').GetSolarSystemTrace(self.item_id, self._link_hint)) 638 self._waypoint_trace_label.text = text 639 if self.should_show_triglavian_warning: 640 self._waypoint_trace_label.padRight = 34 641 self._trig_warning.Show() 642 else: 643 self._waypoint_trace_label.padRight = 8 644 self._trig_warning.Hide() 645 646 @threadutils.threaded 647 def _on_mouse_down_with_url(self, url, *args): 648 try: 649 parsed = evelink.parse_show_info_url(url) 650 except Exception: 651 log.LogWarning('Failed to parse URL') 652 return 653 654 if parsed.item_id is None or not idCheckers.IsSolarSystem(parsed.item_id): 655 return 656 local_stargate = FindLocalStargate(parsed.item_id) 657 if local_stargate: 658 destination_id = local_stargate.itemID 659 type_id = local_stargate.typeID 660 else: 661 destination_id = parsed.item_id 662 type_id = const.typeSolarSystem 663 GetMenuService().TryExpandActionMenu(itemID=destination_id, clickedObject=self, typeID=type_id) 664 665 666 class NextWaypointPanel(WaypointPanel): 667 668 def __init__(self, item_id = None, **kwargs): 669 self._trig_icon_cont = None 670 super(NextWaypointPanel, self).__init__(item_id=item_id, link_hint=localization.GetByLabel('UI/Neocom/Autopilot/NextSystemInRoute'), **kwargs) 671 672 def layout(self): 673 super(NextWaypointPanel, self).layout() 674 Sprite(parent=Container(parent=self, align=uiconst.TOTOP, height=12), align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/LocationInfo/pointerDown.png', width=10, height=10, color=self.COLOR_BACKGROUND) 675 676 677 class DestinationWaypointPanel(WaypointPanel): 678 679 def __init__(self, item_id = None, pointer_offset = 0, **kwargs): 680 self._pointer = None 681 self._pointer_offset = pointer_offset 682 super(DestinationWaypointPanel, self).__init__(item_id=item_id, link_hint=localization.GetByLabel('UI/Neocom/Autopilot/CurrentDestination'), **kwargs) 683 684 def layout(self): 685 self._pointer = Sprite(parent=Container(parent=self, align=uiconst.TOTOP, height=12), align=uiconst.BOTTOMLEFT, state=uiconst.UI_DISABLED, left=self.pointer_offset, texturePath='res:/UI/Texture/classes/LocationInfo/pointerUp.png', width=10, height=10, color=self.COLOR_BACKGROUND) 686 super(DestinationWaypointPanel, self).layout() 687 688 @property 689 def pointer_offset(self): 690 return self._pointer_offset 691 692 @pointer_offset.setter 693 def pointer_offset(self, pointer_offset): 694 self._pointer_offset = pointer_offset 695 self._pointer.left = pointer_offset 696 697 698 class TriglavianWarningIcon(Sprite): 699 700 def __init__(self, **kwargs): 701 super(TriglavianWarningIcon, self).__init__(texturePath='res:/UI/Texture/classes/Invasions/triglavianRace_18x18.png', width=18, height=18, hint=localization.GetByLabel('UI/Invasion/HUD/InvasionSolarSystemHint'), color=(1.0, 0.2, 0.1), **kwargs)