shipUI.py (48744B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\shipHud\shipUI.py 2 import blue 3 import dogma.const as dogma_const 4 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst 5 import log 6 import telemetry 7 import threadutils 8 import trinity 9 import uthread 10 from carbon.client.script.environment.AudioUtil import PlaySound 11 from carbonui import uiconst, Align, PickState 12 from carbonui.control.buttonIcon import ButtonIcon 13 from carbonui.control.layer import LayerCore 14 from carbonui.primitives.container import Container 15 from carbonui.primitives.sprite import Sprite 16 from carbonui.uianimations import animations 17 from carbonui.uicore import uicore 18 from carbonui.util import colorblind 19 from carbonui.loggers.buttonLogger import log_button_clicked 20 from eve.client.script.parklife import states 21 from eve.client.script.ui.control.utilMenu import UtilMenu 22 from eve.client.script.ui.inflight.notifySettingsWindow import NotifySettingsWindow 23 from eve.client.script.ui.inflight.radialMenuScanner import RadialMenuScanner 24 from eve.client.script.ui.inflight.shipAlert import ShipAlertContainer 25 from eve.client.script.ui.inflight.shipHud.action_indication.hud_action_indication_container import HudActionIndicationContainer 26 from eve.client.script.ui.inflight.shipHud.activeShipController import ActiveShipController 27 from eve.client.script.ui.inflight.shipHud.buffBarContainer import BuffBarContainer 28 from eve.client.script.ui.inflight.shipHud.capacitorContainer import CapacitorContainer 29 from eve.client.script.ui.inflight.shipHud.heatGauges import HeatGauges 30 from eve.client.script.ui.inflight.shipHud.hpGauges import HPGauges 31 from eve.client.script.ui.inflight.shipHud.hudButtonsCont import HudButtonsCont 32 from eve.client.script.ui.inflight.shipHud.hudReadout import HudReadout 33 from eve.client.script.ui.inflight.shipHud.hudShape import HUDShape, StructureHUDShape 34 from eve.client.script.ui.inflight.shipHud.releaseControlBtn import ReleaseControlBtn 35 from eve.client.script.ui.inflight.shipHud.shipHudConst import SHIP_UI_HEIGHT, SHIP_UI_WIDTH 36 from eve.client.script.ui.inflight.shipHud.slotsContainer import SlotsContainer 37 from eve.client.script.ui.inflight.shipHud.speedGauge import SpeedGauge 38 from eve.client.script.ui.inflight.shipSafetyButton import SafetyButton 39 from eve.client.script.ui.inflight.shipscan import CargoScan, ShipScan 40 from eve.client.script.ui.inflight.squadrons.shipFighterState import GetShipFighterState 41 from eve.client.script.ui.inflight.squadrons.squadronsUI import SquadronsUI 42 from eve.client.script.ui.inflight.stanceButtons import StanceButtons 43 from eve.client.script.ui.moonmining.moonminingExtraHudBtns import MoonminingExtraHudBtns 44 from eve.client.script.ui.oremining.mining_scan_buttons import MiningScanButtons 45 from eve.client.script.ui.services.menuSvcExtras import movementFunctions 46 from eve.client.script.ui.util.uix import GetSlimItemName 47 from eve.client.script.ui.view import overlaySettings 48 from eve.client.script.ui.view.viewStateConst import ViewOverlay 49 from eve.client.script.util.settings import IsShipHudTopAligned, SetShipHudTopAligned 50 from eve.common.script.sys.eveCfg import IsControllingStructure 51 from gametime import GetDurationInClient 52 from localization import GetByLabel 53 from menu import MenuLabel 54 from mining.client.mining_util import has_current_ship_integrated_mining_scanner 55 from player_messaging.client.ui_message import prompt_player_fsd_dialog 56 from sensorsuite.overlay.sitecompass import Compass 57 from structures import IsDrillingPlatform 58 from structures.types import IsFlexStructure 59 from uihider import UiHiderMixin 60 SLOTS_CONTAINER_LEFT = SHIP_UI_WIDTH / 2.0 + 70 61 SLOTS_CONTAINER_TOP = -1 62 SLOTS_CONTAINER_WIDTH = 512 63 SLOTS_CONTAINER_HEIGHT = 152 64 EWAR_CONTAINER_WIDTH = 480 65 EWAR_CONTAINER_HEIGHT = 44 66 67 class ShipUI(LayerCore): 68 __notifyevents__ = ['OnShipScanCompleted', 69 'OnJamStart', 70 'OnJamEnd', 71 'OnCargoScanComplete', 72 'DoBallRemove', 73 'OnSetDevice', 74 'OnAssumeStructureControl', 75 'OnRelinquishStructureControl', 76 'OnUIRefresh', 77 'ProcessPendingOverloadUpdate', 78 'DoBallsRemove', 79 'OnSetCameraOffset', 80 'ProcessShipEffect', 81 'OnStateChange', 82 'OnDogmaAttributeChanged'] 83 84 def ApplyAttributes(self, attributes): 85 self.shipuiReady = False 86 self.fighterHudBinding = None 87 LayerCore.ApplyAttributes(self, attributes) 88 self.setupShipTasklet = None 89 self.updateTasklet = None 90 self.controller = ActiveShipController() 91 self.controller.on_new_itemID.connect(self.OnShipChanged) 92 self.compass = None 93 self.stanceButtons = None 94 self.moon_mining_buttons = None 95 self.mining_overlay_buttons = None 96 self.ResetSelf() 97 colorblind.on_colorblind_mode_changed.connect(self.OnColorBlindModeChanged) 98 99 def Close(self): 100 LayerCore.Close(self) 101 self.controller.Close() 102 103 def OnSetCameraOffset(self, cameraOffset): 104 if self.shipuiReady: 105 self.UpdatePosition() 106 107 def OnSetDevice(self): 108 if self.shipuiReady: 109 self.UpdatePosition() 110 111 def UpdateUIScaling(self, value, oldValue): 112 super(ShipUI, self).UpdateUIScaling(value, oldValue) 113 self.OnUIRefresh() 114 115 def OnUIRefresh(self): 116 self.CloseView(recreate=False) 117 self.OpenView() 118 119 def OnColorBlindModeChanged(self): 120 self.OnUIRefresh() 121 122 @telemetry.ZONE_METHOD 123 def ResetSelf(self): 124 self.RemoveFighterHudBinding() 125 self.safetyButton = None 126 self.fighterHudBinding = None 127 self.sr.selectedcateg = 0 128 self.sr.pendingreloads = [] 129 self.sr.rampTimers = {} 130 self.shipuiReady = False 131 self.initing = None 132 self.jammers = {} 133 self.assumingdelay = None 134 if self.updateTasklet is not None: 135 self.updateTasklet.kill() 136 self.updateTasklet = None 137 if self.setupShipTasklet is not None: 138 self.setupShipTasklet.kill() 139 self.setupShipTasklet = None 140 self.fighterCont = None 141 self.Flush() 142 143 def CheckSession(self, change): 144 if sm.GetService('autoPilot').GetState(): 145 self.OnAutoPilotOn() 146 else: 147 self.OnAutoPilotOff() 148 149 @telemetry.ZONE_METHOD 150 def UpdatePosition(self): 151 cameraOffset = sm.GetService('sceneManager').GetCameraOffset() 152 halfWidth = uicore.desktop.width / 2 153 baseOffset = -cameraOffset * halfWidth 154 wndLeft = settings.char.windows.Get('shipuialignleftoffset', 0) 155 maxRight, minLeft = self.GetShipuiOffsetMinMax() 156 self.hudContainer.left = min(maxRight, max(minLeft, baseOffset + wndLeft)) 157 self.buffBarContainer.left = self.hudContainer.left 158 if IsShipHudTopAligned(): 159 self.hudContainer.SetAlign(uiconst.CENTERTOP) 160 self.buffBarContainer.SetAlign(uiconst.CENTERTOP) 161 else: 162 self.hudContainer.SetAlign(uiconst.CENTERBOTTOM) 163 self.buffBarContainer.SetAlign(uiconst.CENTERBOTTOM) 164 self._update_indicator_cont_top() 165 if self.IsFightersDetached() and self.fighterCont: 166 left, top = GetFightersDetachedPos() 167 buttonWidth = 32 168 left = min(left, uicore.desktop.width - buttonWidth) 169 top = min(top, uicore.desktop.height - self.fighterCont.height) 170 self.fighterCont.left = left 171 self.fighterCont.top = top 172 settings.char.ui.Set('fightersDetachedPosition', (left, top)) 173 self.AlignFighters() 174 self.sr.shipAlertContainer.UpdatePosition() 175 176 def _update_indicator_cont_top(self): 177 if IsShipHudTopAligned(): 178 self.indicationContainer.align = Align.CENTERTOP 179 else: 180 self.indicationContainer.align = Align.CENTERBOTTOM 181 self.indicationContainer.top = self.hudContainer.height + self.buffBarContainer.height + 8 182 183 def MakeFighterHudBinding(self): 184 self.RemoveFighterHudBinding() 185 self.fighterHudBinding = trinity.CreatePythonBinding(uicore.uilib.bracketCurveSet, self, 'fighterContLeft', self.fighterCont, 'left') 186 187 def RemoveFighterHudBinding(self): 188 if self.fighterHudBinding: 189 cs = uicore.uilib.bracketCurveSet 190 cs.bindings.fremove(self.fighterHudBinding) 191 self.fighterHudBinding = None 192 193 def OnShipMouseDown(self, wnd, btn, *args): 194 if btn != 0: 195 return 196 self.dragging = True 197 if not self.hudContainer: 198 return 199 self.grab = [uicore.uilib.x, self.hudContainer.left] 200 uthread.new(self.BeginDrag) 201 202 def GetShipuiOffsetMinMax(self, *args): 203 magicNumber = 275 204 if self.CheckShipHasFighterBay(): 205 magicNumber = 300 206 sidePanelsLeft, sidePanelsRight = uicore.layer.sidepanels.GetSideOffset() 207 maxRight = uicore.desktop.width / 2 - self.slotsContainer.width / 2 - magicNumber - sidePanelsRight 208 minLeft = -(uicore.desktop.width / 2 - 180) + sidePanelsLeft 209 return (maxRight, minLeft) 210 211 def OnToggleShipSelected(self, *args): 212 if not self.CheckShipHasFighterBay(): 213 return 214 if not self.IsFightersShown(): 215 self.DeselectShip() 216 return 217 x, y = self.grab 218 currentX, currentY = uicore.uilib.x, self.hudContainer.left 219 if x != currentX or y != currentY: 220 return 221 if uicore.uilib.Key(uiconst.VK_CONTROL): 222 if movementFunctions.IsSelectedForNavigation(session.shipid): 223 self.DeselectShip() 224 else: 225 self.SelectShip() 226 else: 227 self.SelectShip() 228 self.fighterCont.ClearSelection() 229 230 def SelectShip(self): 231 movementFunctions.SelectForNavigation(session.shipid) 232 233 def DeselectShip(self): 234 movementFunctions.DeselectForNavigation(session.shipid) 235 236 def OnStateChange(self, itemID, flag, flagState, *args): 237 if not self.CheckShipHasFighterBay(): 238 return 239 if flag == states.selectedForNavigation and itemID == session.shipid: 240 if flagState: 241 self.ShowSelectionHilite() 242 else: 243 self.HideSelectionHilite() 244 245 def ShowSelectionHilite(self): 246 if self.shipSelectHilight.display: 247 return 248 self.shipSelectHilight.display = True 249 self.ringSprite.opacity = 0.2 250 self.bracketSprite.opacity = 3.0 251 uicore.animations.FadeTo(self.ringSprite, self.ringSprite.opacity, 1.0, duration=0.2) 252 uicore.animations.FadeTo(self.bracketSprite, self.bracketSprite.opacity, 1.0, duration=0.2) 253 254 def HideSelectionHilite(self): 255 self.shipSelectHilight.display = False 256 257 def OnShipMouseUp(self, wnd, btn, *args): 258 if btn != 0: 259 return 260 if wnd is self.capacitorContainer: 261 ui_name = getattr(self.capacitorContainer, 'uniqueUiName', None) 262 if ui_name: 263 self.capacitorContainer.analyticID = ui_name 264 log_button_clicked(self.capacitorContainer) 265 sm.StartService('ui').ForceCursorUpdate() 266 self.dragging = False 267 268 def BeginDrag(self, *args): 269 cameraOffset = sm.GetService('sceneManager').GetCameraOffset() 270 halfWidth = uicore.desktop.width / 2 271 baseOffset = -cameraOffset * halfWidth 272 while not self.hudContainer.destroyed and getattr(self, 'dragging', 0): 273 uicore.uilib.SetCursor(uiconst.UICURSOR_DIVIDERADJUST) 274 maxRight, minLeft = self.GetShipuiOffsetMinMax() 275 grabMouseDiff = uicore.uilib.x - self.grab[0] 276 combinedOffset = min(maxRight, max(minLeft, self.grab[1] + grabMouseDiff)) 277 dragOffset = combinedOffset - baseOffset 278 if -8 <= dragOffset <= 8: 279 settings.char.windows.Set('shipuialignleftoffset', 0) 280 self.hudContainer.left = baseOffset 281 else: 282 self.hudContainer.left = combinedOffset 283 settings.char.windows.Set('shipuialignleftoffset', dragOffset) 284 self.buffBarContainer.left = self.hudContainer.left 285 blue.pyos.synchro.SleepWallclock(1) 286 287 def ConstructOverlayContainer(self): 288 self.optionsCont = Container(parent=self.overlayContainer, name='optionsCont', pos=(190, 194, 16, 16), align=uiconst.TOPLEFT, state=uiconst.UI_PICKCHILDREN) 289 self.moduleToggleCont = Container(parent=self.overlayContainer, name='moduleToggleCont', pos=(self.moduleToggleContLeft, 290 170, 291 24, 292 24), align=uiconst.TOPLEFT, state=uiconst.UI_PICKCHILDREN) 293 if not IsControllingStructure(): 294 self.stopButton = StopButton(parent=self.overlayContainer, align=uiconst.TOPLEFT, controller=self.controller, left=75, top=155) 295 self.maxspeedButton = MaxSpeedButton(parent=self.overlayContainer, align=uiconst.TOPLEFT, controller=self.controller, left=168, top=155, uniqueUiName=pConst.UNIQUE_NAME_FULL_SPEED_BTN) 296 297 @telemetry.ZONE_METHOD 298 def OnOpenView(self, **kwargs): 299 self.ResetSelf() 300 self.state = uiconst.UI_HIDDEN 301 self.hudContainer = HudContainer(name='hudContainer', parent=self, controller=self.controller, align=uiconst.CENTERBOTTOM, width=SHIP_UI_WIDTH, height=SHIP_UI_HEIGHT) 302 self.centerParent = CenterHudContainer(name='centerParent', parent=self.hudContainer, align=uiconst.CENTERBOTTOM, pos=(0, 0, 185, 200)) 303 self.overlayContainer = Container(parent=self.centerParent, name='overlayContainer', pos=(0, 0, 256, 256), align=uiconst.CENTER, state=uiconst.UI_PICKCHILDREN, idx=0) 304 self.ConstructOverlayContainer() 305 if IsControllingStructure(): 306 shipShape = StructureHUDShape(parent=self.centerParent, align=uiconst.CENTER) 307 else: 308 shipShape = HUDShape(parent=self.centerParent, align=uiconst.CENTER) 309 self.shipuiMainShape = shipShape.shipuiMainShape 310 self.capacitorContainer = CapacitorContainer(parent=self.centerParent, align=uiconst.CENTER, top=-1, controller=self.controller, uniqueUiName=pConst.UNIQUE_NAME_CAPACITOR) 311 self.capacitorContainer.OnMouseDown = (self.OnShipMouseDown, self.capacitorContainer) 312 self.capacitorContainer.OnMouseUp = (self.OnShipMouseUp, self.capacitorContainer) 313 self.capacitorContainer.OnClick = self.OnToggleShipSelected 314 heatPicker = Container(name='heatPicker', parent=self.centerParent, align=uiconst.CENTER, width=160, height=160, pickRadius=43, state=uiconst.UI_NORMAL) 315 self.heatGauges = HeatGauges(parent=heatPicker, align=uiconst.CENTERTOP, controller=self.controller) 316 self.hpGauges = HPGauges(name='healthGauges', parent=self.centerParent, align=uiconst.CENTER, pos=(0, -37, 148, 74), controller=self.controller, uniqueUiName=pConst.UNIQUE_NAME_SHIP_HEALTH) 317 if IsControllingStructure(): 318 ReleaseControlBtn(parent=self.centerParent, top=29, align=uiconst.CENTERBOTTOM, func=self.ReleaseStructureControl, structureTypeID=self.controller.GetTypeID(), uniqueUiName=pConst.UNIQUE_NAME_RELEASE_CONTROL) 319 else: 320 self.speedGauge = SpeedGauge(parent=self.centerParent, top=29, align=uiconst.CENTERBOTTOM, controller=self.controller) 321 if is_compass_enabled(): 322 self.compass = self.CreateCompass() 323 self.shipSelectHilight = Container(name='navSelectHilight', parent=self.centerParent, align=uiconst.CENTER, state=uiconst.UI_DISABLED, width=self.shipSelectHilightSize, height=self.shipSelectHilightSize) 324 self.ringSprite = Sprite(bgParent=self.shipSelectHilight, texturePath='res:/UI/Texture/classes/ShipUI/Fighters/selectionRingLarge.png') 325 self.bracketSprite = Sprite(bgParent=self.shipSelectHilight, texturePath='res:/UI/Texture/classes/ShipUI/Fighters/selectionBracketLarge.png') 326 self.shipSelectHilight.display = False 327 self.slotsContainer = SlotsContainer(parent=self.hudContainer, pos=(self.slotsContLeft, 328 SLOTS_CONTAINER_TOP, 329 SLOTS_CONTAINER_WIDTH, 330 SLOTS_CONTAINER_HEIGHT), align=uiconst.CENTERLEFT, state=uiconst.UI_PICKCHILDREN, controller=self.controller) 331 self.stanceButtons = StanceButtons(parent=self.hudContainer, pos=(self.stanceButtonsLeft, 332 1, 333 40, 334 120), name='stanceButtons', align=uiconst.CENTERLEFT, state=uiconst.UI_PICKCHILDREN, buttonSize=36) 335 self.stanceButtons.Hide() 336 self.moon_mining_buttons = MoonminingExtraHudBtns(parent=self.hudContainer, pos=(self.stanceButtonsLeft, 337 -14, 338 60, 339 120), align=uiconst.CENTERLEFT, state=uiconst.UI_PICKCHILDREN) 340 self.moon_mining_buttons.Hide() 341 self.mining_overlay_buttons = MiningScanButtons(parent=self.hudContainer, left=self.stanceButtonsLeft, align=Align.CENTERLEFT, display=False, pickState=PickState.ON) 342 self.hudButtons = HudButtonsCont(name='hudButtons', parent=self.hudContainer, align=uiconst.CENTERRIGHT, left=self.hudButtonsLeft, top=15) 343 self.buffBarContainer = BuffBarContainer(parent=self, align=uiconst.CENTERBOTTOM, top=SHIP_UI_HEIGHT, height=EWAR_CONTAINER_HEIGHT, width=EWAR_CONTAINER_WIDTH) 344 self.sr.shipAlertContainer = ShipAlertContainer(parent=self.hudContainer) 345 self.indicationContainer = HudActionIndicationContainer(parent=self.hudContainer, name='indicationContainer', align=uiconst.CENTERTOP) 346 self.safetyButton = SafetyButton(parent=self.overlayContainer, left=self.safetyButtonLeft, top=self.safetyButtonTop, uniqueUiName=pConst.UNIQUE_NAME_SAFETY_BUTTON) 347 self.ConstructReadoutCont() 348 self.settingsMenu = UtilMenu(name='hudSettingsMenu', uniqueUiName=pConst.UNIQUE_NAME_HUD_SETTINGS, menuAlign=uiconst.BOTTOMLEFT, parent=self.optionsCont, align=uiconst.TOPLEFT, GetUtilMenu=self.GetHUDOptionMenu, pos=(0, 0, 16, 16), texturePath='res:/UI/Texture/Icons/73_16_50.png', hint=GetByLabel('UI/Inflight/Options')) 349 _oldMouseUp = self.settingsMenu.OnMouseUp 350 menu = self.settingsMenu 351 352 def _SettingsMenuOnMouseUp(*args): 353 ui_name = getattr(menu, 'uniqueUiName', None) 354 if ui_name: 355 menu.analyticID = ui_name 356 try: 357 log_button_clicked(menu) 358 except Exception: 359 pass 360 361 if _oldMouseUp: 362 return _oldMouseUp(*args) 363 364 menu.OnMouseUp = _SettingsMenuOnMouseUp 365 self.moduleToggleBtn = ButtonIcon(name='moduleToggleBtn', parent=self.moduleToggleCont, align=uiconst.TOPLEFT, width=24, height=24, iconSize=24, texturePath='res:/UI/Texture/classes/ShipUI/Fighters/toggleModules_Up.png', func=self.OnToggleHudModules, hint=GetByLabel('UI/Inflight/HUDOptions/ClickToToggle'), uniqueUiName=pConst.UNIQUE_NAME_FIGHTERS_TOGGLE) 366 self.moduleToggleBtn.display = False 367 self.moduleToggleBtn.GetMenu = self.GetModuleToggleBtnMenu 368 self.DrawFighters() 369 self.hudContainer.state = uiconst.UI_PICKCHILDREN 370 self.UpdatePosition() 371 self.UpdateButtonPositions() 372 self.shipuiReady = True 373 self.SetupShip() 374 Sprite(parent=self.centerParent, name='bgCircle', texturePath='res:/UI/Texture/classes/ShipUI/mainBGCircle.png', color=(0, 0, 0, 0.3), pos=(0, 0, 160, 160), align=uiconst.CENTER, state=uiconst.UI_DISABLED) 375 376 def ReleaseStructureControl(self, structureTypeID): 377 structureControlSvc = sm.GetService('structureControl') 378 if IsFlexStructure(structureTypeID): 379 structureControlSvc.BoardPreviousShip() 380 else: 381 return structureControlSvc.ReleaseControl() 382 383 def DrawFighters(self): 384 if self.fighterCont and not self.fighterCont.destroyed: 385 self.fighterCont.Close() 386 self.fighterCont = SquadronsUI(name='fighters', parent=self, state=uiconst.UI_PICKCHILDREN, parentFunc=self.OnToggleFightersDetached) 387 self.AlignFighters() 388 if self.IsFightersDetached(): 389 left, top = GetFightersDetachedPos() 390 self.fighterCont.left = left 391 self.fighterCont.top = top 392 self.slotsContainer.display = True 393 else: 394 self.fighterCont.left = self.slotsContLeft 395 self.SetFighterButtonsHint() 396 self.fighterCont.KeepSelection() 397 398 def SetFighterButtonsHint(self): 399 isDetached = self.IsFightersDetached() 400 if isDetached: 401 self.fighterCont.fighterToggleBtn.hint = GetByLabel('UI/Inflight/HUDOptions/ClickToAttach') 402 else: 403 self.fighterCont.fighterToggleBtn.hint = GetByLabel('UI/Inflight/HUDOptions/DragToDetach') 404 self.fighterCont.SetToggleBtnTexture(isDetached) 405 406 def CheckShipHasFighterBay(self): 407 if not session.shipid: 408 return False 409 godmaSM = sm.GetService('godma').GetStateManager() 410 shipTypeID = self.controller.GetTypeID() 411 if shipTypeID is None: 412 return False 413 fighterCapacity = godmaSM.GetType(shipTypeID).fighterCapacity 414 return fighterCapacity > 0 415 416 def OptionsBtnMouseEnter(self, *args): 417 self.options.SetAlpha(1.0) 418 419 def OptionsBtnMouseExit(self, *args): 420 self.options.SetAlpha(0.8) 421 422 def CheckControl(self): 423 control = sm.GetService('pwn').GetCurrentControl() 424 if control: 425 self.OnAssumeStructureControl() 426 427 def SetButtonState(self): 428 if settings.user.ui.Get('hudButtonsExpanded', 1): 429 self.hudButtons.state = uiconst.UI_PICKCHILDREN 430 if IsControllingStructure(): 431 self.hudButtons.autopilotBtn.Disable() 432 else: 433 self.hudButtons.autopilotBtn.Enable() 434 else: 435 self.hudButtons.state = uiconst.UI_HIDDEN 436 437 @telemetry.ZONE_METHOD 438 def ConstructReadoutCont(self): 439 self.readoutCont = HudReadout(parent=self.hudContainer, pos=(278, 22, 200, 0), align=uiconst.TOPLEFT, state=uiconst.UI_HIDDEN, controller=self.controller) 440 441 def OnAssumeStructureControl(self, *args): 442 now = blue.os.GetSimTime() 443 self.assumingdelay = now 444 uthread.new(self.DelayedOnAssumeStructureControl, now) 445 446 def DelayedOnAssumeStructureControl(self, issueTime): 447 blue.pyos.synchro.SleepSim(250) 448 if self.assumingdelay is None: 449 return 450 issuedAt = self.assumingdelay 451 if issuedAt != issueTime: 452 return 453 self.assumingdelay = None 454 self.ShowStructureControl() 455 456 def ShowStructureControl(self, *args): 457 if self.controller.IsControllingTurret(): 458 self.initing = 1 459 self.slotsContainer.InitSlots() 460 self.hudButtons.construct_buttons() 461 self.initing = 0 462 463 def OnRelinquishStructureControl(self, *args): 464 self.SetupShip() 465 466 @property 467 def slotsContLeft(self): 468 offset = 16 if is_compass_enabled() else 0 469 if self.stanceButtons and self.stanceButtons.display or self.moon_mining_buttons and self.moon_mining_buttons.display or self.mining_overlay_buttons and self.mining_overlay_buttons.display: 470 offset += 32 471 return SLOTS_CONTAINER_LEFT + offset - 8 472 473 @property 474 def stanceButtonsLeft(self): 475 offset = 16 if is_compass_enabled() else 0 476 return SLOTS_CONTAINER_LEFT + 4 + offset - 8 477 478 @property 479 def fighterContLeft(self): 480 offset = 8 if is_compass_enabled() else -8 481 left = self.centerParent.GetAbsoluteRight() 482 return left + offset 483 484 @property 485 def moduleToggleContLeft(self): 486 if is_compass_enabled(): 487 return 202 488 return 186 489 490 @property 491 def safetyButtonLeft(self): 492 if is_compass_enabled(): 493 return 40 494 return 50 495 496 @property 497 def safetyButtonTop(self): 498 if is_compass_enabled(): 499 return 28 500 return 38 501 502 @property 503 def hudButtonsLeft(self): 504 if is_compass_enabled(): 505 return 690 506 return 680 507 508 @property 509 def shipSelectHilightSize(self): 510 if is_compass_enabled(): 511 return 206 512 return 172 513 514 def UpdateButtonsForShip(self): 515 itemID = self.controller.GetItemID() 516 typeID = self.controller.GetTypeID() 517 self.moon_mining_buttons.Hide() 518 if self.stanceButtons.HasStances(): 519 self.stanceButtons.Hide() 520 self.stanceButtons.UpdateButtonsForShip(itemID, typeID) 521 if self.stanceButtons.HasStances(): 522 self.stanceButtons.Show() 523 elif self.should_show_moon_mining_buttons(typeID): 524 self.moon_mining_buttons.UpdateButtonsForHull() 525 self.moon_mining_buttons.Show() 526 self.mining_overlay_buttons.display = has_current_ship_integrated_mining_scanner() 527 self.UpdateButtonPositions() 528 529 def should_show_moon_mining_buttons(self, typeID): 530 return IsDrillingPlatform(typeID) 531 532 def ToggleCompass(self): 533 settings.user.ui.Set('showSensorOverlay', not is_compass_enabled()) 534 if is_compass_enabled(): 535 self.compass = self.CreateCompass() 536 else: 537 self.compass.Close() 538 self.compass = None 539 self.UpdateButtonPositions() 540 541 def CreateCompass(self): 542 return Compass(parent=self.centerParent, uniqueUiName=pConst.UNIQUE_NAME_SENSOR_OVERLAY) 543 544 def UpdateButtonPositions(self): 545 self.slotsContainer.left = self.slotsContLeft 546 self.stanceButtons.left = self.stanceButtonsLeft 547 self.moon_mining_buttons.left = self.stanceButtonsLeft 548 self.mining_overlay_buttons.left = self.stanceButtonsLeft 549 self.moduleToggleCont.left = self.moduleToggleContLeft 550 self.safetyButton.left = self.safetyButtonLeft 551 self.safetyButton.top = self.safetyButtonTop 552 self.hudButtons.left = self.hudButtonsLeft 553 self.shipSelectHilight.width = self.shipSelectHilightSize 554 self.shipSelectHilight.height = self.shipSelectHilightSize 555 556 def OnDogmaAttributeChanged(self, shipID, itemID, attributeID, value): 557 if shipID == session.shipid and attributeID in (dogma_const.attributeMiningScannerUpgrade, dogma_const.attributeIntegratedMiningScanner): 558 self.UpdateButtonsForShip() 559 560 def GetHUDOptionMenu(self, menuParent): 561 showPassive = settings.user.ui.Get('showPassiveModules', 1) 562 text = GetByLabel('UI/Inflight/HUDOptions/DisplayPassiveModules') 563 menuParent.AddCheckBox(text=text, checked=showPassive, callback=self.ToggleShowPassive) 564 showEmpty = settings.user.ui.Get('showEmptySlots', 0) 565 text = GetByLabel('UI/Inflight/HUDOptions/DisplayEmptySlots') 566 menuParent.AddCheckBox(text=text, checked=showEmpty, callback=self.ToggleShowEmpty) 567 showReadout = settings.user.ui.Get('showReadout', 0) 568 text = GetByLabel('UI/Inflight/HUDOptions/DisplayReadout') 569 menuParent.AddCheckBox(text=text, checked=showReadout, callback=self.ToggleReadout) 570 readoutType = settings.user.ui.Get('readoutType', 1) 571 text = GetByLabel('UI/Inflight/HUDOptions/DisplayReadoutAsPercentage') 572 if showReadout: 573 callback = self.ToggleReadoutType 574 else: 575 callback = None 576 menuParent.AddCheckBox(text=text, checked=readoutType, callback=callback) 577 showHudButtons = settings.user.ui.Get('hudButtonsExpanded', 1) 578 menuParent.AddCheckBox(text=GetByLabel('UI/Inflight/HUDOptions/DisplayUtilityButtons'), checked=showHudButtons, callback=self.ToggleHudButtons) 579 menuParent.AddCheckBox(text=GetByLabel('UI/Inflight/HUDOptions/DisplayZoomButtons'), checked=settings.user.ui.Get('showZoomBtns', 0), callback=self.ToggleShowZoomBtns if showHudButtons else None) 580 showTooltips = settings.user.ui.Get('showModuleTooltips', 1) 581 text = GetByLabel('UI/Inflight/HUDOptions/DisplayModuleTooltips') 582 menuParent.AddCheckBox(text=text, checked=showTooltips, callback=self.ToggleShowModuleTooltips) 583 text = GetByLabel('UI/Inflight/HUDOptions/DisplaySensorOverlay') 584 menuParent.AddCheckBox(text=text, checked=is_compass_enabled(), callback=self.ToggleCompass, uniqueUiName=pConst.UNIQUE_NAME_SENSOR_OVERLAY_SETTING) 585 menuParent.AddDivider() 586 lockModules = settings.user.ui.Get('lockModules', 0) 587 text = GetByLabel('UI/Inflight/HUDOptions/LockModulesInPlace') 588 menuParent.AddCheckBox(text=text, checked=lockModules, callback=self.ToggleLockModules) 589 menuParent.AddCheckBox(text=GetByLabel('UI/Inflight/HUDOptions/BlinkCargo'), checked=self.GetCargoBlinkValue(), callback=self.ToggleBlinkCargo) 590 lockOverload = settings.user.ui.Get('lockOverload', 0) 591 text = GetByLabel('UI/Inflight/HUDOptions/LockOverloadState') 592 menuParent.AddCheckBox(text=text, checked=lockOverload, callback=self.ToggleOverloadLock) 593 text = GetByLabel('UI/Inflight/HUDOptions/AlignHUDToTop') 594 cb = menuParent.AddCheckBox(text=text, checked=IsShipHudTopAligned(), callback=self.ToggleAlign) 595 cb.isToggleEntry = False 596 text = GetByLabel('/Carbon/UI/Controls/Window/AlwaysAboveFullScreenViews') 597 menuParent.AddCheckBox(text=text, checked=overlaySettings.IsFullscreenOverlayModeEnabled(ViewOverlay.ShipUI), callback=lambda : overlaySettings.ToggleFullscreenOverlayMode(ViewOverlay.ShipUI)) 598 menuParent.AddDivider() 599 text = GetByLabel('UI/Inflight/NotifySettingsWindow/DamageAlertSettings') 600 iconPath = 'res:/UI/Texture/classes/UtilMenu/BulletIcon.png' 601 menuParent.AddIconEntry(icon=iconPath, text=text, callback=self.ShowNotifySettingsWindow) 602 if sm.GetService('logger').IsInDragMode(): 603 text = GetByLabel('UI/Accessories/Log/ExitMessageMovingMode') 604 enterArgs = False 605 else: 606 text = GetByLabel('UI/Accessories/Log/EnterMessageMovingMode') 607 enterArgs = True 608 menuParent.AddIconEntry(icon='res:/UI/Texture/classes/UtilMenu/BulletIcon.png', text=text, callback=(sm.GetService('logger').MoveNotifications, enterArgs)) 609 610 def ShowNotifySettingsWindow(self): 611 NotifySettingsWindow.Open() 612 613 def ToggleAlign(self): 614 SetShipHudTopAligned(not IsShipHudTopAligned()) 615 self.UpdatePosition() 616 for each in uicore.layer.abovemain.children[:]: 617 if each.name == 'message': 618 each.Close() 619 break 620 621 msg = getattr(uicore.layer.target, 'message', None) 622 if msg: 623 msg.Close() 624 625 def CheckShowReadoutCont(self): 626 if settings.user.ui.Get('showReadout', 0): 627 self.readoutCont.state = uiconst.UI_DISABLED 628 self.hudButtons.top = 30 629 else: 630 self.readoutCont.state = uiconst.UI_HIDDEN 631 self.hudButtons.top = 15 632 633 def ToggleReadout(self): 634 current = not settings.user.ui.Get('showReadout', 0) 635 settings.user.ui.Set('showReadout', current) 636 self.CheckShowReadoutCont() 637 638 def GetCargoBlinkValue(self): 639 return settings.user.ui.Get('BlinkCargoHudIcon', True) 640 641 def ToggleBlinkCargo(self): 642 settings.user.ui.Set('BlinkCargoHudIcon', not self.GetCargoBlinkValue()) 643 644 def ToggleReadoutType(self): 645 current = settings.user.ui.Get('readoutType', 1) 646 settings.user.ui.Set('readoutType', not current) 647 648 def ToggleShowZoomBtns(self): 649 settings.user.ui.Set('showZoomBtns', not settings.user.ui.Get('showZoomBtns', 0)) 650 self.hudButtons.construct_buttons() 651 652 def ToggleLockModules(self): 653 settings.user.ui.Set('lockModules', not settings.user.ui.Get('lockModules', 0)) 654 self.slotsContainer.CheckGroupAllButton() 655 656 def ToggleOverloadLock(self): 657 settings.user.ui.Set('lockOverload', not settings.user.ui.Get('lockOverload', 0)) 658 659 def ToggleShowModuleTooltips(self): 660 settings.user.ui.Set('showModuleTooltips', not settings.user.ui.Get('showModuleTooltips', 1)) 661 662 def ToggleHudButtons(self): 663 isExpanded = self.hudButtons.state == uiconst.UI_PICKCHILDREN 664 if isExpanded: 665 PlaySound(uiconst.SOUND_COLLAPSE) 666 self.hudButtons.state = uiconst.UI_HIDDEN 667 else: 668 PlaySound(uiconst.SOUND_EXPAND) 669 self.hudButtons.state = uiconst.UI_PICKCHILDREN 670 settings.user.ui.Set('hudButtonsExpanded', not isExpanded) 671 672 def GetModuleToggleBtnMenu(self, *args): 673 if self.IsFightersDetached(): 674 menuLabel = MenuLabel('UI/Inflight/ResetFighterPosition') 675 return [[menuLabel, self.ResetSetFightersPos, ()]] 676 return [] 677 678 def ResetSetFightersPos(self): 679 ResetSetFightersDetachedPos() 680 self.DrawFighters() 681 682 def OnToggleHudModules(self, *args): 683 if self.IsFightersDetached(): 684 self.OnToggleFightersDetached() 685 else: 686 settings.user.ui.Set('displayFighterUI', not settings.user.ui.Get('displayFighterUI', False)) 687 self.ShowHideFighters() 688 689 def OnToggleFightersDetached(self, *args): 690 isDetached = self.IsFightersDetached() 691 settings.user.ui.Set('detachFighterUI', not isDetached) 692 if isDetached: 693 self.AttachHudModules() 694 else: 695 self.DetachHudModules() 696 697 def AttachHudModules(self): 698 self.AlignFighters() 699 self.fighterCont.left = 0 700 self.fighterCont.top = 10 701 self.MakeFighterHudBinding() 702 self.ShowHideFighters() 703 self.SetFighterButtonsHint() 704 705 def DetachHudModules(self): 706 self.slotsContainer.display = True 707 self.RemoveFighterHudBinding() 708 self.DrawFighters() 709 710 def InitFighters(self): 711 if not self.IsFightersDetached(): 712 self.MakeFighterHudBinding() 713 self.ShowHideFighters() 714 else: 715 self.DetachHudModules() 716 self.slotsContainer.display = True 717 718 def ShowHideFighters(self): 719 displayFighters = self.IsFightersShown() 720 isDetached = self.IsFightersDetached() 721 if self.CheckShipHasFighterBay(): 722 if isDetached: 723 self.fighterCont.display = True 724 self.slotsContainer.display = True 725 return 726 if displayFighters == True: 727 self.fighterCont.display = True 728 self.slotsContainer.display = False 729 return 730 self.fighterCont.ClearSelection() 731 self.fighterCont.display = False 732 self.slotsContainer.display = True 733 self.DeselectShip() 734 735 def AlignFighters(self): 736 if not self.fighterCont or self.fighterCont.destroyed: 737 return 738 if self.IsFightersDetached(): 739 self.fighterCont.SetAlign(uiconst.TOPLEFT) 740 elif IsShipHudTopAligned(): 741 self.fighterCont.SetAlign(uiconst.TOTOP) 742 else: 743 self.fighterCont.SetAlign(uiconst.TOBOTTOM) 744 self.fighterCont.top = 10 745 746 def IsFightersDetached(self): 747 return settings.user.ui.Get('detachFighterUI', False) 748 749 def IsFightersShown(self): 750 return settings.user.ui.Get('displayFighterUI', False) 751 752 def Scanner(self, button): 753 self.expandTimer = None 754 uicore.layer.menu.Flush() 755 radialMenu = RadialMenuScanner(name='radialMenu', parent=uicore.layer.menu, state=uiconst.UI_NORMAL, align=uiconst.TOPLEFT, anchorObject=button) 756 uicore.layer.menu.radialMenu = radialMenu 757 uicore.uilib.SetMouseCapture(radialMenu) 758 759 def BlinkButton(self, key): 760 self.slotsContainer.BlinkButton(key) 761 762 def ChangeOpacityForRange(self, currentRange, *args): 763 if getattr(self, 'slotContainer', None): 764 self.slotsContainer.ChangeOpacityForRange(self, currentRange) 765 766 def ResetModuleButtonOpacity(self, *args): 767 if getattr(self, 'slotContainer', None): 768 self.slotsContainer.ResetModuleButtonOpacity() 769 770 def ToggleRackOverload(self, slotName): 771 self.slotsContainer.ToggleRackOverload(slotName) 772 773 def ProcessPendingOverloadUpdate(self, moduleIDs): 774 self.slotsContainer.ProcessPendingOverloadUpdate(moduleIDs) 775 776 def ResetSwapMode(self): 777 self.slotsContainer.ResetSwapMode() 778 779 def StartDragMode(self, itemID, typeID): 780 self.slotsContainer.StartDragMode(itemID, typeID) 781 782 def GetPosFromFlag(self, slotFlag): 783 return self.slotsContainer.GetPosFromFlag(slotFlag) 784 785 def GetSlotByName(self, name): 786 return self.slotsContainer.FindChild(name) 787 788 def ChangeSlots(self, toFlag, fromFlag): 789 self.slotsContainer.ChangeSlots(toFlag, fromFlag) 790 791 def SwapSlots(self, slotFlag1, slotFlag2): 792 self.slotsContainer.SwapSlots(slotFlag1, slotFlag2) 793 794 def LinkWeapons(self, master, slave, slotFlag1, slotFlag2, merge = False): 795 self.slotsContainer.LinkWeapons(master, slave, slotFlag1, slotFlag2, merge) 796 797 def GetModuleType(self, flag): 798 return self.slotsContainer.GetModuleType(flag) 799 800 def GetModuleFromID(self, moduleID): 801 return self.slotsContainer.GetModuleFromID(moduleID) 802 803 def ToggleShowEmpty(self): 804 self.slotsContainer.ToggleShowEmpty() 805 806 def ToggleShowPassive(self): 807 self.slotsContainer.ToggleShowPassive() 808 809 def GetModuleForFKey(self, key): 810 return self.slotsContainer.GetModuleForFKey(key) 811 812 def GetModule(self, moduleID): 813 return self.slotsContainer.GetModule(moduleID) 814 815 def OnF(self, sidx, gidx): 816 if not self.CheckShipHasFighterBay(): 817 self.slotsContainer.OnF(sidx, gidx) 818 return 819 shipIsSelected, fightersSelected = movementFunctions.GetSelectedShipAndFighters() 820 if self.IsFightersDetached(): 821 moduleIsActive = self.IsModuleActiveForFKey(sidx, gidx) 822 isAllAbilitiesActiveOrInCooldown = GetShipFighterState().IsAllAbilitiesInSlotActiveOrInCooldown(sidx) 823 if shipIsSelected: 824 if isAllAbilitiesActiveOrInCooldown: 825 if moduleIsActive is not None: 826 self.slotsContainer.OnF(sidx, gidx) 827 if moduleIsActive is None or moduleIsActive == True: 828 self.TryActivateFighters(sidx, gidx) 829 else: 830 self.TryActivateFighters(sidx, gidx) 831 if moduleIsActive == False: 832 self.slotsContainer.OnF(sidx, gidx) 833 else: 834 self.TryActivateFighters(sidx, gidx) 835 elif self.IsFightersShown(): 836 self.TryActivateFighters(sidx, gidx) 837 else: 838 self.slotsContainer.OnF(sidx, gidx) 839 840 def ActivateModuleByItemID(self, itemID): 841 moduleButton = self.GetModule(itemID) 842 if moduleButton: 843 moduleButton.ActivateModule() 844 845 def DeactivateModuleByItemID(self, itemID): 846 moduleButton = self.GetModule(itemID) 847 if moduleButton: 848 moduleButton.DeactivateModule() 849 850 def TryActivateFighters(self, sidx, gidx): 851 if gidx != 0: 852 return 853 self.fighterCont.OnF(sidx) 854 855 def GetModuleDefaultEffect(self, sidx, gidx): 856 slot = self.slotsContainer.slotsByOrder.get((gidx, sidx), None) 857 if not slot: 858 return 859 if not slot.sr.module: 860 return 861 if slot.sr.module.state != uiconst.UI_NORMAL: 862 return 863 if slot.sr.module.def_effect is None: 864 return 865 return slot.sr.module.def_effect 866 867 def IsModuleActiveForFKey(self, sidx, gidx): 868 defaultEffect = self.GetModuleDefaultEffect(sidx, gidx) 869 if defaultEffect: 870 return defaultEffect.isActive 871 872 def OnFKeyOverload(self, sidx, gidx): 873 self.slotsContainer.OnFKeyOverload(sidx, gidx) 874 875 def OnReloadAmmo(self): 876 self.slotsContainer.OnReloadAmmo() 877 878 def OnCloseView(self): 879 self.ResetSelf() 880 settings.user.ui.Set('selected_shipuicateg', self.sr.selectedcateg) 881 882 @telemetry.ZONE_METHOD 883 def DoBallsRemove(self, pythonBalls, isRelease): 884 if isRelease: 885 self.UnhookBall() 886 self.jammers = {} 887 return 888 controllerBall = self.controller.GetBall() 889 if controllerBall is not None: 890 for ball, slimItem, terminal in pythonBalls: 891 if ball and ball.id == controllerBall.id: 892 self.UnhookBall() 893 controllerBall = self.controller.GetBall() 894 895 if self.jammers: 896 uthread.new(self.UpdateJammersAfterBallRemoval, [ ball.id for ball, _, _ in pythonBalls if ball ]) 897 if isRelease and self.compass: 898 self.compass.RemoveAll() 899 900 def DoBallRemove(self, ball, slimItem, terminal): 901 if ball is None: 902 return 903 log.LogInfo('DoBallRemove::shipui', ball.id) 904 if self.controller.GetBall() is not None and ball.id == self.controller.GetBall().id: 905 self.UnhookBall() 906 uthread.new(self.UpdateJammersAfterBallRemoval, (ball.id,)) 907 908 def UpdateJammersAfterBallRemoval(self, ballIDs): 909 jams = self.jammers.keys() 910 for jammingType in jams: 911 jam = self.jammers[jammingType] 912 for id in jam.keys(): 913 sourceBallID, moduleID, targetBallID = id 914 if sourceBallID in ballIDs: 915 del self.jammers[jammingType][id] 916 917 def ProcessShipEffect(self, godmaStm, effectState): 918 if effectState.error is not None: 919 uthread.new(prompt_player_fsd_dialog, effectState.error[0], effectState.error[1]) 920 921 def OnJamStart(self, sourceBallID, moduleID, targetBallID, jammingType, startTime, duration): 922 durationInClient = GetDurationInClient(startTime, duration) 923 if durationInClient < 0.0: 924 return 925 if jammingType not in self.jammers: 926 self.jammers[jammingType] = {} 927 jammerID = (sourceBallID, moduleID, targetBallID) 928 self.jammers[jammingType][jammerID] = (blue.os.GetSimTime(), durationInClient) 929 if self.buffBarContainer and targetBallID == session.shipid: 930 self.buffBarContainer.StartTimer(jammingType, jammerID, durationInClient) 931 932 def OnJamEnd(self, sourceBallID, moduleID, targetBallID, jammingType): 933 if jammingType in self.jammers: 934 jammerID = (sourceBallID, moduleID, targetBallID) 935 if jammerID in self.jammers[jammingType]: 936 del self.jammers[jammingType][jammerID] 937 938 def OnShipScanCompleted(self, shipID, capacitorCharge, capacitorCapacity, hardwareList): 939 bp = sm.GetService('michelle').GetBallpark() 940 if not bp: 941 return 942 slimItem = bp.slimItems[shipID] 943 wndName = GetByLabel('UI/Inflight/ScanWindowName', itemName=GetSlimItemName(slimItem), title=GetByLabel('UI/Inflight/ScanResult')) 944 ShipScan.CloseIfOpen(windowID='shipscan', windowInstanceID=shipID) 945 ShipScan.Open(windowID='shipscan', windowInstanceID=shipID, caption=wndName, shipID=shipID, results=(capacitorCharge, capacitorCapacity, hardwareList)) 946 947 def OnCargoScanComplete(self, shipID, cargoList): 948 bp = sm.GetService('michelle').GetBallpark() 949 if not bp: 950 return 951 wnd = CargoScan.Open(windowID='cargoscanner', windowInstanceID=shipID, shipID=shipID, cargoList=cargoList) 952 if wnd: 953 wnd.LoadResult(cargoList) 954 955 def UnhookBall(self): 956 self.controller.InvalidateBall() 957 958 def OnShipChanged(self, *args): 959 self.SetupShip(animate=True) 960 961 @threadutils.Throttled(1.5) 962 def SetupShip(self, animate = False): 963 if self.setupShipTasklet is not None: 964 self.setupShipTasklet.kill() 965 self.setupShipTasklet = uthread.new(self._SetupShip, animate) 966 967 @telemetry.ZONE_METHOD 968 def _SetupShip(self, animate = False): 969 if self.destroyed or self.initing or not self.shipuiReady: 970 return 971 self.initing = True 972 try: 973 while not self.controller.IsLoaded(): 974 blue.synchro.Yield() 975 976 if not sm.GetService('viewState').IsViewActive('planet') and sm.GetService('ui').IsUiVisible(): 977 self.state = uiconst.UI_PICKCHILDREN 978 self.ResetUpdateTasklet() 979 self.sr.rampTimers = {} 980 self.slotsContainer.InitSlots(animate) 981 self.hudButtons.construct_buttons() 982 self.SetButtonState() 983 self.CheckControl() 984 self.UpdateButtonsForShip() 985 self.capacitorContainer.InitCapacitor() 986 self.DrawFighters() 987 self.InitFighters() 988 self.ShowHideFighters() 989 if self.CheckShipHasFighterBay(): 990 self.moduleToggleBtn.display = True 991 else: 992 self.moduleToggleBtn.display = False 993 if self.shipSelectHilight.display: 994 self.shipSelectHilight.display = False 995 blue.pyos.synchro.SleepWallclock(200) 996 except Exception as e: 997 log.LogException(e) 998 finally: 999 self.initing = False 1000 if self.display: 1001 sm.GetService('michelle').DetectAndFixMissingHudModules() 1002 1003 def ResetUpdateTasklet(self): 1004 if self.updateTasklet: 1005 self.updateTasklet.kill() 1006 self.updateTasklet = uthread.new(self.UpdateGauges) 1007 1008 def SetSpeed(self, speedRatio): 1009 self.controller.SetSpeed(speedRatio) 1010 1011 def Hide(self): 1012 self.state = uiconst.UI_HIDDEN 1013 1014 def Show(self): 1015 self.state = uiconst.UI_PICKCHILDREN 1016 1017 def OnMouseEnter(self, *args): 1018 uicore.layer.inflight.HideTargetingCursor() 1019 1020 def GetMenu(self): 1021 return self.controller.GetMenu() 1022 1023 @telemetry.ZONE_FUNCTION 1024 def UpdateGauges(self): 1025 while not self.destroyed: 1026 try: 1027 if self.controller.IsLoaded(): 1028 self.heatGauges.Update() 1029 self.hpGauges.Update() 1030 self.UpdateReadouts() 1031 except Exception as e: 1032 log.LogException(e) 1033 1034 blue.synchro.SleepWallclock(500) 1035 1036 def UpdateReadouts(self): 1037 self.CheckShowReadoutCont() 1038 if self.readoutCont.state != uiconst.UI_HIDDEN: 1039 if settings.user.ui.Get('readoutType', 1): 1040 self.readoutCont.UpdateHpPercentages() 1041 else: 1042 self.readoutCont.UpdateHpAbsolutes() 1043 1044 1045 class BaseSpeedButtonCont(Container): 1046 default_width = 12 1047 default_height = 12 1048 default_state = uiconst.UI_NORMAL 1049 default_texturePath = '' 1050 1051 def ApplyAttributes(self, attributes): 1052 Container.ApplyAttributes(self, attributes) 1053 texturePath = attributes.get('texturePath', self.default_texturePath) 1054 Sprite(parent=self, texturePath=texturePath, align=uiconst.TOALL, state=uiconst.UI_DISABLED) 1055 self.controller = attributes.controller 1056 1057 def OnClick(self, *args): 1058 ui_name = getattr(self, 'uniqueUiName', None) 1059 if ui_name: 1060 self.analyticID = ui_name 1061 log_button_clicked(self) 1062 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1063 self.ExecuteCommand() 1064 1065 def OnMouseEnter(self, *args): 1066 PlaySound(uiconst.SOUND_BUTTON_HOVER) 1067 1068 def ExecuteCommand(self): 1069 pass 1070 1071 1072 class MaxSpeedButton(BaseSpeedButtonCont): 1073 default_name = 'MaxSpeedButton' 1074 default_texturePath = 'res:/UI/Texture/classes/ShipUI/plus.png' 1075 1076 def ExecuteCommand(self): 1077 self.controller.SetMaxSpeed() 1078 1079 def GetHint(self): 1080 return GetByLabel('UI/Inflight/SetFullSpeed', maxSpeed=self.controller.GetSpeedMaxFormatted()) 1081 1082 1083 class StopButton(BaseSpeedButtonCont): 1084 default_name = 'StopButton' 1085 uniqueUiName = pConst.UNIQUE_NAME_STOP_BUTTON 1086 default_texturePath = 'res:/UI/Texture/classes/ShipUI/minus.png' 1087 default_hint = GetByLabel('UI/Inflight/StopTheShip') 1088 1089 def ExecuteCommand(self, *args): 1090 self.controller.StopShip() 1091 1092 1093 class CenterHudContainer(UiHiderMixin, Container): 1094 uniqueUiName = pConst.UNIQUE_NAME_HUD_CENTER 1095 1096 def ApplyAttributes(self, attributes): 1097 super(CenterHudContainer, self).ApplyAttributes(attributes) 1098 1099 def AnimateReveal(self): 1100 PlaySound('onboarding_ui_sfx_play') 1101 self.opacity = 0 1102 self.Show() 1103 animations.BlinkIn(self, startVal=0.2, endVal=1.0, loops=3) 1104 1105 1106 class HudContainer(Container): 1107 default_name = 'hudContainer' 1108 default_width = SHIP_UI_WIDTH 1109 default_height = SHIP_UI_HEIGHT 1110 1111 def set_protobuf_event_context(self, event): 1112 event.set_is_in_ship_hud() 1113 1114 1115 def ResetSetFightersDetachedPos(): 1116 return settings.char.ui.Delete('fightersDetachedPosition') 1117 1118 1119 def GetFightersDetachedPos(): 1120 return settings.char.ui.Get('fightersDetachedPosition', (uicore.desktop.width / 2, uicore.desktop.height / 2 - 60)) 1121 1122 1123 def is_compass_enabled(): 1124 return settings.user.ui.Get('showSensorOverlay', False)