map2D.py (47476B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\maps\map2D.py 2 import sys 3 import math 4 from math import pi 5 import evetypes 6 import carbon.client.script.util.lg as lg 7 import trinity 8 import uthread 9 import carbonui.const as uiconst 10 import localization 11 import geo2 12 from carbon.common.script.util import timerstuff 13 from carbonui.primitives import vectorline, vectorarc 14 from carbonui.primitives.container import Container 15 from carbonui.primitives.polygon import Polygon 16 from carbonui.primitives.sprite import Sprite 17 from carbonui.primitives.transform import Transform 18 from carbonui.uicore import uicore 19 from carbonui.util.various_unsorted import FlushList, SortListOfTuples 20 from eve.client.script.ui.control.eveLabel import EveLabelMedium 21 from eve.client.script.ui.util import uix 22 from eve.common.lib import appConst as const 23 from eveservices.menu import GetMenuService 24 from menu import MenuLabel 25 DRAW_REGIONS = 1 26 DRAW_CONSTELLATIONS = 2 27 DRAW_SOLARSYSTEMS = 3 28 DRAW_SOLARSYSTEM_INTERIOR = 4 29 FLIPMAP = -1 30 31 class Map2D(Container): 32 __guid__ = 'xtriui.Map2D' 33 __nonpersistvars__ = [] 34 __notifyevents__ = ['OnDestinationSet'] 35 tooltipPositionRect = None 36 37 def ApplyAttributes(self, attributes): 38 Container.ApplyAttributes(self, attributes) 39 sm.RegisterNotify(self) 40 self.sr.sizefactor = None 41 self.sr.sizefactorsize = None 42 self.sr.marks = None 43 self.Reset() 44 self.overlays = Container(name='overlays', parent=self, clipChildren=1, pos=(0, 0, 0, 0)) 45 self.sr.areas = Container(name='areas', parent=self, clipChildren=1, pos=(0, 0, 0, 0)) 46 self.hilite = Sprite(parent=self.overlays, pos=(0, 0, 16, 16), color=(1.0, 1.0, 1.0, 0.4), name='hilite', state=uiconst.UI_HIDDEN, texturePath='res:/UI/Texture/Shared/circleThin16.png', align=uiconst.RELATIVE) 47 self.imhere = Container(name='imhere', parent=self.overlays, state=uiconst.UI_HIDDEN, align=uiconst.TOPLEFT, width=16, height=16) 48 circle = Sprite(parent=self.imhere, idx=0, pos=(0, 0, 16, 16), color=(1.0, 0.0, 0.0, 1.0), name='imhere_sprite', texturePath='res:/UI/Texture/Shared/circleThin16.png', align=uiconst.RELATIVE) 49 self.destination = Sprite(parent=self.overlays, pos=(0, 0, 16, 16), color=(1.0, 1.0, 0.0, 1.0), state=uiconst.UI_HIDDEN, name='destination', texturePath='res:/UI/Texture/Shared/circleThin16.png', align=uiconst.RELATIVE) 50 self.sprite = Container(name='mapsprite', parent=self, align=uiconst.TOALL, clipChildren=1) 51 self.bgSprite = None 52 self.dragging = 0 53 self.ditherIn = 1 54 self.dragAllowed = 0 55 self.dataLayer = None 56 self.dataToggle = 0 57 self.dataArgs = {} 58 self.dataLoaded = None 59 self.needsize = None 60 self.allowAbstract = 1 61 self.fillSize = 0.8 62 self.mouseHoverGroups = [] 63 self.cordsAsPortion = {} 64 self.fov = None 65 self.tempAngleFov = None 66 67 def SetInfoMode(self): 68 self.updatemylocationtimer = None 69 FlushList(self.imhere.children[1:]) 70 for each in self.children: 71 if each.name == 'frame': 72 each.Close() 73 74 def MarkAreas(self, areas = []): 75 uthread.pool('Map2D::_MarkAreas', self._MarkAreas, areas) 76 77 def _MarkAreas(self, areas): 78 size = self.absoluteRight - self.absoluteLeft 79 self.sr.areas.Flush() 80 for area in areas: 81 id, hint, (absX, absY, absZ), radius, color = area 82 maxdist = self.GetMaxDist() 83 sizefactor = size / 2 / maxdist * self.fillSize 84 x = FLIPMAP * absX * sizefactor / float(size) + 0.5 85 y = absZ * sizefactor / float(size) + 0.5 86 rad = radius * sizefactor / float(size) 87 mark = Sprite(parent=self.sr.areas, name='area', left=int(int(x * size) - mark.width / 2), top=int(int(y * size) - mark.height / 2 + 1), width=int(rad * size * 2), height=int(rad * size * 2), state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/circle_full.png', color=(1.0, 0.2, 0.2, 1.0)) 88 mark.sr.x = x 89 mark.sr.y = y 90 mark.sr.rad = rad 91 92 def SetMarks(self, marks = []): 93 uthread.pool('Map2D::SetMarks', self._SetMarks, marks) 94 95 def _SetMarks(self, marks): 96 if not self.IsUnder(uicore.desktop): 97 return 98 for i in xrange(0, len(marks), 4): 99 id = marks[i] 100 hint = marks[i + 1] 101 size = max(1, self.absoluteRight - self.absoluteLeft) 102 x, y = self.GetCordsByKeyAsPortion(id, size) 103 if x is None or y is None: 104 return 105 if self.sr.marks is None: 106 self.sr.marks = Container(name='marks', parent=self, align=uiconst.TOALL, pos=(0, 0, 0, 0), idx=0, state=uiconst.UI_DISABLED) 107 mark = Sprite(parent=self.sr.marks, name='area', left=x - mark.width / 2, top=y - mark.height / 2 + 1, width=128, height=128, state=uiconst.UI_PICKCHILDREN, texturePath='res:/UI/Texture/circle_full.png', color=(1.0, 1.0, 1.0, 0.21)) 108 if hint: 109 EveLabelMedium(text=hint, parent=self.sr.marks, left=mark.left + mark.width, top=mark.top + 2, width=min(128, max(64, size - mark.left - mark.width)), state=uiconst.UI_NORMAL) 110 111 def OnDestinationSet(self, destinationID, *args): 112 if self is None or self.destroyed: 113 return 114 self.CheckDestination() 115 116 def Reset(self): 117 self.portion = 0.75 118 self.areas = [] 119 self.orbs = [] 120 self.hilite = None 121 self.imhere = None 122 self.overlays = None 123 self.lasthilite = None 124 self.pickradius = 6 125 self.mapitems = [] 126 self.outsideitems = [] 127 self.ids = None 128 self.idlevel = None 129 self.drawlevel = None 130 self.clipped = 0 131 self.updatemylocationtimer = None 132 self.showingtempangle = None 133 self.settings = None 134 135 def _OnClose(self): 136 sm.UnregisterNotify(self) 137 self.updatemylocationtimer = None 138 for each in self.overlays.children: 139 if each.name == 'destinationline': 140 if hasattr(each, 'renderObject') and each.renderObject and len(each.renderObject.children): 141 for _each in each.renderObject.children: 142 _each.object.numPoints = 0 143 del _each.object.vectorCurve.keys[:] 144 each.renderObject.children.remove(_each) 145 146 each.renderObject = None 147 each.Close() 148 149 self.OnSelectItem = None 150 self.Reset() 151 152 def Draw(self, ids, idlevel, drawlevel, needsize, sprite = None, solarsystem = None, lineColors = None, dotColor = None, dotSizeMultiplier = None): 153 _settings = (ids, 154 idlevel, 155 drawlevel, 156 needsize) 157 if _settings == self.settings: 158 return 159 self.settings = _settings 160 lg.Info('2Dmaps', 'Drawing map, ids/idlevel/drawlevel:', ids, idlevel, drawlevel) 161 if drawlevel <= idlevel: 162 return 163 if drawlevel == DRAW_SOLARSYSTEM_INTERIOR and len(ids) > 1: 164 ids = ids[:1] 165 SIZE = needsize 166 if sprite is None: 167 sprite = self.sprite 168 sprite.Flush() 169 _ids = {} 170 for id in ids: 171 _ids[id] = '' 172 173 ids = _ids.keys() 174 endid = '' 175 if len(ids) > 1: 176 endid = '%s_' % ids[-1] 177 self.ids = ids 178 self.idlevel = idlevel 179 self.drawlevel = drawlevel 180 self.needsize = needsize 181 imageid = '%s_%s_%s_%s_%s_%s' % (ids[0], 182 '_' * max(0, len(ids) - 2), 183 endid, 184 idlevel, 185 drawlevel, 186 self.fillSize) 187 imageid = imageid.replace('.', '') 188 if self.drawlevel == DRAW_SOLARSYSTEM_INTERIOR: 189 imageid += '_' + str(settings.user.ui.Get('solarsystemmapabstract', 0)) 190 lg.Info('2Dmaps', 'MapID is: %s' % imageid) 191 for each in self.overlays.children: 192 if each.name == 'destinationline': 193 each.renderObject = None 194 each.Close() 195 196 self.cordsAsPortion = {} 197 mapitems = self.mapitems = self.GetMapData(ids, idlevel, drawlevel) 198 if drawlevel == 4: 199 self.DrawSolarsystem(sprite, ids, imageid, mapitems, SIZE) 200 self.CheckMyLocation(solarsystem=solarsystem) 201 return 202 connections, outsideitems = self.GetConnectionData(ids, idlevel, drawlevel) 203 self.outsideitems = outsideitems 204 minx = 1e+100 205 maxx = -1e+100 206 minz = 1e+100 207 maxz = -1e+100 208 for item in mapitems: 209 minx = min(minx, item.x) 210 maxx = max(maxx, item.x) 211 minz = min(minz, item.z) 212 maxz = max(maxz, item.z) 213 214 mw = -minx + maxx 215 mh = -minz + maxz 216 if not mw: 217 mw = 1e-07 218 if not mh: 219 mh = 1e-07 220 dotrad = [2, 221 3, 222 4, 223 5, 224 6][idlevel] 225 sizefactor = min(SIZE / mw, SIZE / mh) * self.portion 226 cords = {} 227 for item in mapitems[:]: 228 if item.groupID == const.groupRegion: 229 if drawlevel != 1: 230 continue 231 if item.groupID == const.groupConstellation: 232 if drawlevel != 2: 233 continue 234 x = int(item.x * sizefactor - int(minx * sizefactor) + (SIZE - mw * sizefactor) / 2) 235 y = int(item.z * sizefactor - int(minz * sizefactor) + (SIZE - mh * sizefactor) / 2) 236 cords[item.itemID] = (x, 237 SIZE - y, 238 dotrad, 239 1, 240 16777215) 241 242 for item in self.outsideitems: 243 x = int(item.x * sizefactor - int(minx * sizefactor) + (SIZE - mw * sizefactor) / 2) 244 y = int(item.z * sizefactor - int(minz * sizefactor) + (SIZE - mh * sizefactor) / 2) 245 cords[item.itemID] = (x, 246 SIZE - y, 247 dotrad, 248 0, 249 None) 250 251 for x, y, dotrad, cordtype, col in cords.itervalues(): 252 if cordtype == 0: 253 dotrad = dotrad / 2 254 if dotSizeMultiplier is not None: 255 dotrad = dotrad * dotSizeMultiplier 256 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=x - dotrad, top=y - dotrad, width=2 * dotrad, height=2 * dotrad, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED, color=dotColor) 257 258 done = [] 259 i = 0 260 lineWidth = 1.0 261 if lineColors is None: 262 lineColors = [(0, 0.7, 0, 1), (0, 0, 1, 1), (1, 0, 0, 1)] 263 for jumptype in connections: 264 for pair in jumptype: 265 fr, to = pair 266 if (fr, to) in done: 267 continue 268 if fr in cords and to in cords: 269 color = lineColors[i] 270 vectorline.VectorLine(parent=sprite, translationFrom=cords[fr], widthFrom=lineWidth, translationTo=cords[to], widthTo=lineWidth, colorFrom=color, colorTo=color, align=uiconst.TOPLEFT) 271 272 i += 1 273 274 self.areas = [ (cords[id][0], 275 cords[id][1], 276 cords[id][2], 277 id) for id in cords.iterkeys() ] 278 self.cordsAsPortion = {} 279 for id in cords.iterkeys(): 280 self.cordsAsPortion[id] = (cords[id][0] / float(SIZE), cords[id][1] / float(SIZE)) 281 282 self.CheckMyLocation(solarsystem=solarsystem) 283 self.CheckDestination() 284 285 def CheckDestination(self): 286 if self is None or self.destroyed: 287 return 288 destination = sm.GetService('starmap').GetDestination() 289 if destination and self.drawlevel == DRAW_SOLARSYSTEMS: 290 x, y = self.GetCordsByKeyAsPortion(destination) 291 if x is None or y is None: 292 return 293 self.destination.sr.x, self.destination.sr.y = x, y 294 self.destination.state = uiconst.UI_DISABLED 295 self.RefreshOverlays(1) 296 else: 297 for each in self.overlays.children: 298 if each.name == 'destinationline': 299 each.renderObject = None 300 each.Close() 301 302 def GetMapData(self, ids, idlevel, drawlevel): 303 if idlevel != 3 and drawlevel != idlevel + 1: 304 raise Exception('map2d.py GetMapData: Unexpected usage pattern for this function! idlevel: %i, drawLevel: %i' % (idlevel, drawlevel)) 305 if len(ids) != 1: 306 raise Exception('map2d.py GetMapData: Unexpected usage pattern for this function! Many IDs:' + str(ids)) 307 if drawlevel == DRAW_REGIONS: 308 return GetMap2DItemsForUniverse() 309 elif drawlevel == DRAW_CONSTELLATIONS: 310 return GetMap2DItemsForRegion(ids[0]) 311 elif drawlevel == DRAW_SOLARSYSTEMS: 312 return GetMap2DItemsForConstellation(ids[0]) 313 else: 314 return GetMap2DItemsForSolarSystem(ids[0]) 315 316 def GetConnectionData(self, ids, idlevel, drawlevel): 317 if len(ids) != 1: 318 raise Exception('unexpectedly many IDs passed to GetConnectionData: %s' % str(ids)) 319 if drawlevel == DRAW_REGIONS: 320 return GetMap2DConnectionsForUniverse() 321 if drawlevel == DRAW_CONSTELLATIONS: 322 return GetMap2DConstellationConnectionsForRegion(ids[0]) 323 if drawlevel == DRAW_SOLARSYSTEMS: 324 return GetMap2DConnectionsForConstellation(ids[0]) 325 raise Exception('map2D GetConnectionData unexpectedly asked for connections for drawlevel %i', drawlevel) 326 327 def Width(self): 328 return self.absoluteRight - self.absoluteLeft 329 330 def Height(self): 331 return self.absoluteBottom - self.absoluteTop 332 333 def MyHierarchy(self): 334 return (session.regionid, 335 session.constellationid, 336 session.solarsystemid2, 337 session.stationid) 338 339 def CheckMyLocation(self, solarsystem = None): 340 if self is None or self.destroyed: 341 return 342 self.updatemylocationtimer = None 343 self.imhere.sr.x = self.imhere.sr.y = None 344 self.imhere.state = uiconst.UI_HIDDEN 345 self.destination.sr.x = self.destination.sr.y = None 346 self.destination.state = uiconst.UI_HIDDEN 347 destination = sm.GetService('starmap').GetDestination() 348 if self.drawlevel < DRAW_SOLARSYSTEM_INTERIOR or session.stationid: 349 for locationID in self.cordsAsPortion.iterkeys(): 350 if locationID in self.MyHierarchy() or locationID == solarsystem: 351 self.imhere.sr.x, self.imhere.sr.y = self.cordsAsPortion[locationID] 352 self.imhere.state = uiconst.UI_DISABLED 353 if destination and locationID == destination: 354 self.destination.sr.x, self.destination.sr.y = self.cordsAsPortion[locationID] 355 self.destination.state = uiconst.UI_DISABLED 356 357 elif self.ids[0] == session.solarsystemid2: 358 self.updatemylocationtimer = timerstuff.AutoTimer(100, self.UpdateMyLocation) 359 uthread.new(self.UpdateMyLocation) 360 self.RefreshOverlays(1) 361 362 def UpdateMyLocation(self): 363 if not self.IsUnder(uicore.desktop): 364 return 365 bp = sm.GetService('michelle').GetBallpark() 366 if bp is None or self is None or self.destroyed: 367 self.updatemylocationtimer = None 368 return 369 myball = bp.GetBall(session.shipid) 370 if myball is None: 371 self.updatemylocationtimer = None 372 return 373 size = max(1, self.absoluteRight - self.absoluteLeft) 374 if size == 1: 375 size = max(1, self.absoluteRight - self.absoluteLeft) 376 x = y = None 377 if self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0): 378 if not len(self.orbs): 379 return 380 x, y = self.GetAbstractPosition((myball.x, 0.0, myball.z), 1) 381 elif self.sr.sizefactor is not None and self.sr.sizefactorsize is not None: 382 maxdist = self.GetMaxDist() 383 sizefactor = size / 2 / maxdist * self.fillSize 384 x = FLIPMAP * myball.x * sizefactor / float(size) + 0.5 385 y = -(myball.z * sizefactor) / float(size) + 0.5 386 if x is not None and y is not None: 387 self.imhere.sr.x = x 388 self.imhere.sr.y = y 389 self.imhere.state = uiconst.UI_DISABLED 390 scene = sm.GetService('sceneManager').GetRegisteredScene('default') 391 camera = sm.GetService('sceneManager').GetActiveCamera() 392 if camera is None: 393 return 394 yaw = camera.GetYaw() 395 if not self.fov: 396 self.fov = Fov(parent=self.imhere) 397 self.fov.SetRotation(yaw) 398 actualfov = camera.fov * (uicore.desktop.width / float(uicore.desktop.height)) 399 degfov = actualfov - pi / 2 400 self.fov.SetFovAngle(actualfov) 401 if self.showingtempangle: 402 if not self.tempAngleFov: 403 self.tempAngleFov = Fov(parent=self.imhere, state=uiconst.UI_DISABLED, blendMode=trinity.TR2_SBM_ADDX2) 404 self.tempAngleFov.SetColor((0.0, 0.3, 0.0, 1.0)) 405 self.tempAngleFov.display = True 406 self.tempAngleFov.SetRotation(yaw) 407 angle = self.showingtempangle 408 self.tempAngleFov.SetFovAngle(angle) 409 elif self.tempAngleFov: 410 self.tempAngleFov.display = False 411 self.RefreshOverlays() 412 413 def SetTempAngle(self, angle): 414 if self.imhere is None or self.imhere.destroyed or len(self.imhere.children) <= 1: 415 return 416 self.showingtempangle = angle 417 418 def GetRegionColor(self, regionID): 419 color = trinity.TriColor() 420 color.SetHSV(float(regionID) * 21 % 360.0, 0.5, 0.8) 421 color.a = 0.75 422 return color 423 424 def GetAbstractPosition(self, pos, asPortion = 0, size = None): 425 if not len(self.orbs): 426 return (None, None) 427 dist = geo2.Vec3Length(pos) 428 maxorb = None 429 minorb = (0.0, 0) 430 for orbdist, pixelrad, orbititem, SIZE in self.orbs: 431 if orbdist < dist: 432 minorb = (orbdist, pixelrad) 433 elif orbdist > dist and maxorb is None: 434 maxorb = (orbdist, pixelrad) 435 436 mindist, minpixelrad = minorb 437 distInPixels = minpixelrad 438 if maxorb: 439 maxdist, maxpixelrad = maxorb 440 rnge = maxdist - mindist 441 pixelrnge = maxpixelrad - minpixelrad 442 posWithinRange = dist - mindist 443 distInPixels += pixelrnge * (posWithinRange / rnge) 444 sizefactor = float(distInPixels) / dist 445 if asPortion: 446 size = max(1, self.absoluteRight - self.absoluteLeft) 447 return (float(size) / (FLIPMAP * pos[0] * sizefactor + SIZE / 2), float(size) / (pos[2] * sizefactor + SIZE / 2)) 448 return (int(FLIPMAP * pos[0] * sizefactor) + SIZE / 2, int(pos[2] * sizefactor) + SIZE / 2) 449 450 def GetPick(self): 451 areas = [] 452 size = max(1, self.absoluteRight - self.absoluteLeft) 453 radius = 2 454 isAbstract = self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0) == 1 455 for locationID in self.cordsAsPortion.iterkeys(): 456 if len(self.mouseHoverGroups) and not isAbstract: 457 locationrec = self.GetItemRecord(locationID)[0] 458 if not locationrec or locationrec.groupID not in self.mouseHoverGroups: 459 continue 460 x, y = self.GetCordsByKeyAsPortion(locationID, size) 461 if x is None or y is None: 462 continue 463 if int(x - radius - 3) <= uicore.uilib.x - self.absoluteLeft <= int(x + radius + 3) and int(y - radius - 3) <= uicore.uilib.y - self.absoluteTop <= int(y + radius + 3): 464 areas.append(locationID) 465 466 return areas 467 468 def GetItemRecord(self, getkey): 469 for each in self.mapitems: 470 if not hasattr(each, 'itemID'): 471 continue 472 if each.itemID == getkey: 473 return (each, 1) 474 475 for each in self.outsideitems: 476 if not hasattr(each, 'itemID'): 477 continue 478 if each.itemID == getkey: 479 return (each, 0) 480 481 return (None, None) 482 483 def GetCordsByKeyAsPortion(self, locationID, size = None): 484 if size is None: 485 return self.cordsAsPortion.get(locationID, (None, None)) 486 x, y = self.cordsAsPortion.get(locationID, (None, None)) 487 if x is not None and y is not None: 488 return (int(x * size), int(y * size)) 489 return (None, None) 490 491 def ToggleAbstract(self, setTo): 492 uthread.new(self._ToggleAbstract, setTo) 493 494 def _ToggleAbstract(self, setTo): 495 settings.user.ui.Set('solarsystemmapabstract', setTo) 496 self.settings = None 497 self.Draw(self.ids, self.idlevel, self.drawlevel, self.needsize) 498 499 def SetSelected(self, ids): 500 if self is None or self.destroyed: 501 return 502 for each in self.overlays.children[:]: 503 if each.name == 'selected': 504 each.Close() 505 506 for id in ids: 507 x, y = self.GetCordsByKeyAsPortion(id) 508 if x is not None and y is not None: 509 newsel = Container(parent=self.overlays, name='selected', align=uiconst.TOPLEFT, width=16, height=16, state=uiconst.UI_DISABLED) 510 pointer = Sprite(parent=newsel, pos=(0, 0, 16, 32), state=uiconst.UI_PICKCHILDREN, texturePath='res:/UI/Texture/Shared/circlePointerDown.png', color=(1.0, 1.0, 1.0, 0.4)) 511 newsel.sr.x = x 512 newsel.sr.y = y 513 514 self.RefreshOverlays(1) 515 516 def _OnResize(self): 517 if self.align == uiconst.TOTOP: 518 self.height = self.absoluteRight - self.absoluteLeft 519 elif self.align in (uiconst.TOLEFT, uiconst.TORIGHT): 520 self.width = self.absoluteBottom - self.absoluteTop 521 try: 522 self.RefreshOverlays(1) 523 except: 524 sys.exc_clear() 525 526 def RefreshOverlays(self, update = 0): 527 if not self.IsUnder(uicore.desktop): 528 return 529 if self is None or self.destroyed or not uicore.uilib: 530 return 531 size = self.absoluteRight - self.absoluteLeft 532 for each in self.sr.areas.children: 533 if not hasattr(each, 'sr') or getattr(each.sr, 'x', None) is None and getattr(each.sr, 'y', None) is None: 534 continue 535 each.width = each.height = int(each.sr.rad * size * 2) 536 each.left = int(getattr(each.sr, 'x', 0) * size) - each.width / 2 + 1 537 each.top = int(getattr(each.sr, 'y', 0) * size) - each.height / 2 + 1 538 539 for each in self.overlays.children: 540 if not hasattr(each, 'sr') or getattr(each.sr, 'x', None) is None and getattr(each.sr, 'y', None) is None: 541 continue 542 each.left = int(getattr(each.sr, 'x', 0) * size) - each.width / 2 + 1 543 each.top = int(getattr(each.sr, 'y', 0) * size) - each.height / 2 + 1 544 545 def OnClick(self, *args): 546 areas = self.GetPick() 547 if areas: 548 self.OnSelectItem(self, areas[0]) 549 550 def OnMouseDown(self, *args): 551 if self.dragAllowed: 552 self.dragging = 1 553 554 def OnMouseUp(self, *args): 555 if self.dragging: 556 self.left = max(-self.width + 24, min(self.parent.absoluteRight - self.parent.absoluteLeft - 24, self.left)) 557 self.top = max(-self.height + 24, min(self.parent.absoluteBottom - self.parent.absoluteTop - 24, self.top)) 558 self.SetOrder(-1) 559 self.dragging = 0 560 561 def SetHint(self, hint): 562 self.hilite.state = uiconst.UI_HIDDEN 563 refresh = self.sr.hint != hint 564 self.sr.hint = hint 565 self.hilite.state = uiconst.UI_DISABLED 566 if refresh: 567 uicore.uilib.tooltipHandler.RefreshTooltipForOwner(self) 568 569 def GetTooltipPosition(self): 570 if self.tooltipPositionRect: 571 return self.tooltipPositionRect 572 573 def OnMouseMove(self, *args): 574 if self.dragging: 575 self.left = max(-self.width + 24, min(self.parent.absoluteRight - self.parent.absoluteLeft - 24, self.left)) 576 self.top = max(-self.height + 24, min(self.parent.absoluteBottom - self.parent.absoluteTop - 24, self.top)) 577 return 578 areas = self.GetPick() 579 if areas: 580 if (areas[0], len(areas)) == self.lasthilite: 581 return 582 self.lasthilite = (areas[0], len(areas)) 583 x, y = self.GetCordsByKeyAsPortion(areas[0], self.absoluteRight - self.absoluteLeft) 584 if x is not None and y is not None: 585 self.hilite.left = x - self.hilite.width / 2 586 self.hilite.top = y - self.hilite.height / 2 + 1 587 self.hilite.state = uiconst.UI_DISABLED 588 locStr = '' 589 locStrList = [] 590 for id in areas: 591 datarec, datahint = self.GetDataArgs(id) 592 item, insider = self.GetItemRecord(id) 593 if item: 594 groupname = evetypes.GetGroupNameByGroup(item.groupID) 595 if item.itemName.lower().find(groupname.lower()) >= 0: 596 groupname = '' 597 locStrList.append(localization.GetByLabel('UI/Map/Map2D/hintMouseMoveFormating', locationName=item.itemName, dataHint=datahint, locationGroupName=groupname)) 598 if not insider: 599 parent = sm.GetService('map').GetItem(item.locationID) 600 linkTo = '<br>'.join(locStrList) 601 locStrList = [localization.GetByLabel('UI/Map/Map2D/hintMouseMove', group=evetypes.GetGroupNameByGroup(parent.groupID), parent=parent.itemName, linkTo=linkTo)] 602 603 locStr = '<br>'.join(locStrList) 604 self.SetHint(locStr) 605 self.tooltipPositionRect = (uicore.uilib.x - 6, 606 uicore.uilib.y - 6, 607 12, 608 12) 609 return 610 self.SetHint('') 611 self.hilite.state = uiconst.UI_HIDDEN 612 self.lasthilite = None 613 614 def OnMouseExit(self, *args): 615 self.hilite.state = uiconst.UI_HIDDEN 616 617 def GetMenu(self): 618 m = [] 619 pick = self.GetPick() 620 if len(pick) == 1: 621 item, insider = self.GetItemRecord(pick[0]) 622 m += GetMenuService().CelestialMenu(pick[0], item) 623 else: 624 for itemID in pick: 625 item, insider = self.GetItemRecord(itemID) 626 if item: 627 submenu = GetMenuService().CelestialMenu(itemID, item) 628 if len(submenu): 629 if item.groupID == const.groupStation: 630 locationName = uix.EditStationName(item.itemName) 631 else: 632 locationName = item.itemName 633 groupname = evetypes.GetGroupNameByGroup(item.groupID) 634 if locationName.lower().find(groupname.lower()) >= 0: 635 groupname = '' 636 locationName = MenuLabel('UI/Map/Map2D/menuLocationEntry', {'locationName': locationName, 637 'groupName': groupname}) 638 m.append((locationName, submenu)) 639 640 m.sort() 641 if not m: 642 m = self.GetParentMenu() 643 if self.drawlevel == DRAW_SOLARSYSTEM_INTERIOR: 644 if self.allowAbstract: 645 isAbstract = settings.user.ui.Get('solarsystemmapabstract', 0) == 1 646 if isAbstract: 647 lbl = MenuLabel('UI/Map/Map2D/menuShowNonAbstract') 648 else: 649 lbl = MenuLabel('UI/Map/Map2D/menuShowAbstract') 650 m += [None, (lbl, self.ToggleAbstract, (not isAbstract,))] 651 return m 652 653 def GetParentMenu(self): 654 return [] 655 656 def GetMaxDist(self): 657 maxdist = 0.0 658 for item in self.mapitems: 659 pos = (item.x, 0.0, item.z) 660 maxdist = max(maxdist, geo2.Vec3Length(pos)) 661 662 return maxdist 663 664 def DrawSolarsystem(self, sprite, ids, imageid, mapitems, SIZE): 665 if not len(mapitems): 666 return 667 planets = [] 668 stargates = [] 669 asteroidbelts = [] 670 for item in mapitems: 671 if item.groupID == const.groupPlanet: 672 planets.append(item) 673 elif item.groupID == const.groupStargate: 674 stargates.append(item) 675 elif item.groupID == const.groupAsteroidBelt: 676 asteroidbelts.append(item) 677 678 cords = {} 679 maxdist = 0.0 680 for item in mapitems: 681 pos = (item.x, 0.0, item.z) 682 maxdist = max(maxdist, geo2.Vec3Length(pos)) 683 if item.groupID == const.groupSun: 684 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=SIZE / 2 - 4, top=SIZE / 2 - 4, width=8, height=8, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED) 685 686 sizefactor = SIZE / 2 / maxdist * self.fillSize 687 self.sr.sizefactor = sizefactor 688 self.sr.sizefactorsize = SIZE 689 if self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0): 690 _planets = [] 691 for planet in planets: 692 pos = (planet.x, planet.y, planet.z) 693 dist = geo2.Vec3Length(pos) 694 _planets.append([dist, planet]) 695 696 _planets = SortListOfTuples(_planets) 697 planet = _planets 698 i = 1 699 for item in planets: 700 pos = (item.x, 0.0, item.z) 701 dist = geo2.Vec3Length(pos) 702 if self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0): 703 planetscale = i * (maxdist / len(planets)) / dist 704 pos = geo2.Vec3Scale(pos, planetscale) 705 x = FLIPMAP * pos[0] * sizefactor + SIZE / 2 706 y = pos[2] * sizefactor + SIZE / 2 707 radius = 1 708 cords[item.itemID] = (x, SIZE - y, radius) 709 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=x - 4, top=SIZE - y - 4, width=8, height=8, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED, color=self.GetColorByGroupID(const.groupPlanet)) 710 self.AddChilds(x, y, radius, item.itemID, SIZE, sprite, cords, item) 711 i += 1 712 713 self.orbs = [] 714 for orbit in planets: 715 if orbit.itemID in cords: 716 x, y, radius = cords[orbit.itemID] 717 center = SIZE / 2 718 frompos = geo2.Vector(float(center), 0.0, float(center)) 719 topos = geo2.Vector(float(x), 0.0, float(y)) 720 diff = topos - frompos 721 rad = int(geo2.Vec3Length(diff)) 722 vectorarc.VectorArc(parent=sprite, align=uiconst.TOPLEFT, radius=rad, fill=False, left=center, lineWidth=1, top=center, width=SIZE, height=SIZE, color=self.GetColorByGroupID(const.groupPlanet), spriteEffect=trinity.TR2_SFX_FILL_AA) 723 orbpos = (orbit.x, 0.0, orbit.z) 724 orbdist = geo2.Vec3Length(orbpos) 725 self.orbs.append([orbdist, (orbdist, 726 rad, 727 orbit, 728 SIZE)]) 729 730 self.orbs = SortListOfTuples(self.orbs) 731 for item in stargates: 732 if self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0): 733 if not len(self.orbs): 734 return 735 x, y = self.GetAbstractPosition((item.x, 0.0, item.z)) 736 else: 737 x = FLIPMAP * self.sr.sizefactor * item.x + self.sr.sizefactorsize / 2 738 y = self.sr.sizefactor * item.z + self.sr.sizefactorsize / 2 739 x += 6 740 radius = 1 741 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=x - 4, top=SIZE - y - 4, width=8, height=8, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED, color=self.GetColorByGroupID(const.groupStargate)) 742 cords[item.itemID] = (x, SIZE - y, radius) 743 744 self.areas = [ (cords[id][0], 745 cords[id][1], 746 cords[id][2], 747 id) for id in cords.iterkeys() ] 748 self.cordsAsPortion = {} 749 for id in cords.iterkeys(): 750 self.cordsAsPortion[id] = (cords[id][0] / float(SIZE), cords[id][1] / float(SIZE)) 751 752 if self.destroyed: 753 return 754 self.PlaceBackground('res:/UI/Texture/map_ssunderlay.png') 755 756 def AddChilds(self, parentX, parentY, parentRad, parentID, SIZE, sprite, cords, parent, _x = None, _y = None): 757 parentpos = geo2.Vector(parent.x, parent.y, parent.z) 758 sorted = [] 759 allchilds = self.GetChilds(parentID, [], 0) 760 for child in allchilds: 761 childpos = geo2.Vector(child.x, child.y, child.z) 762 diff = childpos - parentpos 763 dist = geo2.Vec3Length(diff) 764 sorted.append((dist, child)) 765 766 sorted = SortListOfTuples(sorted) 767 if self.allowAbstract and settings.user.ui.Get('solarsystemmapabstract', 0): 768 done = [] 769 i = 1 770 xi = 0 771 for child in sorted: 772 if child.itemID in done: 773 continue 774 radius = 1 775 step = max(12, radius * 4) - 2 776 y = _y or parentY + parentRad + i * step 777 x = _x or parentX + xi 778 if y + step > SIZE: 779 i = 0 780 xi += step 781 done.append(child.itemID) 782 fill = self.GetColorByGroupID(child.groupID) 783 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=x - 2, top=SIZE - y - 2, width=4, height=4, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED, color=self.GetColorByGroupID(child.groupID)) 784 cords[child.itemID] = (x, SIZE - y, radius) 785 i += 1 786 787 else: 788 for child in sorted: 789 radius = 1 790 pos = geo2.Vector(child.x, 0.0, child.z) 791 pos = pos + (pos - parentpos) * max(1.0, 4096 / SIZE) 792 x = FLIPMAP * pos.x * self.sr.sizefactor + SIZE / 2 793 y = pos.z * self.sr.sizefactor + SIZE / 2 794 fill = self.GetColorByGroupID(child.groupID) 795 Sprite(parent=sprite, align=uiconst.TOPLEFT, left=x - 2, top=SIZE - y - 2, width=4, height=4, texturePath='res:/UI/Texture/classes/graph/point.png', state=uiconst.UI_DISABLED, color=self.GetColorByGroupID(child.groupID)) 796 cords[child.itemID] = (x, SIZE - y, radius) 797 798 def GetChilds(self, parentID, childs, i): 799 i += 1 800 if i == 20 or len(childs) > 1000: 801 return childs 802 _childs = [ child for child in self.mapitems if child.orbitID == parentID and child not in childs ] 803 if len(_childs): 804 childs += _childs 805 for granchild in _childs: 806 childs = self.GetChilds(granchild.itemID, childs, i) 807 808 return childs 809 810 def GetColorByGroupID(self, groupID): 811 col = {const.groupAsteroidBelt: (0, 0, 1), 812 const.groupPlanet: (0.53, 0.53, 0.53), 813 const.groupStargate: (0, 0.53, 0), 814 const.groupStation: (1, 0.2, 0.2)}.get(groupID, (0.6, 0.6, 0.6)) 815 return col 816 817 def GetDataArgs(self, locationID): 818 if locationID in self.dataArgs: 819 return self.dataArgs[locationID] 820 return (None, '') 821 822 def PlaceBackground(self, imagepath): 823 if self is None or self.destroyed: 824 return 825 imagepath = str(imagepath) 826 if self.bgSprite is None: 827 self.bgSprite = Sprite(name='bgSprite', parent=self, align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 1.0), texturePath=imagepath, filter=True) 828 829 def OnSelectItem(self, _self, arg, *args): 830 pass 831 832 833 class Fov(Transform): 834 default_name = 'fov' 835 default_left = 0 836 default_top = 0 837 default_width = 128 838 default_height = 128 839 default_align = uiconst.CENTER 840 default_state = uiconst.UI_NORMAL 841 842 def ApplyAttributes(self, attributes): 843 Transform.ApplyAttributes(self, attributes) 844 blendMode = attributes.get('blendMode', trinity.TR2_SBM_BLEND) 845 self.angle = math.pi 846 self.color = (1.0, 1.0, 1.0, 0.5) 847 self.polygon = Polygon(parent=self, align=uiconst.TOALL, blendMode=trinity.TR2_SBM_ADD) 848 self.RenderGradient() 849 850 def RenderGradient(self): 851 self.polygon.Flush() 852 directionAngle = math.pi / 2 853 fromDeg = directionAngle - self.angle / 2 854 toDeg = directionAngle + self.angle / 2 855 numSegments = 40 856 segmentStep = (toDeg - fromDeg) / float(numSegments) 857 c = self.color 858 innerColor = c 859 outerColor = (c[0], 860 c[1], 861 c[2], 862 0.0) 863 radius = 50 864 ro = self.polygon.GetRenderObject() 865 for i in xrange(numSegments + 1): 866 a = fromDeg + i * segmentStep 867 x = math.cos(a) 868 y = -math.sin(a) 869 innerVertex = trinity.Tr2Sprite2dVertex() 870 innerVertex.position = (self.width / 2 * uicore.desktop.dpiScaling, self.height / 2 * uicore.desktop.dpiScaling) 871 innerVertex.color = innerColor 872 ro.vertices.append(innerVertex) 873 outerVertex = trinity.Tr2Sprite2dVertex() 874 outerVertex.position = ((self.width / 2 + radius * x) * uicore.desktop.dpiScaling, (self.height / 2 + radius * y) * uicore.desktop.dpiScaling) 875 outerVertex.color = outerColor 876 ro.vertices.append(outerVertex) 877 878 for i in xrange(numSegments * 2): 879 triangle = trinity.Tr2Sprite2dTriangle() 880 triangle.index0 = i 881 triangle.index1 = i + 1 882 triangle.index2 = i + 2 883 ro.triangles.append(triangle) 884 885 def SetColor(self, color): 886 self.color = color 887 self.RenderGradient() 888 889 def SetFovAngle(self, angle): 890 self.angle = angle 891 self.RenderGradient() 892 893 894 import collections 895 Map2DItemInfoType = collections.namedtuple('Map2DItemInfoType', ['itemID', 896 'typeID', 897 'locationID', 898 'itemName', 899 'groupID', 900 'x', 901 'y', 902 'z']) 903 Map2DCelestialItemInfoType = collections.namedtuple('Map2DItemInfoType', ['itemID', 904 'typeID', 905 'orbitID', 906 'orbitIndex', 907 'celestialIndex', 908 'locationID', 909 'itemName', 910 'groupID', 911 'x', 912 'y', 913 'z']) 914 915 def GetMap2DConnectionsForUniverse(): 916 connections = [] 917 for regionID, regionData in cfg.mapRegionCache.iteritems(): 918 if regionID > const.mapWormholeRegionMin: 919 continue 920 for neighbourID in regionData.neighbours: 921 connections.append((regionID, neighbourID)) 922 923 return ((connections, [], []), []) 924 925 926 def GetMap2DConstellationConnectionsForRegion(regionID): 927 connectionsToOtherRegions = [] 928 connectionsWithinRegion = [] 929 externalItems = [] 930 regionInfo = cfg.mapRegionCache[regionID] 931 constellationsInRegion = set(regionInfo.constellationIDs) 932 for constellationID in constellationsInRegion: 933 constellation = cfg.mapConstellationCache[constellationID] 934 for neighbourID in constellation.neighbours: 935 if neighbourID not in constellationsInRegion: 936 nei = cfg.mapConstellationCache[neighbourID] 937 i = Map2DItemInfoType(itemID=neighbourID, locationID=nei.regionID, itemName=localization.GetByMessageID(nei.nameID), groupID=const.groupConstellation, typeID=const.typeConstellation, x=nei.center.x, y=nei.center.y, z=nei.center.z) 938 externalItems.append(i) 939 connectionsToOtherRegions.append((constellationID, neighbourID)) 940 else: 941 connectionsWithinRegion.append((constellationID, neighbourID)) 942 943 return ((connectionsToOtherRegions, connectionsWithinRegion, []), externalItems) 944 945 946 def GetMap2DConnectionsForConstellation(constellationID): 947 connectionsToOtherRegions = [] 948 connectionsToOtherConstellations = [] 949 connectionsWithinConstellation = [] 950 externalItems = [] 951 constellationInfo = cfg.mapConstellationCache[constellationID] 952 systemsInConstellation = set(constellationInfo.solarSystemIDs) 953 regionInfo = cfg.mapRegionCache[constellationInfo.regionID] 954 systemsInRegion = set(regionInfo.solarSystemIDs) 955 for solarSystemID in systemsInConstellation: 956 ssInfo = cfg.mapSystemCache[solarSystemID] 957 for neighbour in ssInfo.neighbours: 958 neighbourID = neighbour.solarSystemID 959 if neighbourID in systemsInConstellation: 960 connectionsWithinConstellation.append((solarSystemID, neighbourID)) 961 else: 962 nei = cfg.mapSystemCache[neighbourID] 963 externalItems.append(Map2DItemInfoType(itemID=neighbourID, locationID=nei.constellationID, itemName=localization.GetByMessageID(nei.nameID), groupID=const.groupSolarSystem, typeID=const.typeSolarSystem, x=nei.center.x, y=nei.center.y, z=nei.center.z)) 964 if neighbourID not in systemsInRegion: 965 connectionsToOtherRegions.append((solarSystemID, neighbourID)) 966 elif neighbourID not in systemsInConstellation: 967 connectionsToOtherConstellations.append((solarSystemID, neighbourID)) 968 969 return ((connectionsToOtherRegions, connectionsToOtherConstellations, connectionsWithinConstellation), externalItems) 970 971 972 def GetMap2DItemsForUniverse(): 973 items = [] 974 for regionID, regionData in cfg.mapRegionCache.iteritems(): 975 if regionID > const.mapWormholeRegionMin: 976 continue 977 i = Map2DItemInfoType(itemID=regionID, locationID=9, itemName=localization.GetByMessageID(regionData.nameID), groupID=const.groupRegion, typeID=const.typeRegion, x=regionData.center.x, y=regionData.center.y, z=regionData.center.z) 978 items.append(i) 979 980 return items 981 982 983 def GetMap2DItemsForRegion(regionID): 984 items = [] 985 regionData = cfg.mapRegionCache[regionID] 986 items.append(Map2DItemInfoType(itemID=regionID, locationID=9, itemName=localization.GetByMessageID(regionData.nameID), groupID=const.groupRegion, typeID=const.typeRegion, x=regionData.center.x, y=regionData.center.y, z=regionData.center.z)) 987 for constellationID in regionData.constellationIDs: 988 constellationData = cfg.mapConstellationCache[constellationID] 989 items.append(Map2DItemInfoType(itemID=constellationID, locationID=constellationData.regionID, itemName=localization.GetByMessageID(constellationData.nameID), groupID=const.groupConstellation, typeID=const.typeConstellation, x=constellationData.center.x, y=constellationData.center.y, z=constellationData.center.z)) 990 991 return items 992 993 994 def GetMap2DItemsForConstellation(constellationID): 995 items = [] 996 constellationData = cfg.mapConstellationCache[constellationID] 997 items.append(Map2DItemInfoType(itemID=constellationID, locationID=constellationData.regionID, itemName=localization.GetByMessageID(constellationData.nameID), groupID=const.groupConstellation, typeID=const.typeConstellation, x=constellationData.center.x, y=constellationData.center.y, z=constellationData.center.z)) 998 for solarSystemID in constellationData.solarSystemIDs: 999 solarSystemData = cfg.mapSystemCache[solarSystemID] 1000 items.append(Map2DItemInfoType(itemID=solarSystemID, locationID=solarSystemData.constellationID, itemName=localization.GetByMessageID(solarSystemData.nameID), groupID=const.groupSolarSystem, typeID=const.typeSolarSystem, x=solarSystemData.center.x, y=solarSystemData.center.y, z=solarSystemData.center.z)) 1001 1002 return items 1003 1004 1005 def GetMap2DItemsForSolarSystem(solarSystemID): 1006 items = [] 1007 try: 1008 ssContents = cfg.mapSolarSystemContentCache[solarSystemID] 1009 except (IndexError, KeyError): 1010 return [] 1011 1012 sm.GetService('map').GetSolarsystemItems(solarSystemID) 1013 primables = ssContents.stargates.keys() + ssContents.planets.keys() 1014 for planet in ssContents.planets.itervalues(): 1015 moons = getattr(planet, 'moons', {}) 1016 primables += getattr(planet, 'asteroidBelts', {}).keys() + getattr(planet, 'npcStations', {}).keys() + moons.keys() 1017 for moon in moons.itervalues(): 1018 primables += getattr(moon, 'asteroidBelts', {}).keys() + getattr(moon, 'npcStations', {}).keys() 1019 1020 cfg.evelocations.Prime(primables) 1021 for stargateID, stargate in ssContents.stargates.iteritems(): 1022 items.append(Map2DCelestialItemInfoType(itemID=stargateID, orbitID=1, orbitIndex=1, locationID=solarSystemID, celestialIndex=0, itemName=cfg.evelocations.Get(stargateID).locationName, groupID=const.groupStargate, typeID=stargate.typeID, x=stargate.position.x, y=stargate.position.y, z=stargate.position.z)) 1023 1024 for planetID, planet in ssContents.planets.iteritems(): 1025 items.append(Map2DCelestialItemInfoType(itemID=planetID, orbitID=1, orbitIndex=1, locationID=solarSystemID, celestialIndex=planet.celestialIndex, itemName=cfg.evelocations.Get(planetID).locationName, groupID=const.groupPlanet, typeID=planet.typeID, x=planet.position.x, y=planet.position.y, z=planet.position.z)) 1026 asteroidBelts = getattr(planet, 'asteroidBelts', {}) 1027 for asteroidBeltID, asteroidBelt in asteroidBelts.iteritems(): 1028 items.append(Map2DCelestialItemInfoType(itemID=asteroidBeltID, orbitID=planetID, orbitIndex=1, celestialIndex=planet.celestialIndex, locationID=solarSystemID, itemName=cfg.evelocations.Get(asteroidBeltID).locationName, groupID=9, typeID=asteroidBelt.typeID, x=asteroidBelt.position.x, y=asteroidBelt.position.y, z=asteroidBelt.position.z)) 1029 1030 npcStations = getattr(planet, 'npcStations', {}) 1031 for npcStationID, npcStation in npcStations.iteritems(): 1032 items.append(Map2DCelestialItemInfoType(itemID=npcStationID, orbitID=planetID, orbitIndex=1, celestialIndex=planet.celestialIndex, locationID=solarSystemID, itemName=cfg.evelocations.Get(npcStationID).locationName, groupID=const.groupStation, typeID=npcStation.typeID, x=npcStation.position.x, y=npcStation.position.y, z=npcStation.position.z)) 1033 1034 moons = getattr(planet, 'moons', {}) 1035 for moonID, moon in moons.iteritems(): 1036 items.append(Map2DCelestialItemInfoType(itemID=moonID, orbitID=planetID, orbitIndex=1, locationID=solarSystemID, celestialIndex=planet.celestialIndex, itemName=cfg.evelocations.Get(moonID).locationName, groupID=const.groupMoon, typeID=moon.typeID, x=moon.position.x, y=moon.position.y, z=moon.position.z)) 1037 asteroidBelts = getattr(moon, 'asteroidBelts', {}) 1038 for asteroidBeltID, asteroidBelt in asteroidBelts.iteritems(): 1039 items.append(Map2DCelestialItemInfoType(itemID=asteroidBeltID, orbitID=moonID, orbitIndex=1, celestialIndex=planet.celestialIndex, locationID=solarSystemID, itemName=cfg.evelocations.Get(asteroidBeltID).locationName, groupID=9, typeID=asteroidBelt.typeID, x=asteroidBelt.position.x, y=asteroidBelt.position.y, z=asteroidBelt.position.z)) 1040 1041 npcStations = getattr(moon, 'npcStations', {}) 1042 for npcStationID, npcStation in npcStations.iteritems(): 1043 items.append(Map2DCelestialItemInfoType(itemID=npcStationID, orbitID=planetID, orbitIndex=1, celestialIndex=planet.celestialIndex, locationID=solarSystemID, itemName=cfg.evelocations.Get(npcStationID).locationName, groupID=const.groupStation, typeID=npcStation.typeID, x=npcStation.position.x, y=npcStation.position.y, z=npcStation.position.z)) 1044 1045 return items