navigation.py (16420B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\maps\navigation.py 2 import types 3 import blue 4 import evecamera 5 import uthread 6 from carbon.common.script.sys.serviceConst import ROLE_GML, ROLE_WORLDMOD 7 from eve.client.script.ui.util import uix 8 import carbonui.const as uiconst 9 import trinity 10 import localization 11 import geo2 12 from carbon.common.script.util import timerstuff 13 from eve.client.script.ui.control.eveHint import BubbleHint 14 from eve.client.script.ui.shared.maps.palette import MapPalette 15 from carbonui.control.layer import LayerCore 16 from carbonui.uicore import uicore 17 from menu import MenuLabel 18 from player_messaging.client.ui_message import prompt_player_fsd_dialog 19 MOUSE_HOVER_REFRESH_TIME = 100 20 21 class StarMapLayer(LayerCore): 22 __nonpersistvars__ = ['wnd'] 23 __update_on_reload__ = 0 24 hoveringParticleID = None 25 lastMouseXPick = None 26 lastMouseYPick = None 27 lastMousePickTime = None 28 mouseStationary = False 29 mouseMovedAfterMouseDown = False 30 31 def __init__(self, *args, **kwargs): 32 LayerCore.__init__(self, *args, **kwargs) 33 self.smoothTranslateCameraTasklet = None 34 self.smoothDollyCameraTasklet = None 35 self.watchCameraTasklet = None 36 37 def __del__(self): 38 if self.watchCameraTasklet is not None: 39 self.watchCameraTasklet.kill() 40 41 def ApplyAttributes(self, attributes): 42 LayerCore.ApplyAttributes(self, attributes) 43 self.lastTimeLeftMouseWasPressed = blue.os.GetWallclockTime() 44 self.cursor = uiconst.UICURSOR_SELECT 45 self._isPicked = False 46 self.lastPickTime = blue.os.GetWallclockTime() 47 self.drag = False 48 self.bubbleHint = None 49 50 def Close(self, *args): 51 LayerCore.Close(self, *args) 52 self.pickThread = None 53 54 def MoveTF(self, tf, dx, dy): 55 camera = sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_STARMAP) 56 X = float(dx) / float(trinity.device.width) 57 Y = -float(dy) / float(trinity.device.height) 58 viewVec = camera.viewVec 59 upVec = geo2.Vec3Scale(camera.upVec, Y) 60 rightVec = geo2.Vec3Scale(camera.rightVec, X) 61 pos = geo2.Vec3Add(rightVec, upVec) 62 pos = geo2.Vec3Scale(pos, pow(tf.cameraDistSq, 0.5) * 1.5) 63 pos = geo2.QuaternionTransformVector(camera.rotationAroundParent, pos) 64 tf.translation = geo2.Vec3Add(tf.translation, pos) 65 66 def ScaleTF(self, tf, dy): 67 tf.scaling.Scale(1.0 + 0.025 * float(dy)) 68 if tf.scaling.x < 80.0: 69 tf.scaling.SetXYZ(80.0, 80.0, 80.0) 70 71 def OnMouseEnter(self, *args): 72 if sm.GetService('ui').IsUiVisible(): 73 uicore.layer.main.state = uiconst.UI_PICKCHILDREN 74 75 def SmoothTranslateCamera(self, dx, dy): 76 dx *= 2.0 77 dy *= 2.0 78 79 def DoMove(dx, dy): 80 lib = uicore.uilib 81 friction = 0.9 82 starmap = sm.GetService('starmap') 83 while self.display: 84 starmap.TranslateCamera(lib.x, lib.y, int(dx * 0.5), int(dy * 0.5)) 85 starmap.OnCameraMoved() 86 dx = dx * friction 87 dy = dy * friction 88 if int(dx) == 0 and int(dy) == 0: 89 break 90 blue.pyos.synchro.SleepWallclock(10) 91 92 if self.smoothTranslateCameraTasklet is not None: 93 self.smoothTranslateCameraTasklet.kill() 94 self.smoothTranslateCameraTasklet = uthread.new(DoMove, dx, dy) 95 96 def SmoothOrbitParent(self, dx, dy): 97 98 def WatchCamera(camera): 99 epsilon = 0.0001 100 yaw = camera.yaw 101 pitch = camera.pitch 102 starmap = sm.GetService('starmap') 103 while True: 104 if abs(camera.yaw - yaw) > epsilon or abs(camera.pitch - pitch) > epsilon: 105 starmap.OnCameraMoved() 106 yaw = camera.yaw 107 pitch = camera.pitch 108 blue.pyos.synchro.SleepWallclock(50) 109 110 camera = sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_STARMAP) 111 fov = camera.fieldOfView 112 camera.OrbitParent(-dx * fov * 0.2, dy * fov * 0.2) 113 if self.watchCameraTasklet is None: 114 self.watchCameraTasklet = uthread.new(WatchCamera, camera) 115 116 def SmoothDollyCamera(self, dy): 117 dy *= 2.5 118 119 def DoDolly(dy): 120 friction = 0.9 121 camera = sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_STARMAP) 122 if camera is None: 123 return 124 starmap = sm.GetService('starmap') 125 while True: 126 camera.Dolly(-dy * 0.002 * abs(camera.translationFromParent)) 127 camera.translationFromParent = camera.CheckTranslationFromParent(camera.translationFromParent) 128 starmap.OnCameraMoved() 129 dy = dy * friction 130 if int(dy) == 0: 131 break 132 blue.pyos.synchro.SleepWallclock(10) 133 134 starmap.CheckLabelDist() 135 self.mouseStationary = False 136 137 if self.smoothDollyCameraTasklet is not None: 138 self.smoothDollyCameraTasklet.kill() 139 self.smoothDollyCameraTasklet = uthread.new(DoDolly, dy) 140 141 def OnMouseMove(self, *args): 142 if not self._isPicked: 143 return 144 self.mouseMovedAfterMouseDown = True 145 starmap = sm.GetService('starmap') 146 lib = uicore.uilib 147 dx = lib.dx 148 dy = lib.dy 149 camera = sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_STARMAP) 150 if camera is None: 151 return 152 ctrl = lib.Key(uiconst.VK_CONTROL) 153 shift = lib.Key(uiconst.VK_SHIFT) 154 self.mouseDownRegionID = None 155 if session.role & (ROLE_GML | ROLE_WORLDMOD): 156 if ctrl and shift and lib.leftbtn and not lib.rightbtn: 157 if self.pickedTF is not None: 158 self.MoveTF(self.pickedTF, dx, dy) 159 return 160 if ctrl and shift and not lib.leftbtn and lib.rightbtn: 161 if self.pickedTF is not None: 162 self.ScaleTF(self.pickedTF, dy) 163 return 164 drag = False 165 if not lib.leftbtn and lib.rightbtn: 166 drag = True 167 elif lib.leftbtn and not lib.rightbtn: 168 if starmap.IsFlat(): 169 drag = True 170 if drag: 171 self.SmoothTranslateCamera(dx, dy) 172 elif lib.leftbtn and lib.rightbtn: 173 modifier = uicore.mouseInputHandler.GetCameraZoomModifier() 174 self.SmoothDollyCamera(modifier * dy) 175 elif lib.leftbtn and not lib.rightbtn: 176 self.SmoothOrbitParent(dx, dy) 177 else: 178 regionID = self.PickRegionID() 179 if regionID is not None: 180 label = starmap.GetRegionLabel(regionID) 181 starmap.UpdateLines(regionID) 182 self.drag = drag 183 184 def OverridePick(self, x, y): 185 if uicore.uilib.leftbtn or uicore.uilib.rightbtn: 186 return self 187 mouseX = uicore.uilib.x 188 mouseY = uicore.uilib.y 189 if self.lastMouseXPick is None: 190 self.lastMouseXPick = mouseX 191 self.lastMouseYPick = mouseY 192 self.mouseStationary = False 193 if abs(mouseX - self.lastMouseXPick) + abs(mouseY - self.lastMouseYPick) == 0: 194 if not self.mouseStationary: 195 self.mouseStationary = True 196 self.pickThread = timerstuff.AutoTimer(5, self.CheckPickNew, mouseX, mouseY) 197 else: 198 self.mouseStationary = False 199 if not self.lastMousePickTime or blue.os.TimeDiffInMs(self.lastMousePickTime, blue.os.GetWallclockTime()) >= 100: 200 self.lastMouseXPick = mouseX 201 self.lastMouseYPick = mouseY 202 self.lastMousePickTime = blue.os.GetWallclockTime() 203 return self 204 205 def CheckPickNew(self, mouseX, mouseY): 206 self.pickThread = None 207 if self.destroyed: 208 return 209 if (mouseX, mouseY) != (uicore.uilib.x, uicore.uilib.y): 210 return 211 starmap = sm.GetService('starmap') 212 particleID = starmap.PickParticle() 213 if particleID != None and self.hoveringParticleID != particleID: 214 solarsystemID = starmap.GetItemIDFromParticleID(particleID) 215 if solarsystemID: 216 starmap.ShowCursorInterest(solarsystemID, particleID) 217 uthread.new(starmap.UpdateLines, solarsystemID) 218 self.hoveringParticleID = particleID 219 220 def PickRegionID(self): 221 scene = sm.GetService('sceneManager').GetRegisteredScene('starmap') 222 if scene is None: 223 return 224 x, y = uicore.ScaleDpi(uicore.uilib.x), uicore.ScaleDpi(uicore.uilib.y) 225 projection, view, viewport = uix.GetFullscreenProjectionViewAndViewport() 226 pick = scene.PickObject(x, y, projection, view, viewport) 227 if pick is not None: 228 if hasattr(pick, 'regionID'): 229 return pick.regionID 230 if pick.name[:11] == '__regionDot': 231 return int(pick.name[11:]) 232 233 def ShowBubbleHint(self, particleID, solarsystemID, mapColor = None, extended = 0): 234 starmap = sm.GetService('starmap') 235 if not extended: 236 blue.pyos.synchro.SleepWallclock(25) 237 if self.destroyed: 238 return 239 _particleID = starmap.PickParticle() 240 if _particleID is None or _particleID != particleID: 241 self.state = uiconst.UI_NORMAL 242 return 243 self.bubbleHint = (particleID, 244 solarsystemID, 245 mapColor, 246 extended) 247 prompt_player_fsd_dialog('click') 248 mapData = sm.GetService('map').GetItem(solarsystemID) 249 bubblehint = sm.GetService('systemmap').GetBubbleHint(solarsystemID, mapData=mapData, extended=extended) 250 if self.destroyed: 251 return 252 hint = bubblehint or [mapData.itemName] 253 data = starmap.GetStarData() 254 if particleID in data: 255 hint.append('<line>') 256 hint.append(localization.GetByLabel('UI/Map/Navigation/hintStatistics')) 257 hintFunc, hintArgs = data[particleID] 258 particleData = hintFunc(*hintArgs) 259 if type(particleData) == types.TupleType: 260 for each in particleData: 261 hint += each 262 263 else: 264 hint.append(particleData) 265 if hint: 266 bubble = self.GetBubble() 267 if extended: 268 bubble.state = uiconst.UI_DISABLED 269 else: 270 bubble.state = uiconst.UI_HIDDEN 271 bubble.ShowHint(hint, 0) 272 bubble.parent.SetOrder(0) 273 blue.pyos.synchro.Yield() 274 if bubble.destroyed or self.destroyed: 275 return 276 bubble.state = uiconst.UI_NORMAL 277 self.hoveringParticleID = particleID 278 starmap.ShowCursorInterest(solarsystemID) 279 self.state = uiconst.UI_NORMAL 280 281 def ExpandBubbleHint(self, bubble, expand = 1): 282 if not self.destroyed and self.bubbleHint: 283 tple, regionID, mapColor, exp = self.bubbleHint 284 if not exp: 285 self.state = uiconst.UI_DISABLED 286 uthread.new(self.ShowBubbleHint, tple, regionID, mapColor, 1) 287 288 def GetBubble(self): 289 mapUICursor = sm.GetService('starmap').GetUICursor() 290 if mapUICursor: 291 for each in mapUICursor.children[:]: 292 if each.name == 'bubblehint': 293 each.Close() 294 295 bubble = BubbleHint(parent=mapUICursor, name='bubblehint', align=uiconst.TOPLEFT, width=0, height=0, idx=0, state=uiconst.UI_PICKCHILDREN) 296 bubble.sr.ExpandHint = self.ExpandBubbleHint 297 return bubble 298 299 def ResetHightlight(self): 300 blue.pyos.synchro.SleepWallclock(400) 301 if self.destroyed: 302 return 303 regionID = self.PickRegionID() 304 sm.GetService('starmap').UpdateLines(regionID) 305 306 def OnClick(self, *args): 307 if self.destroyed: 308 return 309 if self.mouseMovedAfterMouseDown: 310 return 311 starmap = sm.GetService('starmap') 312 particleID = starmap.PickParticle() 313 if particleID: 314 if particleID == self.hoveringParticleID: 315 solarSystemID = starmap.GetItemIDFromParticleID(particleID) 316 starmap.SetInterest(solarSystemID) 317 return 318 regionID = self.PickRegionID() 319 if regionID is not None and getattr(self, 'mouseDownRegionID', None) == regionID: 320 starmap.SetInterest(regionID) 321 322 def OnMouseDown(self, button): 323 self.mouseMovedAfterMouseDown = False 324 self._isPicked = True 325 scene = sm.GetService('sceneManager').GetRegisteredScene('starmap') 326 self.pickedTF = None 327 if scene is not None: 328 projection, view, viewport = uix.GetFullscreenProjectionViewAndViewport() 329 self.pickedTF = scene.PickObject(uicore.ScaleDpi(uicore.uilib.x), uicore.ScaleDpi(uicore.uilib.y), projection, view, viewport) 330 self.mouseDownRegionID = self.PickRegionID() 331 332 def OnMouseUp(self, button): 333 if not (uicore.uilib.leftbtn or uicore.uilib.rightbtn): 334 self._isPicked = False 335 if sm.GetService('ui').IsUiVisible(): 336 uicore.layer.main.state = uiconst.UI_PICKCHILDREN 337 self.lastTimeLeftMouseWasPressed = blue.os.GetWallclockTime() 338 self.pickedTF = None 339 340 def OnMouseWheel(self, *args): 341 modifier = uicore.mouseInputHandler.GetCameraZoomModifier() 342 self.ZoomBy(modifier * uicore.uilib.dz) 343 return 1 344 345 def ZoomBy(self, amount): 346 if self.destroyed: 347 return 348 self.SmoothDollyCamera(-amount / 10) 349 350 def OnDblClick(self, *args): 351 if self.destroyed: 352 return 353 starmap = sm.GetService('starmap') 354 solarSystemID = starmap.PickSolarSystemID() 355 if solarSystemID is not None: 356 starmap.SetInterest(solarSystemID) 357 358 def GetMenu(self): 359 if self.drag: 360 self.drag = False 361 return 362 mapSvc = sm.GetService('map') 363 starmapSvc = sm.GetService('starmap') 364 solarsystemID = starmapSvc.PickSolarSystemID() 365 if solarsystemID is not None: 366 return starmapSvc.GetItemMenu(solarsystemID) 367 regionID = self.PickRegionID() 368 if regionID: 369 return starmapSvc.GetItemMenu(regionID) 370 if blue.os.GetWallclockTimeNow() - self.lastTimeLeftMouseWasPressed < 30000: 371 return 372 loctations = [(MenuLabel('UI/Map/Navigation/menuSolarSystem'), starmapSvc.SetInterest, (session.solarsystemid2, 1)), (MenuLabel('UI/Map/Navigation/menuConstellation'), starmapSvc.SetInterest, (session.constellationid, 1)), (MenuLabel('UI/Map/Navigation/menuRegion'), starmapSvc.SetInterest, (session.regionid, 1))] 373 panel = [(MenuLabel('UI/Map/Navigation/menuSearch'), self.ShowPanel, (localization.GetByLabel('UI/Map/Navigation/menuSearch'),)), (MenuLabel('UI/Map/Navigation/menuDisplayMapSettings'), self.ShowPanel, (localization.GetByLabel('UI/Map/Navigation/lblStarMap'),))] 374 m = [(MenuLabel('UI/Map/Navigation/menuSelectCurrent'), loctations)] 375 waypoints = starmapSvc.GetWaypoints() 376 if len(waypoints): 377 waypointList = [] 378 wpCount = 1 379 for waypointID in waypoints: 380 waypointItem = mapSvc.GetItem(waypointID) 381 caption = MenuLabel('UI/Map/Navigation/menuWaypointEntry', {'itemName': waypointItem.itemName, 382 'wpCount': wpCount}) 383 waypointList += [(caption, starmapSvc.SetInterest, (waypointID, 1))] 384 wpCount += 1 385 386 m.append((MenuLabel('UI/Map/Navigation/menuSelectWaypoint'), waypointList)) 387 m += [None, (MenuLabel('UI/Map/Navigation/menuWorldControlPanel'), panel)] 388 if len(starmapSvc.GetWaypoints()) > 0: 389 m.append(None) 390 m.append((MenuLabel('UI/Map/Navigation/menuClearWaypoints'), starmapSvc.ClearWaypoints, (None,))) 391 if starmapSvc.genericRoute: 392 m.append((MenuLabel('UI/Map/Navigation/menuClearRoute'), starmapSvc.RemoveGenericPath)) 393 return m 394 395 def ShowPanel(self, panelName): 396 wnd = MapPalette.Open() 397 if wnd: 398 uthread.pool('MapNav::ShowPanel', wnd.ShowPanel, panelName)