scanSvc.py (28688B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\scanSvc.py 2 import blue 3 import carbonui.const as uiconst 4 import evetypes 5 import functools 6 import geo2 7 import localization 8 import probescanning.customFormations as customFormations 9 import probescanning.probeTracker as probeTracker 10 import probescanning.resultFilter as resultFilter 11 import probescanning.scanHandler as scanHandler 12 import uthread 13 import utillib 14 from carbon.client.script.environment.AudioUtil import PlaySound 15 from carbon.common.script.sys.service import Service 16 from carbon.common.script.sys.serviceConst import ROLE_ANY, ROLE_GML, ROLE_QA, ROLE_WORLDMOD 17 from carbon.common.script.util.format import FmtDist 18 from carbonui.uicore import uicore 19 from eve.client.script.ui.inflight.probeScannerWindow import ProbeScannerWindow as Scanner 20 from eve.client.script.ui.shared.maps import mapcommon 21 from eve.common.script.sys import idCheckers 22 from eveexceptions import ExceptionEater, UserError 23 from eveservices.menu import GetMenuService 24 from menu import MenuLabel 25 from player_messaging.client.ui_message import prompt_player_fsd_dialog 26 from probescanning.const import COMBAT_TARGETS 27 from probescanning.explorationSites import get_exploration_site_group_name 28 from probescanning.fiFoDict import FiFoDict 29 from probescanning.formations import SELF_CENTER_FORMATION 30 from probescanning.util import IsExplorationSite 31 RECONNECT_DELAY_MINUTES = 1 32 MIN_PROBE_RECOVER_DISTANCE = 2000 33 NAME_BY_SCANGROUPID = {const.probeScanGroupAnomalies: 'UI/Inflight/Scanner/CosmicAnomaly', 34 const.probeScanGroupSignatures: 'UI/Inflight/Scanner/CosmicSignature', 35 const.probeScanGroupShips: 'UI/Inflight/Scanner/Ship', 36 const.probeScanGroupStructures: 'UI/Inflight/Scanner/Structure', 37 const.probeScanGroupDrones: 'UI/Inflight/Scanner/Drone', 38 const.probeScanGroupCharges: 'UI/Inflight/Scanner/Charge', 39 const.probeScanGroupNPCs: 'UI/Inflight/Scanner/NPC', 40 const.probeScanGroupFighters: 'UI/Inflight/Scanner/Fighter', 41 const.probeScanGroupStarBase: 'UI/Inflight/Scanner/StarBase', 42 const.probeScanGroupOrbitals: 'UI/Inflight/Scanner/Orbital', 43 const.probeScanGroupDeployable: 'UI/Inflight/Scanner/Deployable', 44 const.probeScanGroupSovereignty: 'UI/Inflight/Scanner/Sovereignty', 45 const.probeScanGroupAbyssalTraces: 'UI/Inflight/Scanner/AbyssalTrace'} 46 47 def UserErrorIfScanning(action, *args, **kwargs): 48 49 @functools.wraps(action) 50 def wrapper(*args, **kwargs): 51 if sm.StartService('scanSvc').IsScanning(): 52 raise UserError('ScanInProgressGeneric') 53 return action(*args, **kwargs) 54 55 return wrapper 56 57 58 class ScanSvc(Service): 59 __guid__ = 'svc.scanSvc' 60 __servicename__ = 'svc.scanSvc' 61 __displayname__ = 'Scanner Probe Service' 62 __notifyevents__ = ['OnSessionChanged', 63 'OnSystemScanStarted', 64 'OnSystemScanStopped', 65 'OnProbeWarpStart', 66 'OnProbesIdle', 67 'OnProbeStateChanged', 68 'OnNewProbe', 69 'OnRemoveProbe', 70 'OnScannerInfoRemoved', 71 'DoSimClockRebase', 72 'OnCustomFormationDeleted'] 73 __dependencies__ = ['michelle', 'godma', 'audio'] 74 __uthreads__ = [] 75 __exportedcalls__ = {'SetProbeDestination': [ROLE_ANY], 76 'SetProbeRangeStep': [ROLE_ANY], 77 'GetProbeData': [ROLE_ANY], 78 'GetScanResults': [ROLE_ANY], 79 'RequestScans': [ROLE_ANY], 80 'RecoverProbe': [ROLE_ANY], 81 'RecoverProbes': [ROLE_ANY], 82 'ReconnectToLostProbes': [ROLE_ANY], 83 'DestroyProbe': [ROLE_ANY], 84 'GetScanRangeStepsByTypeID': [ROLE_ANY], 85 'QAScanSites': [ROLE_QA]} 86 __configvalues__ = {'max_scan_systems_stored': 50} 87 88 def __init__(self): 89 Service.__init__(self) 90 self.lastResults = None 91 self.probeLabels = {} 92 self.selectedSites = set() 93 self.lastReconnection = None 94 self.lastRangeStepUsed = 5 95 self.remoteObject = None 96 self.probeTracker = None 97 self.resultFilter = None 98 self.scanHandlerBySystem = None 99 100 def Run(self, memStream = None): 101 self.probeTracker = probeTracker.ProbeTracker(self, sm.ScatterEvent) 102 self.resultFilter = resultFilter.ResultFilter() 103 self.scanHandlerBySystem = FiFoDict(max_size=self.max_scan_systems_stored, default_factory=scanHandler.ScanHandler, factory_params=(self, self.resultFilter)) 104 105 def GetScanMan(self): 106 if self.remoteObject is None: 107 self.remoteObject = sm.RemoteSvc('scanMgr').GetSystemScanMgr() 108 return self.remoteObject 109 110 def OnNewProbe(self, probe): 111 self.probeTracker.AddProbe(probe) 112 113 def OnRemoveProbe(self, probeID): 114 self.probeTracker.RemoveProbe(probeID) 115 116 def DoSimClockRebase(self, times): 117 if not self.lastReconnection: 118 return 119 oldSimTime, newSimTime = times 120 self.lastReconnection += newSimTime - oldSimTime 121 122 def GetActiveProbes(self): 123 return self.probeTracker.GetActiveProbes() 124 125 def HasAvailableProbes(self): 126 return self.probeTracker.HasAvailableProbes() 127 128 def GetProbeState(self, probeID): 129 return self.probeTracker.GetProbeState(probeID) 130 131 def IsProbeActive(self, probeID): 132 return self.probeTracker.IsProbeActive(probeID) 133 134 def GetProbeData(self): 135 return self.probeTracker.GetProbeData() 136 137 def GetScaledProbes(self, point, probeIDs): 138 return self.probeTracker.GetScaledProbes(point, probeIDs, mapcommon.SYSTEMMAP_SCALE) 139 140 def OnSessionChanged(self, isRemote, sess, change): 141 if 'charid' in change and change['charid'][1] is not None: 142 self.probeTracker.Refresh() 143 self.scanHandlerBySystem.clear() 144 if 'solarsystemid' in change or 'shipid' in change or 'structureid' in change: 145 if self.IsScanning(): 146 self.OnSystemScanStopped(self.GetScanningProbes(), None, None) 147 self.FlushScannerState(reinjectSites='solarsystemid' not in change) 148 if sess.charid is None and 'charid' in change: 149 self.scanHandlerBySystem.clear() 150 if sess.solarsystemid: 151 self.ClearCombatTargets() 152 153 def ClearCombatTargets(self): 154 self.scanHandlerBySystem[session.solarsystemid].ClearCombatTargets() 155 156 def SetProbeDestination(self, probeID, location): 157 self.probeTracker.SetProbeDestination(probeID, location) 158 159 def SetProbeRangeStep(self, probeID, rangeStep): 160 self.probeTracker.SetProbeRangeStep(probeID, rangeStep) 161 162 def SetProbeActiveState(self, probeID, state): 163 self.probeTracker.SetProbeActiveState(probeID, state) 164 165 @UserErrorIfScanning 166 def RequestScans_Check(self): 167 if idCheckers.IsAbyssalSpaceSystem(session.solarsystemid2): 168 key = 'ProbeScannerAbyssalSpaceWarning' 169 response = prompt_player_fsd_dialog(key, buttons=uiconst.YESNO, suppress=uiconst.ID_YES) 170 if response == uiconst.ID_NO: 171 return 172 elif idCheckers.IsVoidSpaceSystem(session.solarsystemid2): 173 raise UserError('ProbeScannerVoidSpaceHint') 174 self.RequestScans() 175 176 def RequestScans(self): 177 probes = self.probeTracker.GetProbesForScanning() 178 self.GetScanMan().RequestScans(probes) 179 probeIDs = probes.keys() if probes is not None else [session.shipid] 180 self.scanHandlerBySystem[session.solarsystemid].SetProbesAsScanning(probeIDs) 181 self.probeTracker.SetProbesAsMoving(probes) 182 183 def OnProbeStateChanged(self, probeID, probeState): 184 self.probeTracker.OnProbeStateChanged(probeID, probeState) 185 186 def OnCustomFormationDeleted(self, formationID): 187 self.probeTracker.OnFormationDeleted(formationID) 188 189 def GetScanningProbes(self): 190 return self.scanHandlerBySystem[session.solarsystemid].GetScanningProbes() 191 192 def GetScanResults(self): 193 return self.scanHandlerBySystem[session.solarsystemid].GetScanResults() 194 195 def GetCurrentScan(self): 196 return self.scanHandlerBySystem[session.solarsystemid].GetCurrentScan() 197 198 def GetIgnoredResults(self): 199 return self.scanHandlerBySystem[session.solarsystemid].GetIgnoredResults() 200 201 def GetIgnoredResultsDesc(self): 202 resultIDs = self.GetIgnoredResults() 203 descList = [] 204 for id in resultIDs: 205 result = self.scanHandlerBySystem[session.solarsystemid].resultsHistory.GetResult(id) 206 if result.id: 207 descList.append((id, self.GetDisplayName(result))) 208 209 return descList 210 211 def OnProbeWarpStart(self, probeID, fromPos, toPos, startTime, duration): 212 self.LogInfo('OnProbeWarpStart', probeID) 213 214 def OnProbesIdle(self, probes): 215 self.probeTracker.OnProbesIdle(probes) 216 217 def UpdateProbeState(self, probeID, state, caller = None, notify = True): 218 self.probeTracker.UpdateProbeState(probeID, state, caller=None, notify=True) 219 220 def UpdateProbePosition(self, probeID, position): 221 self.probeTracker.UpdateProbePosition(probeID, position) 222 223 def OnSystemScanStarted(self, startTime, durationMs, probes): 224 self.scanHandlerBySystem[session.solarsystemid].OnSystemScanStarted(startTime, durationMs, probes) 225 sm.ScatterEvent('OnSystemScanBegun') 226 PlaySound('msg_newscan_probe_analyze_play') 227 228 def OnSystemScanStopped(self, probes, results, absentTargets): 229 PlaySound('msg_newscan_probe_analyze_play') 230 PlaySound('msg_newscan_probe_analyze_stop') 231 if not results: 232 prompt_player_fsd_dialog('ScnNoResults') 233 self.scanHandlerBySystem[session.solarsystemid].OnSystemScanStopped(probes, results, absentTargets) 234 sm.ScatterEvent('OnSystemScanDone') 235 236 def GetScanRangeStepsByTypeID(self, typeID): 237 return self.probeTracker.GetScanRangeStepsByTypeID(typeID) 238 239 def DestroyProbe(self, probeID): 240 self.probeTracker.DestroyProbe(probeID, self.GetScanMan().DestroyProbe) 241 242 def ReconnectToLostProbes(self): 243 if not session.solarsystemid2: 244 return 245 ship = sm.StartService('michelle').GetItem(session.shipid) 246 if ship and ship.groupID == const.groupCapsule: 247 raise UserError('ScnProbeRecoverToPod') 248 if self.CanClaimProbes(): 249 self.lastReconnection = blue.os.GetSimTime() 250 try: 251 self.lastReconnection = blue.os.GetSimTime() 252 self.GetScanMan().ReconnectToLostProbes() 253 finally: 254 uthread.new(self.Thread_ShowReconnectToProbesAvailable, self.lastReconnection) 255 256 else: 257 seconds = RECONNECT_DELAY_MINUTES * const.MIN - (blue.os.GetSimTime() - self.lastReconnection) 258 raise UserError('ScannerProbeReconnectWait', {'when': seconds}) 259 260 def Thread_ShowReconnectToProbesAvailable(self, lastReconnection): 261 snooze = (RECONNECT_DELAY_MINUTES * const.MIN - (blue.os.GetSimTime() - self.lastReconnection)) / const.MSEC 262 while snooze > 0: 263 blue.pyos.synchro.SleepSim(snooze) 264 if self.lastReconnection is None: 265 break 266 snooze = (RECONNECT_DELAY_MINUTES * const.MIN - (blue.os.GetSimTime() - self.lastReconnection)) / const.MSEC 267 268 sm.ScatterEvent('OnReconnectToProbesAvailable') 269 270 def CanClaimProbes(self): 271 if self.HasOnlineProbeLauncher() and (self.lastReconnection is None or blue.os.GetSimTime() - self.lastReconnection > RECONNECT_DELAY_MINUTES * const.MIN): 272 return True 273 return False 274 275 def HasOnlineProbeLauncher(self): 276 shipItem = sm.GetService('godma').GetStateManager().GetItem(session.shipid) 277 if shipItem is not None: 278 for module in shipItem.modules: 279 if module.groupID == const.groupScanProbeLauncher and module.isOnline: 280 return True 281 282 return False 283 284 def GetProbeLabel(self, probeID): 285 if probeID in self.probeLabels: 286 return self.probeLabels[probeID] 287 newlabel = localization.GetByLabel('UI/Inflight/Scanner/ProbeLabel', probeIndex=len(self.probeLabels) + 1) 288 self.probeLabels[probeID] = newlabel 289 return newlabel 290 291 def RecoverProbe(self, probeID): 292 self.RecoverProbes([probeID]) 293 294 def RecoverProbes(self, probeIDs): 295 ship = sm.StartService('michelle').GetItem(session.shipid) 296 if ship and ship.groupID == const.groupCapsule: 297 raise UserError('ScnProbeRecoverToPod') 298 ballpark = sm.GetService('michelle').GetBallpark() 299 for id in probeIDs: 300 try: 301 if ballpark.GetBall(id).surfaceDist < MIN_PROBE_RECOVER_DISTANCE: 302 raise UserError('ProbesTooCloseToRecover') 303 except AttributeError: 304 continue 305 306 PlaySound('msg_newscan_probe_recover_play') 307 self.probeTracker.RecoverProbes(probeIDs, self.AskServerToRecallProbes) 308 309 def AskServerToRecallProbes(self, probeIDs): 310 return self.GetScanMan().RecoverProbes(probeIDs) 311 312 def OnScannerInfoRemoved(self): 313 self.LogInfo('OnScannerInfoRemoved received: flushing scanner state') 314 self.FlushScannerState(clearResults=True) 315 316 def QAOverrideProbeExpiry(self, duration): 317 self.GetScanMan().QAOverrideProbeExpiry(duration) 318 for probe in self.probeTracker.GetProbeData().values(): 319 probe.expiry = blue.os.GetSimTime() + long(10000 * duration) 320 321 def FlushScannerState(self, reinjectSites = True, clearResults = False): 322 self.LogInfo('FlushScannerState: resetting state and scattering OnScannerDisconnected') 323 if clearResults: 324 del self.scanHandlerBySystem[session.solarsystemid2] 325 self.probeTracker.Refresh() 326 if reinjectSites: 327 with ExceptionEater('Failure Reinjecting Anomalies'): 328 self.InjectSitesAsScanResults(sm.GetService('sensorSuite').probeScannerController.GetAllSites()) 329 self.remoteObject = None 330 PlaySound('msg_newscan_probe_analyze_stop') 331 sm.ScatterEvent('OnScannerDisconnected') 332 333 def PruneSites(self): 334 sites = [ site['id'] for site in sm.GetService('sensorSuite').probeScannerController.GetAllSites() ] 335 sitesToPrune = [] 336 for site in self.GetResults(applyFiltering=False)[0]: 337 if site['id'] not in sites and site['scanGroupID'] not in COMBAT_TARGETS: 338 sitesToPrune.append(site['id']) 339 340 self.ClearResults(*sitesToPrune) 341 342 def IsScanning(self): 343 return self.scanHandlerBySystem[session.solarsystemid].IsScanning() 344 345 def GetProbeMenu(self, probeID, probeIDs = None, *args): 346 menu = [] 347 if probeID == session.shipid: 348 return menu 349 bp = sm.StartService('michelle').GetBallpark(doWait=True) 350 if bp is None: 351 return menu 352 probeIDs = probeIDs or [probeID] 353 if probeID not in probeIDs: 354 probeIDs.append(probeID) 355 if session.role & (ROLE_GML | ROLE_WORLDMOD): 356 menu.append(('CopyID', self._GMCopyID, (probeID,))) 357 menu.append(None) 358 probes = self.GetProbeData() 359 if probeID in probes: 360 probe = probes[probeID] 361 scanRanges = self.GetScanRangeStepsByTypeID(probe.typeID) 362 menu.append((MenuLabel('UI/Inflight/Scanner/ScanRange'), [ (FmtDist(range), self.SetScanRange_Check, (probeID, 363 probeIDs, 364 range, 365 index + 1)) for index, range in enumerate(scanRanges) ])) 366 menu.append((MenuLabel('UI/Inflight/Scanner/RecoverProbe'), self.RecoverProbe_Check, (probeID, probeIDs))) 367 return menu 368 369 def _GMCopyID(self, id): 370 blue.pyos.SetClipboardData(str(id)) 371 372 @UserErrorIfScanning 373 def SetScanRange_Check(self, probeID, probeIDs, range, rangeStep): 374 for _probeID in probeIDs: 375 self.SetProbeRangeStep(_probeID, rangeStep) 376 377 @UserErrorIfScanning 378 def RecoverProbe_Check(self, probeID, probeIDs): 379 for _probeID in probeIDs: 380 self.RecoverProbe(_probeID) 381 382 @UserErrorIfScanning 383 def SetProbeActiveStateOn_Check(self, probeID, probeIDs): 384 for _probeID in probeIDs: 385 self.GetScanMan().SetActivityState(probeIDs, True) 386 self.SetProbeActiveState(_probeID, True) 387 388 @UserErrorIfScanning 389 def SetProbeActiveStateOff_Check(self, probeID, probeIDs): 390 for _probeID in probeIDs: 391 self.GetScanMan().SetActivityState(probeIDs, False) 392 self.SetProbeActiveState(_probeID, False) 393 394 @UserErrorIfScanning 395 def DestroyProbe_Check(self, probeID, probeIDs): 396 if probeIDs and prompt_player_fsd_dialog('DestroySelectedProbes', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 397 for _probeID in probeIDs: 398 self.DestroyProbe(_probeID) 399 400 def IgnoreResult(self, *targets): 401 self.scanHandlerBySystem[session.solarsystemid2].IgnoreResult(*targets) 402 403 def ClearIgnoredResults(self): 404 self.scanHandlerBySystem[session.solarsystemid2].ClearIgnoredResults() 405 406 def ClearResults(self, *targets): 407 self.scanHandlerBySystem[session.solarsystemid2].ClearResults(*targets) 408 409 def AlignToPosition(self, position): 410 ballpark = self.michelle.GetBallpark() 411 myBall = self.michelle.GetBall(ballpark.ego) 412 myPosition = (myBall.x, myBall.y, myBall.z) 413 directionalVector = geo2.Vec3SubtractD(position, myPosition) 414 rbp = self.michelle.GetRemotePark() 415 rbp.CmdGotoDirection(directionalVector[0], directionalVector[1], directionalVector[2]) 416 417 def IgnoreOtherResults(self, *targets): 418 self.scanHandlerBySystem[session.solarsystemid].IgnoreOtherResults(*targets) 419 420 def ShowIgnoredResult(self, targetID): 421 self.scanHandlerBySystem[session.solarsystemid].ShowIgnoredResult(targetID) 422 423 def GetProbeLauncher(self): 424 ship = self.godma.GetItem(session.shipid) 425 if ship: 426 for module in ship.modules: 427 if not module.isOnline: 428 continue 429 if module.groupID == const.groupScanProbeLauncher: 430 return module 431 432 def FindModuleAndLaunchProbes(self, numProbes): 433 ship = self.godma.GetItem(session.shipid) 434 module = self.GetProbeLauncher() 435 if ship and module and any((s.locationID == session.shipid and s.flagID == module.flagID for s in ship.sublocations)): 436 for effect in module.effects.itervalues(): 437 if effect.isDefault: 438 dogmaLM = self.godma.GetStateManager().GetDogmaLM() 439 dogmaLM.LaunchProbes(module.itemID, numProbes) 440 PlaySound('msg_newscan_probe_launch_play') 441 return 442 443 def GetNumChargesInProbeLauncher(self): 444 charge = self.GetChargesInProbeLauncher() 445 if charge is None: 446 return 0 447 return charge.quantity 448 449 def GetChargesInProbeLauncher(self): 450 launcher = self.GetProbeLauncher() 451 if launcher is None: 452 return 453 flagID = launcher.flagID 454 return self.godma.GetStateManager().GetSubLocation(session.shipid, flagID) 455 456 def CanLaunchFormation(self, formationID): 457 if formationID == SELF_CENTER_FORMATION: 458 return bool(self.GetActiveProbes()) 459 charges = self.GetNumChargesInProbeLauncher() 460 return self.probeTracker.CanCreateFormation(formationID, charges) 461 462 def MoveProbesToFormation(self, formationID, initialPosition = None): 463 self.probeTracker.MoveProbesToFormation(formationID, self.FindModuleAndLaunchProbes, self.GetNumChargesInProbeLauncher(), initialPosition=initialPosition) 464 465 def ScaleFormationSpread(self, scaling): 466 self.probeTracker.ScaleAllProbes(scaling, scaleScanRange=False) 467 468 def ScaleFormation(self, scaling): 469 probeData = self.probeTracker.GetProbeData() 470 for probeID, probe in probeData.iteritems(): 471 currentRange = probe.scanRange 472 newRange = currentRange * scaling 473 rangeSteps = self.probeTracker.GetScanRangeStepsByTypeID(probe.typeID) 474 if newRange not in rangeSteps: 475 return 476 477 self.probeTracker.ScaleAllProbes(scaling) 478 479 def GetProbeTracker(self): 480 return self.probeTracker 481 482 def SetProbesAsScanning(self, probes): 483 return self.probeTracker.SetProbesAsScanning(probes) 484 485 def ProbeControlSelect(self): 486 uicore.layer.systemmapBrackets.state = uiconst.UI_DISABLED 487 488 def ProbeControlDeselected(self): 489 uicore.layer.systemmapBrackets.state = uiconst.UI_PICKCHILDREN 490 491 def FocusOnProbe(self, probeID): 492 try: 493 probeID = int(probeID) 494 except ValueError: 495 uicore.layer.systemmap.FocusOnPoint(self.probeTracker.GetCenterOfActiveProbes()) 496 else: 497 uicore.layer.systemmap.FocusOnPoint(self.probeTracker.GetProbe(probeID).destination) 498 499 def GetFilterOptions(self): 500 return self.resultFilter.GetFilters() 501 502 def GetActiveFilterSet(self): 503 return self.resultFilter.GetActiveFilterSet() 504 505 def AddToActiveFilterSet(self, filterID): 506 self.resultFilter.AddToActiveFilterSet(filterID) 507 sm.ScatterEvent('OnSystemScanFilterChanged') 508 509 def RemoveFromActiveFilterSet(self, filterID): 510 self.resultFilter.RemoveFromActiveFilterSet(filterID) 511 sm.ScatterEvent('OnSystemScanFilterChanged') 512 513 def DeleteFilter(self, filterID): 514 self.resultFilter.DeleteFilter(filterID) 515 516 def GetResults(self, applyFiltering = True): 517 results, ignored, filtered, anomalies = self.scanHandlerBySystem[session.solarsystemid].GetResults(applyFiltering) 518 results = [ utillib.KeyVal(**r) for r in results ] 519 return (results, 520 ignored, 521 filtered, 522 anomalies) 523 524 def GetResultFilter(self, filterID): 525 return self.resultFilter.GetFilter(filterID) 526 527 def CreateResultFilter(self, name, groups): 528 self.resultFilter.CreateFilter(name, groups) 529 530 def EditResultFilter(self, filterID, name, groups): 531 self.resultFilter.EditFilter(filterID, name, groups) 532 533 def GetDisplayName(self, result): 534 displayName = '' 535 if result.typeID: 536 displayName = self.GetTypeName(result) 537 if not displayName and result.groupID: 538 displayName = self.GetGroupName(result) 539 if not displayName: 540 displayName = self.GetScanGroupName(result) 541 return displayName 542 543 def GetTypeName(self, result): 544 if IsExplorationSite(result): 545 if result.dungeonNameID is not None: 546 return localization.GetByMessageID(result.dungeonNameID) 547 return '' 548 if result.typeID is not None: 549 return evetypes.GetName(result.typeID) 550 return '' 551 552 def GetGroupName(self, result): 553 if IsExplorationSite(result): 554 if result.strengthAttributeID is None: 555 return '' 556 return self.GetExplorationSiteType(result.strengthAttributeID, result.archetypeID) 557 elif result.groupID is not None: 558 return evetypes.GetGroupNameByGroup(result.groupID) 559 else: 560 return '' 561 562 def GetExplorationSiteType(self, attributeID, archetypeID): 563 return get_exploration_site_group_name(site_type=attributeID, archetype_id=archetypeID) 564 565 def GetScanGroupName(self, result): 566 return localization.GetByLabel(NAME_BY_SCANGROUPID[result.scanGroupID]) 567 568 def RestoreProbesFromBackup(self): 569 self.probeTracker.RestoreProbesFromBackup() 570 571 def CenterProbesOnMe(self, formationID): 572 ballpark = sm.GetService('michelle').GetBallpark() 573 egoBall = ballpark.GetBall(ballpark.ego) 574 if not egoBall: 575 return 576 oldFormation = customFormations.GetSelectedFormationID() 577 probeInfo = self.probeTracker.GetProbePositionAndRangeInfo() 578 formationID = customFormations.PersistFormation('tempFormation', probeInfo.values(), formationID) 579 self.MoveProbesToFormation(formationID, initialPosition=(egoBall.x, egoBall.y, egoBall.z)) 580 customFormations.SelectFormation(oldFormation) 581 582 def StartMoveMode(self): 583 self.probeTracker.StartMoveMode() 584 585 def PurgeBackupData(self): 586 self.probeTracker.PurgeBackupData() 587 588 def GetResultForTargetID(self, targetID): 589 return self.scanHandlerBySystem[session.solarsystemid].resultsHistory.GetResultAsDict(targetID) 590 591 def GetIgnoreResultMenu(self, targetID, scanGroupID = None): 592 menu = [] 593 menu.append(None) 594 menu.append((MenuLabel('UI/Inflight/Scanner/IngoreResult'), self.IgnoreResult, (targetID,))) 595 menu.append((MenuLabel('UI/Inflight/Scanner/IgnoreOtherResults'), self.IgnoreOtherResults, (targetID,))) 596 return menu 597 598 def GetAccurateScannedDownMenu(self, scanResult): 599 menu = [] 600 if scanResult.IsAccurate(): 601 menu.extend(self.GetScannedDownMenu(scanResult)) 602 return menu 603 604 def GetScanResultMenuWithIgnore(self, scanResult, scanGroupId): 605 menu = [] 606 menu.extend(self.GetAccurateScannedDownMenu(scanResult)) 607 menu.extend(self.GetIgnoreResultMenu(scanResult.targetID, scanGroupId)) 608 return menu 609 610 def GetScanResultMenuWithoutIgnore(self, scanResult): 611 return self.GetAccurateScannedDownMenu(scanResult) 612 613 def GetScannedDownMenu(self, scanResult): 614 menu = [] 615 if self.michelle.IsPositionWithinWarpDistance(scanResult.position): 616 menu.extend(GetMenuService().SolarsystemScanMenu(scanResult.targetID)) 617 menu.append(None) 618 _scanResultNameID, scanResultName = scanResult.GetScanName() 619 menu.extend(self.GetAlignToMenu(scanResult.position)) 620 bookmarkData = utillib.KeyVal(id=scanResult.targetID, position=scanResult.position, name='%s %s' % (scanResult.targetID, scanResultName)) 621 menu.append((MenuLabel('UI/Inflight/BookmarkLocation'), sm.GetService('addressbook').BookmarkLocationPopup, (session.solarsystemid, 622 None, 623 None, 624 None, 625 bookmarkData))) 626 return menu 627 628 def GetAlignToMenu(self, position): 629 return [(MenuLabel('UI/Inflight/AlignTo'), self.AlignToPosition, (position,))] 630 631 def InjectSitesAsScanResults(self, sites, force = False): 632 if session.solarsystemid: 633 self.scanHandlerBySystem[session.solarsystemid].InjectResults(sites, force=force) 634 635 def ShowAnomalies(self): 636 self.resultFilter.ShowAnomalies() 637 sm.ScatterEvent('OnSystemScanFilterChanged') 638 639 def StopShowingAnomalies(self): 640 self.resultFilter.StopShowingAnomalies() 641 sm.ScatterEvent('OnSystemScanFilterChanged') 642 643 def ClickLink(self, action): 644 if action == 'ShowAnomalies': 645 self.ShowAnomalies() 646 elif action == 'HideAnomalies': 647 self.StopShowingAnomalies() 648 elif action == 'ClearIgnored': 649 self.scanHandlerBySystem[session.solarsystemid].ClearIgnoredResults() 650 else: 651 raise RuntimeError('scanSvc::ClickLink - Not supported action (%s)' % action) 652 wnd = Scanner.GetIfOpen() 653 if wnd is not None: 654 wnd.LoadFilterOptionsAndResults() 655 656 def IsShowingAnomalies(self): 657 return self.resultFilter.IsShowingAnomalies() 658 659 def PersistCurrentFormation(self, name): 660 probeInfo = self.probeTracker.GetProbePositionAndRangeInfo() 661 customFormations.PersistFormation(name, probeInfo.values()) 662 663 def SetSelectedSites(self, siteIDs): 664 self.selectedSites.clear() 665 for siteID in siteIDs: 666 self.selectedSites.add(siteID) 667 668 sm.ScatterEvent('OnSiteSelectionChanged') 669 670 def SelectSite(self, siteID): 671 multiSelect = uicore.uilib.Key(uiconst.VK_SHIFT) or uicore.uilib.Key(uiconst.VK_CONTROL) 672 if not multiSelect: 673 self.selectedSites.clear() 674 if siteID not in self.selectedSites: 675 self.selectedSites.add(siteID) 676 elif multiSelect: 677 self.selectedSites.remove(siteID) 678 sm.ScatterEvent('OnSiteSelectionChanged') 679 680 def DeselectSite(self, siteID): 681 if siteID in self.selectedSites: 682 self.selectedSites.remove(siteID) 683 sm.ScatterEvent('OnSiteSelectionChanged') 684 685 def IsSiteSelected(self, siteID): 686 return siteID in self.selectedSites 687 688 def GetActiveProbeTypeID(self): 689 typeID = self.probeTracker.GetProbeTypeID() 690 if typeID: 691 return typeID 692 charges = self.GetChargesInProbeLauncher() 693 if charges: 694 return charges.typeID 695 696 def QAScanSites(self, *siteIDs): 697 sites = self.GetScanMan().QAScanSites(siteIDs) 698 if sites: 699 self.scanHandlerBySystem[session.solarsystemid].InjectResults(sites, True)