bracketMgr.py (59519B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\bracketMgr.py 2 import math 3 import sys 4 import stackless 5 import blue 6 import collections 7 import evetypes 8 import fsd.schemas.binaryLoader as fsdBinaryLoader 9 import localization 10 import mining 11 import overviewPresets.overviewSettingsConst as osConst 12 import telemetry 13 import uthread 14 from caching.memoize import Memoize 15 from carbon.common.script.sys import service 16 from carbon.common.script.util import logUtil as log 17 from carbon.common.script.util.timerstuff import AutoTimer 18 from carbonui import uiconst 19 from carbonui.uicore import uicore 20 from carbonui.util import colorblind 21 from carbonui.util.various_unsorted import SortListOfTuples 22 from eve.client.script.parklife import states as state 23 from eve.client.script.parklife.bracketConst import SHOW_NONE, SHOW_DEFAULT, SHOW_ALL 24 from eve.client.script.parklife.bracketSettings import bracket_display_override_setting, bracket_showing_specials_setting 25 from eve.client.script.remote.michelle import GetMichelle 26 from eve.client.script.ui.control.eveLabel import EveLabelSmall 27 from eve.client.script.ui.inflight.bracketsAndTargets import bracketVarious 28 from eve.client.script.ui.inflight.bracketsAndTargets.phaseStabilizerBracket import PhaseStabilizerBracket 29 from eve.client.script.ui.inflight.bracketsAndTargets.asteroid_bracket import AsteroidBracket 30 from eve.client.script.ui.inflight.bracketsAndTargets.bracketNameFormatting import TagWithBold, TagWithColor, TagWithItalic, TagWithSize, TagWithUnderLine 31 from eve.client.script.ui.inflight.bracketsAndTargets.breach_point_asteroid_bracket import BreachPointAsteroidBracket 32 from eve.client.script.ui.inflight.bracketsAndTargets.haulerBracket import HaulerBracket 33 from eve.client.script.ui.inflight.bracketsAndTargets.inSpaceBracket import InSpaceBracket 34 from eve.client.script.ui.inflight.bracketsAndTargets.my_ship_bracket import MyShipBracket 35 from eve.client.script.ui.inflight.bracketsAndTargets.navigationBracket import NavigationBracket 36 from eve.client.script.ui.inflight.bracketsAndTargets.siphonBracket import SiphonSiloBracket 37 from eve.client.script.ui.inflight.bracketsAndTargets.skyhookBracket import SkyhookBracket 38 from eve.client.script.ui.inflight.bracketsAndTargets.structureBracket import StructureBracket 39 from eve.client.script.ui.inflight.bracketsAndTargets.targetInBar import TargetInBar 40 from eve.client.script.ui.inflight.bracketsAndTargets.timedBracket import TimedBracket 41 from eve.client.script.ui.inflight.overview import overviewConst 42 from eve.client.script.ui.inflight.squadrons.shipFighterState import GetShipFighterState 43 from eve.client.script.ui.util import uix 44 from eve.common.lib import appConst 45 from eve.common.script.sys import idCheckers 46 from eve.common.script.sys.idCheckers import IsSkyhook 47 from eveInflight.componentBracketController import ComponentBracketController 48 from eveprefs import prefs 49 from spacecomponents.client.messages import MSG_ON_BRACKET_CREATED 50 from spacecomponents.common import componentConst 51 from spacecomponents.common.data import type_has_space_component 52 from stargate.client.gate_signals import on_lock_removed 53 from uthread2 import call_after_simtime_delay 54 RED = (0.8, 0, 0, 1.0) 55 ORANGE = (0.75, 0.4, 0, 1.0) 56 YELLOW = (1.0, 1.0, 0, 0.3) 57 RECORDED_DAMAGE_PERIOD_SECONDS = 120 58 NUMBER_OF_DAMAGEDEALERS = 5 59 INF = 1e+32 60 BRACKET_CATEGORIES_WITH_RANGE_MARKER = (appConst.categoryShip, 61 appConst.categoryEntity, 62 appConst.categoryDrone, 63 appConst.categoryFighter) 64 ONLY_VISIBLE_WHEN_SELECTED_GROUPS = (appConst.groupHarvestableCloud,) 65 ONLY_VISIBLE_WHEN_SELECTED_CATEGORIES = [] 66 DEBUG_BRACKET = 0 67 68 def GetBracketMgr(): 69 return sm.GetService('bracket') 70 71 72 class BracketMgr(service.Service): 73 __guid__ = 'svc.bracket' 74 __update_on_reload__ = 0 75 __exportedcalls__ = {'GetBracketName': [], 76 'GetBracketName2': [], 77 'ResetOverlaps': [], 78 'CheckOverlaps': [], 79 'CleanUp': [], 80 'ClearBracket': [], 81 'GetBracketProps': [], 82 'Reload': [], 83 'GetScanSpeed': [], 84 'GetCaptureData': []} 85 __notifyevents__ = ['DoBallsAdded', 86 'DoBallRemove', 87 'DoBallClear', 88 'ProcessSessionChange', 89 'OnFleetStateChange', 90 'OnStateChange', 91 'OnDestinationSet', 92 'OnPostCfgDataChanged', 93 'OnBallparkCall', 94 'OnSlimItemChange', 95 'OnAttribute', 96 'OnAttributes', 97 'OnCaptureChanged', 98 'ProcessBountyInfoUpdated', 99 'OnUIScalingChange', 100 'OnFleetJoin_Local', 101 'OnFleetLeave_Local', 102 'OnDamageMessage', 103 'OnDamageMessages', 104 'DoBallsRemove', 105 'OnStructureVisibilityUpdated', 106 'OnHaulerQuantityChangedInClient', 107 'OnRefreshWhenDockingRequestDenied', 108 'OnStructureAccessUpdated', 109 'OnDockingAccessChangedForCurrentSolarSystem_Local', 110 'OnStateSetupChange', 111 'OnMyFleetInited', 112 'OnClientEvent_WarpStarted', 113 'OnClientEvent_WarpFinished', 114 'OnOverviewOverrideChanged', 115 'OnBracketIconUpdated', 116 'OnEmanationLockUpdated'] 117 __startupdependencies__ = ['wreck', 'overviewPresetSvc'] 118 __dependencies__ = ['michelle', 119 'tactical', 120 'map', 121 'settings', 122 'target', 123 'fighters', 124 'stateSvc'] 125 126 def __init__(self): 127 super(BracketMgr, self).__init__() 128 self.specials = (appConst.groupLargeCollidableStructure, appConst.groupMoon) 129 self.renewingBracketFlags = False 130 self.pendingBracketRenewal = False 131 self.filterLCS = ['wall_x', 132 'wall_z', 133 ' wall', 134 ' barricade', 135 ' fence', 136 ' barrier', 137 ' junction', 138 ' elevator', 139 ' lookout', 140 ' neon sign'] 141 self.showState = SHOW_DEFAULT 142 self.showingSpecials = False 143 self.componentBracketController = ComponentBracketController() 144 bracket_display_override_setting.on_change.connect(self.OnBracketDisplaySettingChanged) 145 bracket_showing_specials_setting.on_change.connect(self.OnBracketDisplaySettingChanged) 146 on_lock_removed.connect(self.OnEmanationGateLockRemoved) 147 colorblind.on_colorblind_mode_changed.connect(self.OnColorBlindModeChanged) 148 149 def OnBracketDisplaySettingChanged(self, *args): 150 self.SoftReload() 151 152 def Run(self, memStream = None): 153 service.Service.Run(self, memStream) 154 self.scenarioMgr = sm.StartService('scenario') 155 self.shipFighterState = GetShipFighterState() 156 self.shipFighterState.signalOnFighterInSpaceUpdate.connect(self.OnFighterInSpaceUpdate) 157 self.Reload() 158 self.CreateBracketIndexes() 159 160 def CreateBracketIndexes(self): 161 self.bracketDataByCategoryID = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/bracketsByCategory.static', optimize=False) 162 self.bracketDataByGroupID = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/bracketsByGroup.static', optimize=False) 163 self.bracketDataByTypeID = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/bracketsByType.static', optimize=False) 164 self.bracketsData = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/brackets.static', optimize=False) 165 166 def GetBrackeDatatByID(self, bracketID): 167 return self.bracketsData.get(bracketID, None) 168 169 def GetBracketDataByTypeID(self, typeID): 170 try: 171 bracketID = self.bracketDataByTypeID[typeID] 172 except KeyError: 173 try: 174 bracketID = self.bracketDataByGroupID[evetypes.GetGroupID(typeID)] 175 except KeyError: 176 try: 177 bracketID = self.bracketDataByCategoryID[evetypes.GetCategoryID(typeID)] 178 except KeyError: 179 return None 180 181 return self.GetBrackeDatatByID(bracketID) 182 183 def GetBracketDataByGroupID(self, groupID): 184 if groupID in self.bracketDataByGroupID: 185 bracketID = self.bracketDataByGroupID[groupID] 186 return self.GetBrackeDatatByID(bracketID) 187 categoryID = evetypes.GetCategoryIDByGroup(groupID) 188 if categoryID in self.bracketDataByCategoryID: 189 bracketID = self.bracketDataByCategoryID[categoryID] 190 return self.GetBrackeDatatByID(bracketID) 191 192 def GetBracketIcon(self, typeID, isEmpty = None, itemID = None): 193 bracket = self.GetBracketDataByTypeID(typeID) 194 return self._GetBracketIcon(bracket, isEmpty, typeID, itemID) 195 196 def _GetBracketIcon(self, bracket, isEmpty, typeID = None, itemID = None): 197 if bracket: 198 componentBracketIcon = self.componentBracketController.GetBracketIcon(bracket, self.michelle.GetBallpark(), typeID, itemID) 199 if componentBracketIcon: 200 return componentBracketIcon 201 elif isEmpty and hasattr(bracket, 'texturePathEmpty'): 202 return bracket.texturePathEmpty 203 else: 204 return bracket.texturePath 205 206 def GetBracketIconByGroupID(self, groupID, isEmpty = None): 207 bracket = self.GetBracketDataByGroupID(groupID) 208 return self._GetBracketIcon(bracket, isEmpty) 209 210 def Stop(self, stream): 211 self.CleanUp() 212 213 def CleanUp(self): 214 self.brackets = {} 215 self.updateBrackets = {} 216 self.damageByBracketID = {} 217 self.biggestDamageDealers = [] 218 self.shipLabels = None 219 self.overlaps = [] 220 self.overlapsHidden = [] 221 self.checkingOverlaps = 0 222 self.showHiddenTimer = None 223 self.hairlinesTimer = None 224 self.shipLabels = None 225 self.inTargetRangeTimer = None 226 self.damageDealerTimer = None 227 uicore.layer.bracket.Flush() 228 self.fleetBracketColor = (0.6, 0.15, 0.9, 0.5) 229 230 def Hide(self): 231 l_bracket = uicore.layer.bracket 232 if l_bracket: 233 l_bracket.state = uiconst.UI_HIDDEN 234 235 def Show(self): 236 l_bracket = uicore.layer.bracket 237 if l_bracket: 238 l_bracket.state = uiconst.UI_PICKCHILDREN 239 240 @telemetry.ZONE_METHOD 241 def Reload(self, *args, **kwds): 242 self.CleanUp() 243 overviewPresetSvc = sm.GetService('overviewPresetSvc') 244 showInTargetRange = overviewPresetSvc.GetSettingValueOrDefaultFromName(osConst.SETTING_TARGET_RANGE, True) 245 if showInTargetRange: 246 self.inTargetRangeTimer = AutoTimer(1000, self.ShowInTargetRange) 247 showBiggestDamageDealers = overviewPresetSvc.GetSettingValueOrDefaultFromName(osConst.SETTING_BIGGEST_DMG_DEALER, True) 248 if showBiggestDamageDealers: 249 self.damageDealerTimer = AutoTimer(1000, self.ShowBiggestDamageDealers_thread) 250 uthread.new(self.SoftReload) 251 self.UpdateFleetColor() 252 253 @telemetry.ZONE_METHOD 254 def SoftReload(self, showSpecials = None, bracketShowState = None): 255 if bracketShowState is not None: 256 self.showState = bracketShowState 257 if showSpecials is not None: 258 self.showingSpecials = showSpecials 259 ballPark = sm.GetService('michelle').GetBallpark(doWait=True) 260 if not ballPark: 261 return 262 for slimItem in ballPark.slimItems.itervalues(): 263 self.AddBracketIfWanted(slimItem) 264 265 def ShowOwnShip(self): 266 if not self.showHiddenTimer: 267 myShipBracket = self.brackets.get(session.shipid, None) 268 if myShipBracket: 269 myShipBracket.ShowOwnShip() 270 self.showHiddenTimer = AutoTimer(100, self.StopShowingHidden) 271 272 def StopShowingHidden(self): 273 alt = uicore.uilib.Key(uiconst.VK_MENU) 274 if not alt: 275 self.showHiddenTimer = None 276 bracket = self.brackets.get(session.shipid, None) 277 if bracket: 278 bracket.SetNormalInvisibleStateForOwnShip() 279 280 def IsShowingAll(self): 281 return bracket_display_override_setting.is_equal(SHOW_ALL) 282 283 def IsHidingAll(self): 284 return bracket_display_override_setting.is_equal(SHOW_NONE) 285 286 def IsShowingSpecials(self): 287 return bracket_showing_specials_setting.is_enabled() 288 289 @telemetry.ZONE_METHOD 290 def IsWanted(self, ballID, typeID = None, groupID = None, categoryID = None, slimItem = None, filtered = None): 291 if typeID and not self.GetBracketDataByTypeID(typeID): 292 return False 293 else: 294 if typeID is None or groupID is None or categoryID is None: 295 slimItem = slimItem or sm.GetService('michelle').GetBallpark().GetInvItem(ballID) 296 if slimItem is None: 297 log.LogWarn('IsWanted - ball', ballID, 'not found in park') 298 return False 299 typeID = slimItem.typeID 300 groupID = slimItem.groupID 301 categoryID = slimItem.categoryID 302 if groupID == appConst.groupDeadspaceOverseersStructure: 303 checkName = evetypes.GetName(typeID).lower() 304 if checkName in self.filterLCS: 305 return False 306 if categoryID == appConst.categoryStructure: 307 if not sm.GetService('structureProximityTracker').IsStructureVisible(ballID): 308 return False 309 if groupID in ONLY_VISIBLE_WHEN_SELECTED_GROUPS or categoryID in ONLY_VISIBLE_WHEN_SELECTED_CATEGORIES: 310 return self.IsSelectedOrTargeted(ballID) 311 isSpecial = groupID in self.specials 312 if isSpecial: 313 if self.IsShowingSpecials(): 314 return True 315 return self.IsSelectedOrTargeted(ballID) 316 if self.IsShowingAll(): 317 return True 318 isSelectedOrTargeted = self.IsSelectedOrTargeted(ballID) 319 if self.IsHidingAll(): 320 return isSelectedOrTargeted 321 if isSelectedOrTargeted: 322 return True 323 slimItem = slimItem or sm.GetService('michelle').GetBallpark().GetInvItem(ballID) 324 filtered = filtered or sm.GetService('tactical').GetFilteredStatesFunctionNames(isBracket=True) 325 alwaysShown = sm.GetService('tactical').GetAlwaysShownStatesFunctionNames() 326 return sm.GetService('tactical').WantIt(slimItem, filtered, alwaysShown, isBracket=True) 327 328 @telemetry.ZONE_METHOD 329 def IsSelectedOrTargeted(self, ballID): 330 for isWanted in self.stateSvc.GetStates(ballID, [state.selected, 331 state.targeted, 332 state.targeting, 333 state.activeTarget]): 334 if isWanted: 335 return True 336 337 return sm.GetService('target').IsTarget(ballID) 338 339 def GetBracketName(self, objectID): 340 if objectID in self.brackets: 341 return self.brackets[objectID].displayName 342 return '' 343 344 def GetBracket(self, objectID): 345 return self.brackets.get(objectID, None) 346 347 def GetBracketName2(self, objectID): 348 if not objectID: 349 return '' 350 ret = self.GetBracketName(objectID) 351 if ret != '': 352 ret = ret.replace('<br>', ' ') 353 return ret 354 ballpark = sm.GetService('michelle').GetBallpark() 355 if not ballpark: 356 return '' 357 slimItem = ballpark.slimItems.get(objectID, None) 358 if slimItem is None: 359 return '' 360 ret = self.GetDisplayNameForBracket(slimItem) 361 if ret: 362 ret = ret.replace('<br>', ' ') 363 return ret 364 365 def GetDisplayNameWithShipLabels(self, slimItem, displayName): 366 shipLabelList = [] 367 if not self.shipLabels: 368 self.shipLabels = self.stateSvc.GetShipLabels() 369 self.hideCorpTicker = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_HIDE_CORP_TICKER, True) 370 for label in self.shipLabels: 371 isVisible = label[overviewConst.LABEL_STATE] 372 labelType = label[overviewConst.LABEL_TYPE] 373 if labelType != overviewConst.LABEL_TYPE_LINEBREAK and not isVisible: 374 continue 375 pre = label[overviewConst.PRE] 376 post = label[overviewConst.POST] 377 labelText = None 378 if labelType is overviewConst.LABEL_TYPE_NONE: 379 if slimItem.corpID and not idCheckers.IsNPC(slimItem.corpID): 380 shipLabelList.append(pre) 381 elif labelType == overviewConst.LABEL_TYPE_LINEBREAK: 382 if shipLabelList and shipLabelList[-1] != overviewConst.CHAR_BR: 383 shipLabelList.append(overviewConst.CHAR_BR) 384 elif labelType == overviewConst.LABEL_TYPE_CORP: 385 if slimItem.corpID and not idCheckers.IsNPC(slimItem.corpID) and not (self.hideCorpTicker and slimItem.allianceID): 386 labelText = cfg.corptickernames.Get(slimItem.corpID).tickerName 387 elif labelType == overviewConst.LABEL_TYPE_ALLIANCE: 388 if slimItem.allianceID: 389 try: 390 labelText = cfg.allianceshortnames.Get(slimItem.allianceID).shortName 391 except: 392 log.LogError('Failed to get allianceName, itemID:', slimItem.itemID, 'allianceID:', slimItem.allianceID) 393 394 elif labelType == overviewConst.LABEL_TYPE_PILOT: 395 labelText = displayName 396 elif labelType == overviewConst.LABEL_TYPE_SHIP_TYPE: 397 labelText = evetypes.GetName(slimItem.typeID) 398 elif labelType == overviewConst.LABEL_TYPE_SHIP_NAME: 399 labelText = cfg.evelocations.Get(slimItem.itemID).name 400 if labelText: 401 labelsForType = [labelText] 402 isBold = label.get(overviewConst.LABEL_BOLD, False) 403 isUnderlined = label.get(overviewConst.LABEL_UNDERLINE, False) 404 isItalic = label.get(overviewConst.LABEL_ITALIC, False) 405 labelsForType = TagWithBold(labelsForType, isBold) 406 labelsForType = TagWithUnderLine(labelsForType, isUnderlined) 407 labelsForType = TagWithItalic(labelsForType, isItalic) 408 labelsForType.insert(0, pre) 409 labelsForType.append(post) 410 color = label.get(overviewConst.LABEL_COLOR, None) 411 fontsize = label.get(overviewConst.LABEL_SIZE) 412 labelsForType = TagWithColor(labelsForType, color) 413 labelsForType = TagWithSize(labelsForType, fontsize) 414 shipLabelList += labelsForType 415 416 return ''.join(shipLabelList) 417 418 def OnSlimItemChange(self, oldSlim, newSlim): 419 bracket = self.GetBracket(newSlim.itemID) 420 if not bracket: 421 return 422 if hasattr(bracket, 'OnSlimItemChange'): 423 bracket.OnSlimItemChange(oldSlim, newSlim) 424 bracket.slimItem = newSlim 425 bracket.displayName = None 426 if idCheckers.IsStarbase(newSlim.categoryID): 427 if newSlim.posState == oldSlim.posState and newSlim.posTimestamp == oldSlim.posTimestamp and newSlim.incapacitated == oldSlim.incapacitated and newSlim.controllerID == oldSlim.controllerID and newSlim.ownerID == oldSlim.ownerID: 428 return 429 bracket.UpdateStructureState(newSlim) 430 elif idCheckers.IsOrbital(newSlim.categoryID): 431 if newSlim.orbitalState == oldSlim.orbitalState and newSlim.orbitalTimestamp == oldSlim.orbitalTimestamp and newSlim.ownerID == oldSlim.ownerID and newSlim.orbitalHackerID == oldSlim.orbitalHackerID and newSlim.orbitalHackerProgress == oldSlim.orbitalHackerProgress: 432 return 433 bracket.UpdateOrbitalState(newSlim) 434 if newSlim.corpID != oldSlim.corpID: 435 uthread.pool('BracketMgr::OnSlimItemChange --> UpdateStates', bracket.UpdateFlagAndBackground, newSlim) 436 if newSlim.groupID in appConst.environmentContainers: 437 if newSlim.groupID == appConst.groupWreck and newSlim.isEmpty and not oldSlim.isEmpty: 438 self.stateSvc.SetState(newSlim.itemID, state.flagWreckEmpty, True) 439 bracket.Load_update(newSlim) 440 self.UpdateCaptureFromSlim(newSlim) 441 442 def UpdateCaptureFromSlim(self, slimItem): 443 if getattr(slimItem, 'capturePoint', None): 444 if not hasattr(self, 'capturePoints'): 445 self.capturePoints = {} 446 slimItem.capturePoint['lastIncident'] = blue.os.GetSimTime() 447 self.capturePoints[slimItem.itemID] = slimItem.capturePoint 448 bracket = self.GetBracket(slimItem.itemID) 449 if bracket: 450 bracket.UpdateCaptureProgress(slimItem.capturePoint) 451 452 def ProcessSessionChange(self, isremote, session, change): 453 if not sm.GetService('connection').IsConnected() or session.stationid is not None or session.charid is None: 454 self.CleanUp() 455 elif 'solarsystemid' not in change and 'shipid' in change and change['shipid'][0] is not None: 456 oldShipID, shipID = change['shipid'] 457 slimItem = sm.GetService('michelle').GetItem(oldShipID) 458 if slimItem is not None: 459 self._RecreateBracket(slimItem) 460 slimItem = sm.GetService('michelle').GetItem(shipID) 461 if slimItem is not None: 462 self._RecreateBracket(slimItem) 463 464 def RecreateBracket(self, itemID): 465 slimItem = sm.GetService('michelle').GetItem(itemID) 466 if slimItem: 467 self._RecreateBracket(slimItem) 468 469 def _RecreateBracket(self, slimItem): 470 self.RemoveBracket(slimItem.itemID) 471 self.AddBracketIfWanted(slimItem) 472 473 def GetBracketProps(self, slimItem, ball = None): 474 bracketData = self.GetBracketDataByTypeID(slimItem.typeID) 475 texturePath = self._GetBracketIcon(bracketData, getattr(slimItem, 'isEmpty', False), slimItem.typeID, slimItem.itemID) 476 minVisibleDistance = getattr(bracketData, 'minVisibleDistance', 0.0) 477 maxVisibleDistance = getattr(bracketData, 'maxVisibleDistance', INF) 478 iconOffset = getattr(bracketData, 'iconOffset', 0) 479 return (texturePath, 480 1, 481 minVisibleDistance, 482 maxVisibleDistance, 483 iconOffset, 484 0) 485 486 def PrimeLocations(self, slimItem): 487 locations = [] 488 for each in slimItem.jumps: 489 if each.locationID not in locations: 490 locations.append(each.locationID) 491 if each.toCelestialID not in locations: 492 locations.append(each.toCelestialID) 493 494 if len(locations): 495 cfg.evelocations.Prime(locations) 496 497 def DoBallsAdded(self, balls_slimItems, *args, **kw): 498 t = stackless.getcurrent() 499 timer = t.PushTimer(blue.pyos.taskletTimer.GetCurrent() + '::BracketMgr') 500 try: 501 uthread.new(self._AddBrackets, balls_slimItems).context = blue.pyos.taskletTimer.GetCurrent() + '::_AddBrackets' 502 finally: 503 t.PopTimer(timer) 504 505 @telemetry.ZONE_METHOD 506 def _AddBrackets(self, balls_slimItems): 507 for ball, slimItem in balls_slimItems: 508 self.AddBracketIfWanted(slimItem, ball) 509 510 @telemetry.ZONE_METHOD 511 def RemoveBracket(self, itemID): 512 if itemID in self.brackets: 513 self.LogInfo('DoBallRemove::bracketMgr removing item', itemID) 514 bracket = self.brackets[itemID] 515 if bracket is not None and not bracket.destroyed: 516 bracket.Close() 517 del self.brackets[itemID] 518 if itemID in self.updateBrackets: 519 del self.updateBrackets[itemID] 520 521 @telemetry.ZONE_METHOD 522 def AddBracketIfWanted(self, slimItem, ball = None): 523 try: 524 itemID = slimItem.itemID 525 groupID = slimItem.groupID 526 categoryID = slimItem.categoryID 527 typeID = slimItem.typeID 528 if not self.IsWanted(itemID, typeID=typeID, groupID=groupID, categoryID=categoryID, slimItem=slimItem): 529 bracket = self.brackets.get(itemID, None) 530 if bracket: 531 bracket.Hide() 532 return 533 bracket = self.brackets.get(itemID, None) 534 if bracket: 535 if not bracket.display: 536 bracket.Show() 537 return 538 ball = ball or sm.GetService('michelle').GetBall(itemID) 539 if not ball: 540 return 541 bracket_cls = self.GetBracketClass(categoryID, groupID, slimItem.typeID, itemID) 542 is_update_item = self.stateSvc.CheckIfUpdateItem(slimItem) and itemID != session.shipid 543 bracket_ui = bracket_cls(parent=uicore.layer.bracket, name='__inflightbracket_%s' % itemID, align=uiconst.NOALIGN, state=uiconst.UI_NORMAL, ball=ball, slimItem=slimItem, is_update_item=is_update_item) 544 if itemID in self.brackets: 545 bracket_ui.Close() 546 return 547 self.brackets[itemID] = bracket_ui 548 if is_update_item: 549 self.updateBrackets[itemID] = bracket_ui 550 bracket_ui.Load_update(slimItem) 551 if categoryID == appConst.categoryFighter and slimItem.ownerID == session.charid: 552 self.UpdateSquadronNumber(itemID, bracket_ui) 553 if hasattr(self, 'capturePoints') and itemID in self.capturePoints.keys(): 554 bracket_ui.UpdateCaptureProgress(self.capturePoints[itemID]) 555 else: 556 self.UpdateCaptureFromSlim(slimItem) 557 if idCheckers.IsOrbital(categoryID): 558 bracket_ui.UpdateOrbitalState(slimItem) 559 self.michelle.GetBallpark().componentRegistry.SendMessageToItem(itemID, MSG_ON_BRACKET_CREATED, bracket_ui, slimItem) 560 except AttributeError as e: 561 log.LogException(e) 562 sys.exc_clear() 563 564 def OnFighterInSpaceUpdate(self, fighterID, tubeFlagID): 565 try: 566 fighterBracket = self.brackets[fighterID] 567 except KeyError: 568 pass 569 else: 570 fighterInSpace = self.shipFighterState.GetFighterInSpaceByID(fighterID) 571 if fighterInSpace: 572 fighterBracket.UpdateSquadronNumber(fighterInSpace.tubeFlagID) 573 else: 574 self.RecreateBracket(fighterID) 575 576 def UpdateSquadronNumber(self, fighterID, fighterBracket): 577 fighterInSpace = self.shipFighterState.GetFighterInSpaceByID(fighterID) 578 if fighterInSpace is None: 579 tubeFlagID = None 580 else: 581 tubeFlagID = fighterInSpace.tubeFlagID 582 fighterBracket.UpdateSquadronNumber(tubeFlagID) 583 584 def GetBracketClass(self, categoryID, groupID, typeID, itemID): 585 if categoryID == appConst.categoryStructure: 586 return StructureBracket 587 else: 588 if mining.is_harvestable(typeID): 589 if type_has_space_component(typeID, componentConst.BREACH_POINT_ASTEROID): 590 return BreachPointAsteroidBracket 591 else: 592 return AsteroidBracket 593 else: 594 if typeID == appConst.typeMobileShippingUnit: 595 return TimedBracket 596 if groupID == appConst.groupSiphonPseudoSilo: 597 return SiphonSiloBracket 598 if groupID == appConst.groupNpcIndustrialCommand: 599 return HaulerBracket 600 if itemID == session.shipid: 601 return MyShipBracket 602 if self.IsMyFighterInSpace(categoryID, itemID): 603 return NavigationBracket 604 if IsSkyhook(typeID): 605 return SkyhookBracket 606 if groupID == appConst.groupMobilePhaseAnchor: 607 return PhaseStabilizerBracket 608 return InSpaceBracket 609 610 def IsMyFighterInSpace(self, categoryID, itemID): 611 return categoryID == appConst.categoryFighter and sm.GetService('fighters').shipFighterState.IsMyFighterInSpace(itemID) 612 613 @telemetry.ZONE_METHOD 614 def GetDisplayNameForBracket(self, slimItem): 615 try: 616 displayName = uix.GetSlimItemName(slimItem) 617 except Exception as e: 618 if slimItem: 619 self.LogException('Couldnt generate name for bracket, slimItem is not None') 620 else: 621 self.LogException('Couldnt generate name for bracket, slimItem is None') 622 return 623 624 groupID = slimItem.groupID 625 categoryID = slimItem.categoryID 626 if groupID == appConst.groupStation: 627 displayName = uix.EditStationName(displayName, usename=1) 628 elif groupID == appConst.groupStargate: 629 uthread.new(self.PrimeLocations, slimItem) 630 elif groupID == appConst.groupHarvestableCloud: 631 displayName = localization.GetByLabel('UI/Generic/HarvestableCloud', item=slimItem.typeID) 632 if not idCheckers.IsOrbital(categoryID) and getattr(slimItem, 'corpID', None): 633 displayName = self.GetDisplayNameWithShipLabels(slimItem, displayName) 634 return displayName 635 636 @telemetry.ZONE_METHOD 637 def UpdateLabels(self): 638 self.shipLabels = self.stateSvc.GetShipLabels() 639 self.hideCorpTicker = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_HIDE_CORP_TICKER, True) 640 for bracket in self.brackets: 641 slimItem = self.brackets[bracket].slimItem 642 if not slimItem: 643 continue 644 if slimItem.corpID: 645 self.brackets[slimItem.itemID].displayName = self.GetDisplayNameForBracket(slimItem) 646 647 @telemetry.ZONE_METHOD 648 def RenewFlags(self): 649 if self.renewingBracketFlags: 650 self.pendingBracketRenewal = True 651 return 652 self.renewingBracketFlags = True 653 self.pendingBracketRenewal = False 654 uthread.pool('BracketMgr::RenewFlags', self._RenewAllFlags) 655 656 def _RenewAllFlags(self): 657 try: 658 self._DoRenewAllFlags() 659 finally: 660 self.renewingBracketFlags = False 661 662 if self.pendingBracketRenewal: 663 self.RenewFlags() 664 665 def _DoRenewAllFlags(self): 666 for bracket in self.brackets.values(): 667 if not self._ShouldRenewBracket(bracket): 668 continue 669 bracket.Load_update(bracket.slimItem) 670 blue.pyos.BeNice() 671 672 def _ShouldRenewBracket(self, bracket): 673 if bracket.destroyed: 674 return False 675 if bracket.itemID not in self.updateBrackets: 676 if bracket.slimItem is None or bracket.slimItem.groupID not in appConst.containerGroupIDs: 677 return False 678 return True 679 680 def RenewFlagForItemIDs(self, itemIDs): 681 uthread.new(self._RenewFlagForItemIDs, itemIDs) 682 683 def _RenewFlagForItemIDs(self, itemIDs): 684 for eachItemID in itemIDs: 685 bracket = self.GetBracket(eachItemID) 686 if bracket is None: 687 continue 688 if not self._ShouldRenewBracket(bracket): 689 continue 690 bracket.Load_update(bracket.slimItem) 691 blue.pyos.BeNice() 692 693 def RenewSingleFlagForCharID(self, charID): 694 uthread.new(self._RenewSingleFlag, charID) 695 696 def _RenewSingleFlag(self, charID): 697 bp = sm.GetService('michelle').GetBallpark() 698 if not bp: 699 return 700 for bracket in self.brackets.itervalues(): 701 slimItem = bracket.slimItem 702 if slimItem is None: 703 continue 704 if bracket.itemID not in self.updateBrackets: 705 if slimItem.groupID not in appConst.containerGroupIDs: 706 continue 707 if getattr(slimItem, 'ownerID', None) == charID: 708 bracket.Load_update(slimItem) 709 elif getattr(slimItem, 'charID', None) == charID: 710 bracket.Load_update(slimItem) 711 blue.pyos.BeNice() 712 713 def OnBallparkCall(self, funcName, args): 714 if funcName == 'SetBallFree': 715 itemID, isFree = args 716 bracket = self.GetBracket(itemID) 717 if bracket and bracket.slimItem: 718 bracket.SetBracketAnchoredState(bracket.slimItem) 719 720 def OnClientEvent_WarpStarted(self, *args): 721 for itemID, bracket in self.brackets.iteritems(): 722 if isinstance(bracket, StructureBracket) and bracket.slimItem.timer is not None: 723 bracket.Update() 724 call_after_simtime_delay(bracket.Update, 10) 725 726 def OnClientEvent_WarpFinished(self, *args): 727 for itemID, bracket in self.brackets.iteritems(): 728 if isinstance(bracket, StructureBracket) and bracket.slimItem.timer is not None: 729 bracket.Update() 730 731 def OnOverviewOverrideChanged(self): 732 self.SoftReload() 733 734 def OnBracketIconUpdated(self, itemID): 735 bracket = self.brackets.get(itemID, None) 736 if bracket and hasattr(bracket, 'UpdateIcon'): 737 bracket.UpdateIcon() 738 739 @telemetry.ZONE_METHOD 740 def DoBallsRemove(self, pythonBalls, isRelease): 741 if isRelease: 742 for itemID, bracket in self.brackets.iteritems(): 743 if bracket is not None and not bracket.destroyed: 744 bracket.Close() 745 746 self.capturePoints = {} 747 self.brackets = {} 748 self.updateBrackets = {} 749 return 750 for ball, slimItem, terminal in pythonBalls: 751 self.DoBallRemove(ball, slimItem, terminal) 752 753 def DoBallRemove(self, ball, slimItem, terminal): 754 if ball is None: 755 return 756 self.RemoveBracket(ball.id) 757 if ball.id in getattr(self, 'capturePoints', {}): 758 del self.capturePoints[ball.id] 759 760 def DoBallClear(self, solitem): 761 self.brackets = {} 762 self.updateBrackets = {} 763 for bracket in uicore.layer.bracket.children: 764 bracket.Close() 765 766 def OnUIScalingChange(self, *args): 767 self.Reload() 768 769 def OnColorBlindModeChanged(self): 770 self.Reload() 771 772 def OnDestinationSet(self, destinationID = None): 773 focusOn = [] 774 updateGroups = (appConst.groupStation, appConst.groupStargate) 775 updateCategories = (appConst.categoryStructure,) 776 for each in uicore.layer.bracket.children: 777 if not getattr(each, 'IsBracket', 0) or each.destroyed: 778 continue 779 if not each.slimItem or each.slimItem.groupID not in updateGroups and each.slimItem.categoryID not in updateCategories: 780 continue 781 each.UpdateIconColor(each.slimItem) 782 if each.sr.icon and each.sr.icon.GetRGB() != overviewConst.OVERVIEW_NORMAL_COLOR: 783 focusOn.append(each) 784 785 for each in focusOn: 786 each.SetOrder(0) 787 788 def OnFleetStateChange(self, fleetState): 789 if fleetState: 790 for itemID, tag in fleetState.targetTags.iteritems(): 791 bracket = self.GetBracket(itemID) 792 if not bracket: 793 continue 794 if bracket.slimItem: 795 bracket.Load_update(bracket.slimItem) 796 797 def OnFleetJoin_Local(self, member, *args): 798 self.UpdateWrecksAndContainers(member) 799 800 def OnFleetLeave_Local(self, member, *args): 801 self.UpdateWrecksAndContainers(member) 802 803 def UpdateWrecksAndContainers(self, member): 804 if member.charID == session.charid: 805 for bracket in self.brackets.values(): 806 if bracket.slimItem and bracket.slimItem.groupID in (appConst.groupWreck, appConst.groupCargoContainer): 807 bracket.Load_update(bracket.slimItem) 808 809 def OnStateChange(self, itemID, flag, flagState, *args): 810 if flag in (state.selected, state.targeted, state.targeting): 811 slimItem = uix.GetBallparkRecord(itemID) 812 if not slimItem: 813 return 814 IsWanted = self.IsWanted(slimItem.itemID, slimItem=slimItem) 815 if flagState: 816 self.AddBracketIfWanted(slimItem) 817 elif not IsWanted: 818 self.RemoveBracket(slimItem.itemID) 819 return 820 bracket = self.GetBracket(itemID) 821 if bracket: 822 try: 823 bracket.OnStateChange(itemID, flag, flagState, *args) 824 except AttributeError: 825 if DEBUG_BRACKET: 826 log.LogException('failure to update bracket') 827 828 def OnStructureVisibilityUpdated(self, structureID): 829 self.RecreateBracket(structureID) 830 831 def OnHaulerQuantityChangedInClient(self, haulerID, qty, totalQty, ownerID, typeID): 832 if haulerID in self.brackets: 833 self.brackets[haulerID].UpdateQuantity(totalQty) 834 835 def OnRefreshWhenDockingRequestDenied(self, structureID): 836 bracket = self.GetBracket(structureID) 837 if bracket and getattr(bracket, 'slimItem', None): 838 bracket.UpdateFlagAndBackground(bracket.slimItem) 839 840 def OnStructureAccessUpdated(self): 841 self._RefreshStructureBracketIcons() 842 843 def OnDockingAccessChangedForCurrentSolarSystem_Local(self): 844 self._RefreshStructureBracketIcons() 845 846 def _RefreshStructureBracketIcons(self): 847 for eachBracket in self.brackets.itervalues(): 848 if getattr(eachBracket, 'slimItem', None) and eachBracket.slimItem.categoryID == appConst.categoryStructure: 849 eachBracket.UpdateFlagAndBackground(eachBracket.slimItem) 850 851 def OnAttribute(self, attributeName, item, newValue): 852 if item.itemID == session.shipid and attributeName == 'scanResolution': 853 for targetID in sm.GetService('target').GetTargeting(): 854 bracket = self.GetBracket(targetID) 855 if bracket and hasattr(bracket, 'OnAttribute'): 856 bracket.OnAttribute(attributeName, item, newValue) 857 858 def OnAttributes(self, changeList): 859 for t in changeList: 860 self.OnAttribute(*t) 861 862 def OnPostCfgDataChanged(self, what, data): 863 if what == 'evelocations': 864 bracket = self.GetBracket(data[0]) 865 if bracket is not None: 866 bracket.displayName = None 867 868 def OnCaptureChanged(self, ballID, captureID, lastIncident, points, captureTime, lastCapturing): 869 bracket = self.GetBracket(ballID) 870 if not hasattr(self, 'capturePoints'): 871 self.capturePoints = {} 872 self.capturePoints[ballID] = {'captureID': captureID, 873 'lastIncident': blue.os.GetSimTime(), 874 'points': points, 875 'captureTime': captureTime, 876 'lastCapturing': lastCapturing} 877 if bracket: 878 bracket.UpdateCaptureProgress(self.capturePoints[ballID]) 879 880 def ResetOverlaps(self): 881 for each in self.overlaps: 882 if not getattr(each, 'IsBracket', 0): 883 continue 884 projectBracket = each.projectBracket 885 if projectBracket: 886 projectBracket.bracket = each.GetRenderObject() 887 each.KillLabel() 888 each.opacity = getattr(each, '_pervious_opacity', 1.0) 889 each.SetAlign(uiconst.NOALIGN) 890 891 for each in self.overlapsHidden: 892 bubble = each.sr.bubble 893 if bubble: 894 bubble.state = uiconst.UI_PICKCHILDREN 895 896 self.overlaps = [] 897 self.overlapsHidden = [] 898 899 def GetOverlapOverlap(self, sameX, minY, maxY): 900 overlaps = [] 901 stillLeft = [] 902 for bracket in sameX: 903 if bracket.absoluteTop > minY - 16 and bracket.absoluteBottom < maxY + 16: 904 if bracket.displayName: 905 overlaps.append((bracket.displayName.lower(), bracket)) 906 else: 907 overlaps.append(('', bracket)) 908 else: 909 stillLeft.append(bracket) 910 911 return (overlaps, stillLeft) 912 913 def CheckingOverlaps(self): 914 return self.checkingOverlaps 915 916 @telemetry.ZONE_METHOD 917 def CheckOverlaps(self, sender, hideRest = 0): 918 self.checkingOverlaps = sender.itemID 919 self.ResetOverlaps() 920 overlaps = [] 921 excludedC = (appConst.categoryAsteroid,) 922 excludedG = (appConst.groupHarvestableCloud,) 923 sameX = [] 924 LEFT = 0 925 TOP = 1 926 BOTTOM = 2 927 RIGHT = 3 928 BRACKETSIZE = 16 929 MAXEXPANDED = 15 930 931 @Memoize 932 def GetAbsolute(bracket): 933 ro = bracket.GetRenderObject() 934 x, y = uicore.ReverseScaleDpi(ro.displayX), uicore.ReverseScaleDpi(ro.displayY) 935 centerX = x + bracket.width / 2 936 centerY = y + bracket.height / 2 937 return (centerX - 8, 938 centerY - 8, 939 centerY + 8, 940 centerX + 8) 941 942 s = GetAbsolute(sender) 943 topMargin, bottomMargin = sender.GetLockedPositionTopBottomMargin() 944 sender._topMargin = topMargin 945 sender._bottomMargin = bottomMargin 946 totalHeight = BRACKETSIZE + topMargin 947 for bracket in sender.parent.children: 948 if not getattr(bracket, 'IsBracket', 0) or not bracket.display or bracket.invisible or bracket.categoryID in excludedC or bracket.groupID in excludedG or bracket == sender: 949 continue 950 b = GetAbsolute(bracket) 951 overlapx = not (b[RIGHT] <= s[LEFT] or b[LEFT] >= s[RIGHT]) 952 overlapy = not (b[BOTTOM] <= s[TOP] or b[TOP] >= s[BOTTOM]) 953 if overlapx and overlapy and bracket.displayName: 954 topMargin, bottomMargin = bracket.GetLockedPositionTopBottomMargin() 955 bracket._topMargin = topMargin 956 bracket._bottomMargin = bottomMargin 957 totalHeight += topMargin + BRACKETSIZE + bottomMargin 958 overlaps.append((bracket.displayName.lower(), bracket)) 959 elif overlapx and not overlapy: 960 sameX.append(bracket) 961 if len(overlaps) == MAXEXPANDED: 962 break 963 964 if not overlaps: 965 self.checkingOverlaps = None 966 sender.parent.state = uiconst.UI_PICKCHILDREN 967 return 968 if sameX: 969 while len(overlaps) < MAXEXPANDED: 970 minY = s[TOP] - totalHeight 971 maxY = s[BOTTOM] 972 oo, sameX = self.GetOverlapOverlap(sameX, minY, maxY) 973 if not oo or not sameX: 974 break 975 for overlap in oo: 976 overlaps.append(overlap) 977 topMargin, bottomMargin = overlap[1].GetLockedPositionTopBottomMargin() 978 overlap[1]._topMargin = topMargin 979 overlap[1]._bottomMargin = bottomMargin 980 totalHeight += topMargin + BRACKETSIZE + bottomMargin 981 if len(overlaps) == MAXEXPANDED: 982 break 983 984 overlaps = SortListOfTuples(overlaps, reverse=True) 985 986 def LockBracketPosition(bracket, left, top): 987 projectBracket = bracket.projectBracket 988 if projectBracket: 989 projectBracket.bracket = None 990 bracket.SetAlign(uiconst.TOPLEFT) 991 bracket.left = left - bracket.width / 2 992 lockedTopPos = top - (bracket.height - 16) / 2 993 bracket.top = lockedTopPos 994 bracket._lockedTopPos = lockedTopPos 995 bracket.displayX = left 996 bracket._pervious_opacity = bracket.opacity 997 bracket.opacity = 1.0 998 bracket.SetOrder(0) 999 if hasattr(bracket, 'update_attached_objects'): 1000 bracket.update_attached_objects() 1001 1002 top = s[TOP] 1003 left = s[LEFT] + BRACKETSIZE / 2 1004 sender._lockedTopPos = top 1005 self.overlaps = [sender] + overlaps 1006 for overlapBracket in self.overlaps: 1007 hasBubble = bool(overlapBracket.sr.bubble) 1008 if not hasBubble: 1009 overlapBracket.ShowLabel() 1010 if overlapBracket is not sender: 1011 top -= overlapBracket._bottomMargin 1012 LockBracketPosition(overlapBracket, left, top) 1013 top -= overlapBracket._topMargin + BRACKETSIZE 1014 1015 self.overlapsHidden = [] 1016 if hideRest: 1017 for bracket in sender.parent.children: 1018 if bracket is sender or bracket in overlaps or not getattr(bracket, 'IsBracket', 0) or bracket.state != uiconst.UI_PICKCHILDREN or bracket.invisible: 1019 continue 1020 bubble = bracket.sr.bubble 1021 if bubble: 1022 bubble.state = uiconst.UI_HIDDEN 1023 self.overlapsHidden.append(bracket) 1024 1025 if top < 0: 1026 for overlapBracket in self.overlaps: 1027 overlapBracket.top = -top + overlapBracket._lockedTopPos - BRACKETSIZE 1028 1029 sender.parent.state = uiconst.UI_PICKCHILDREN 1030 self.checkingOverlaps = None 1031 uicore.uilib.RegisterForTriuiEvents(uiconst.UI_MOUSEDOWN, self.OnGlobalMouseDown) 1032 1033 def OnGlobalMouseDown(self, *args): 1034 mo = uicore.uilib.mouseOver 1035 for bracket in self.overlaps: 1036 if mo in (bracket, bracket.label): 1037 return True 1038 1039 self.ResetOverlaps() 1040 1041 def GetBracket(self, bracketID): 1042 if getattr(self, 'brackets', None) is not None: 1043 return self.brackets.get(bracketID, None) 1044 1045 def ClearBracket(self, id, *args, **kwds): 1046 self.RemoveBracket(id) 1047 1048 def GetScanSpeed(self, source = None, target = None): 1049 if source is None: 1050 source = session.shipid 1051 if not source: 1052 return 1053 myitem = sm.GetService('godma').GetItem(source) 1054 scanSpeed = None 1055 if myitem.scanResolution and target: 1056 slimItem = target 1057 targetitem = sm.GetService('godma').GetType(slimItem.typeID) 1058 if targetitem.AttributeExists('signatureRadius'): 1059 radius = targetitem.signatureRadius 1060 else: 1061 radius = 0 1062 if radius <= 0.0: 1063 bp = sm.GetService('michelle').GetBallpark() 1064 radius = bp.GetBall(slimItem.itemID).radius 1065 if radius <= 0.0: 1066 radius = evetypes.GetRadius(targetitem.typeID) 1067 if radius <= 0.0: 1068 radius = 1.0 1069 scanSpeed = 40000000.0 / myitem.scanResolution / math.log(radius + math.sqrt(radius * radius + 1)) ** 2.0 1070 if scanSpeed is None: 1071 scanSpeed = 2000 1072 log.LogWarn('GetScanSpeed returned the defauly scanspeed of %s ms ... missing scanResolution?' % scanSpeed) 1073 return min(scanSpeed, 180000) 1074 1075 def GetCaptureData(self, ballID): 1076 if hasattr(self, 'capturePoints'): 1077 return self.capturePoints.get(ballID, None) 1078 1079 def ProcessBountyInfoUpdated(self, itemIDs): 1080 for itemID in itemIDs: 1081 try: 1082 self.brackets[itemID].RefreshBounty() 1083 except KeyError: 1084 pass 1085 1086 @telemetry.ZONE_METHOD 1087 def OnDamageMessages(self, dmgmsgs): 1088 for msg in dmgmsgs: 1089 self.OnDamageMessage(*msg[1:]) 1090 1091 @telemetry.ZONE_METHOD 1092 def OnDamageMessage(self, damageMessagesArgs): 1093 attackerID = damageMessagesArgs.get('attackerID', None) 1094 if attackerID is None: 1095 attackType = damageMessagesArgs.get('attackType', 'me') 1096 if attackType != 'me': 1097 self.LogWarn('No attacker found! - damageMessagesArgs = ', damageMessagesArgs) 1098 return 1099 damage = damageMessagesArgs['damage'] 1100 s = blue.os.GetSimTime() / appConst.SEC 1101 if attackerID not in self.damageByBracketID: 1102 self.damageByBracketID[attackerID] = collections.defaultdict(long) 1103 self.damageByBracketID[attackerID][s] += int(damage) 1104 if damage: 1105 self.TryBlinkAttacker(attackerID) 1106 1107 def DisableShowingDamageDealers(self, *args): 1108 if self.damageDealerTimer is None: 1109 return 1110 self.damageDealerTimer = None 1111 if not session.shipid: 1112 return 1113 oldDamageDealers = self.biggestDamageDealers[:] 1114 self.RemoveDamageIndicatorFromBrackets(oldDamageDealers, []) 1115 1116 def EnableShowingDamageDealers(self, *args): 1117 if self.damageDealerTimer is None: 1118 self.ShowBiggestDamageDealers_thread() 1119 self.damageDealerTimer = AutoTimer(1000, self.ShowBiggestDamageDealers_thread) 1120 1121 def TryBlinkAttacker(self, attackerID, *args): 1122 if attackerID not in self.biggestDamageDealers: 1123 return 1124 bracket = self.GetBracket(attackerID) 1125 if not bracket: 1126 return 1127 sprite = bracket.GetHitSprite(create=False) 1128 if sprite: 1129 uicore.animations.FadeTo(sprite, startVal=sprite.baseOpacity + 0.05, endVal=sprite.baseOpacity, duration=0.75, loops=1, curveType=uiconst.ANIM_OVERSHOT) 1130 1131 def ShowBiggestDamageDealers_thread(self, *args): 1132 oldDamageDealers = self.biggestDamageDealers[:] 1133 newDamageDealers = self.FindBiggestDamageDealers() 1134 alphas = [0.25, 1135 0.2, 1136 0.15, 1137 0.12, 1138 0.08] 1139 size = [100, 1140 90, 1141 80, 1142 75, 1143 70] 1144 counter = 0 1145 self.biggestDamageDealers = [] 1146 for damage, bracketID in newDamageDealers: 1147 bracket = self.GetBracket(bracketID) 1148 if bracket: 1149 sprite = bracket.GetHitSprite() 1150 currentPlace = getattr(sprite, 'currentPlace', None) 1151 duration = 0.2 1152 newOpacity = alphas[counter] 1153 sprite.baseOpacity = newOpacity 1154 newSize = size[counter] 1155 if currentPlace is None: 1156 sprite.width = sprite.height = newSize 1157 uicore.animations.FadeTo(sprite, startVal=0, endVal=newOpacity, duration=duration) 1158 else: 1159 uicore.animations.FadeTo(sprite, startVal=sprite.opacity, endVal=newOpacity, duration=duration) 1160 uicore.animations.MorphScalar(sprite, 'width', startVal=sprite.width, endVal=newSize, duration=duration) 1161 uicore.animations.MorphScalar(sprite, 'height', startVal=sprite.height, endVal=newSize, duration=duration) 1162 sprite.currentPlace = counter 1163 self.biggestDamageDealers.append(bracketID) 1164 if getattr(prefs, 'showDamageOnTarget', False): 1165 label = getattr(bracket, 'debugLabel', None) 1166 if not label: 1167 label = bracket.debugLabel = EveLabelSmall(text='', parent=bracket, top=42, align=uiconst.CENTERTOP, state=uiconst.UI_DISABLED) 1168 label.text = damage 1169 counter += 1 1170 1171 self.RemoveDamageIndicatorFromBrackets(oldDamageDealers, self.biggestDamageDealers) 1172 1173 def RemoveDamageIndicatorFromBrackets(self, oldDamageDealers, newDamageDealers, *args): 1174 for bracketID in oldDamageDealers: 1175 if bracketID in newDamageDealers: 1176 continue 1177 bracket = self.GetBracket(bracketID) 1178 if bracket is None: 1179 continue 1180 sprite = bracket.GetHitSprite(create=False) 1181 if sprite: 1182 sprite.Close() 1183 label = getattr(bracket, 'debugLabel', None) 1184 if label: 1185 label.Close() 1186 1187 def FindBiggestDamageDealers(self, *args): 1188 numDamageDealers = NUMBER_OF_DAMAGEDEALERS 1189 now = blue.os.GetSimTime() / appConst.SEC 1190 timeline = now - RECORDED_DAMAGE_PERIOD_SECONDS 1191 attackersToRemove = [] 1192 damageSumAndAttackerID = [] 1193 for attackerID in self.damageByBracketID: 1194 latestAttacks = collections.defaultdict(long) 1195 for timestamp, value in self.damageByBracketID[attackerID].iteritems(): 1196 if timestamp > timeline: 1197 latestAttacks[timestamp] = value 1198 1199 if len(latestAttacks) == 0: 1200 attackersToRemove.append(attackerID) 1201 continue 1202 self.damageByBracketID[attackerID] = latestAttacks 1203 if attackerID in self.brackets: 1204 totalDamage = sum(latestAttacks.itervalues()) 1205 if totalDamage == 0: 1206 continue 1207 attackersDamageTuple = (totalDamage, attackerID) 1208 damageSumAndAttackerID.append(attackersDamageTuple) 1209 1210 for attackerID in attackersToRemove: 1211 del self.damageByBracketID[attackerID] 1212 1213 damageSumAndAttackerID.sort(reverse=True) 1214 results = damageSumAndAttackerID[:numDamageDealers] 1215 return results 1216 1217 def DisableInTargetRange(self, *args): 1218 if self.inTargetRangeTimer is None: 1219 return 1220 self.inTargetRangeTimer = None 1221 if not session.shipid: 1222 return 1223 for key, bracket in self.brackets.items(): 1224 canTargetSprite = bracket.GetCanTargetSprite(create=False) 1225 if canTargetSprite: 1226 canTargetSprite.Close() 1227 1228 def EnableInTargetRange(self, *args): 1229 if self.inTargetRangeTimer is None: 1230 self.ShowInTargetRange() 1231 self.inTargetRangeTimer = AutoTimer(1000, self.ShowInTargetRange) 1232 1233 def ShowInTargetRange(self, *args): 1234 if not session.shipid: 1235 return 1236 bp = sm.GetService('michelle').GetBallpark() 1237 ship = sm.GetService('godma').GetItem(session.shipid) 1238 if ship is None: 1239 return 1240 maxTargetRange = ship.maxTargetRange 1241 for key, bracket in self.brackets.items(): 1242 if not bracket or bracket.destroyed or key == session.shipid: 1243 continue 1244 if bracket.categoryID not in BRACKET_CATEGORIES_WITH_RANGE_MARKER: 1245 continue 1246 settingConfigName = 'showCategoryInTargetRange_%s' % bracket.categoryID 1247 showCategory = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(settingConfigName, True) 1248 distance = self.GetBallDistanceFromBracketKey(bp, key) 1249 if distance is None: 1250 continue 1251 canTargetSprite = bracket.GetCanTargetSprite() 1252 if canTargetSprite is not None: 1253 if distance > maxTargetRange or not showCategory: 1254 newOpacity = 0.0 1255 canTargetSprite.display = False 1256 continue 1257 elif getattr(bracket, 'brighterForRange', False): 1258 newOpacity = 1.0 1259 else: 1260 newOpacity = 0.15 1261 canTargetSprite.display = True 1262 if canTargetSprite.opacity != newOpacity: 1263 canTargetSprite.opacity = newOpacity or 0 1264 1265 def ShowModuleRange(self, moduleID, rangeDistance, *args): 1266 showInTargetRange = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_TARGET_RANGE, True) 1267 if not showInTargetRange: 1268 return 1269 bp = sm.GetService('michelle').GetBallpark() 1270 maxTargetRange = sm.GetService('godma').GetItem(session.shipid).maxTargetRange 1271 for key, bracket in self.brackets.items(): 1272 if not bracket or bracket.destroyed or key == session.shipid: 1273 continue 1274 if bracket.categoryID not in BRACKET_CATEGORIES_WITH_RANGE_MARKER: 1275 continue 1276 distance = self.GetBallDistanceFromBracketKey(bp, key) 1277 if distance is None: 1278 continue 1279 if distance <= rangeDistance and distance <= maxTargetRange: 1280 bracket.brighterForRange = True 1281 canTargetSprite = bracket.GetCanTargetSprite() 1282 if canTargetSprite is not None: 1283 canTargetSprite.opacity = 1.0 1284 1285 def ShowHairlinesForModule(self, moduleID, reverse = False): 1286 showHairlines = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_MODULE_HAIRLINES, True) 1287 if not showHairlines: 1288 if self.hairlinesTimer: 1289 self.hairlinesTimer = None 1290 self.StopShowingHairlines() 1291 ship = sm.GetService('michelle').GetBall(session.shipid) 1292 for moduleID in ship.modules: 1293 self.ResetModuleIcon(moduleID) 1294 1295 return 1296 for target in sm.GetService('target').targetsByID.itervalues(): 1297 if not isinstance(target, TargetInBar): 1298 continue 1299 if target is None or target.destroyed: 1300 continue 1301 if moduleID in target.activeModules: 1302 weapon = target.GetWeapon(moduleID) 1303 icon = weapon.icon 1304 icon.SetAlpha(1.5) 1305 bracket = self.brackets.get(target.itemID) 1306 if bracket is None: 1307 return 1308 self.ShowHairlines(moduleID, bracket, target, reverse) 1309 return 1310 1311 def ShowHairlines(self, moduleID, bracket, target, reverse, *args): 1312 if getattr(self, 'vectorLines', None) is None: 1313 self.vectorLines = bracketVarious.TargetingHairlines() 1314 self.vectorLines.CreateHairlines(moduleID, bracket, target) 1315 self.vectorLines.UpdateHairlinePoints(moduleID, bracket, target) 1316 self.vectorLines.StartAnimation(reverse=reverse) 1317 self.hairlinesTimer = AutoTimer(50, self.AnimateVectorLine, moduleID, bracket, target) 1318 1319 def AnimateVectorLine(self, moduleID, bracket, target, *args): 1320 if getattr(self, 'vectorLines', None) is None: 1321 return 1322 if bracket.destroyed: 1323 self.vectorLines.StopAnimations() 1324 self.vectorLines.HideLines() 1325 self.hairlinesTimer = None 1326 return 1327 self.vectorLines.UpdateHairlinePoints(moduleID, bracket, target) 1328 1329 def StopShowingModuleRange(self, moduleID, *args): 1330 for key, bracket in self.brackets.items(): 1331 if not bracket or bracket.destroyed: 1332 continue 1333 if getattr(bracket, 'brighterForRange', False): 1334 canTargetSprite = bracket.GetCanTargetSprite() 1335 if canTargetSprite is not None: 1336 canTargetSprite.opacity = 0.3 1337 bracket.brighterForRange = False 1338 1339 self.StopShowingHairlines() 1340 self.ResetModuleIcon(moduleID) 1341 1342 def ResetModuleIcon(self, moduleID, *args): 1343 for target in sm.GetService('target').GetTargets().itervalues(): 1344 if not isinstance(target, TargetInBar): 1345 continue 1346 target.ResetModuleIcon(moduleID) 1347 1348 def StopShowingHairlines(self, *args): 1349 self.hairlinesTimer = None 1350 if getattr(self, 'vectorLines', None) is not None: 1351 self.vectorLines.HideLines() 1352 self.vectorLines.StopAnimations() 1353 1354 def GetBallDistanceFromBracketKey(self, bp, bracketKey, *args): 1355 ball = bp.GetBall(bracketKey) 1356 if ball is None: 1357 return 1358 try: 1359 distance = int(ball.surfaceDist) 1360 except ValueError: 1361 return 1362 1363 return distance 1364 1365 def OnMyFleetInited(self): 1366 self.UpdateFleetColor() 1367 1368 def OnStateSetupChange(self, *args): 1369 self.UpdateFleetColor() 1370 1371 def UpdateFleetColor(self): 1372 flagInfo = self.stateSvc.GetStatePropsColorAndBlink(state.flagSameFleet) 1373 self.fleetBracketColor = flagInfo.flagColor[:3] + (0.5,) 1374 1375 def GetFleetBracketColor(self): 1376 return self.fleetBracketColor 1377 1378 def OnEmanationLockUpdated(self, lockDetails): 1379 if not lockDetails or lockDetails.solar_system_id != session.solarsystemid2: 1380 return 1381 self._UpdateEmanationLock() 1382 1383 def OnEmanationGateLockRemoved(self, *args): 1384 if not session.solarsystemid: 1385 return 1386 self._UpdateEmanationLock() 1387 1388 def _UpdateEmanationLock(self): 1389 systemInfo = cfg.mapSolarSystemContentCache.get(session.solarsystemid2, None) 1390 if not systemInfo: 1391 return 1392 self.RenewFlagForItemIDs(systemInfo.stargates.keys())