Пример #1
0
class SquadronController(object):
    def __init__(self):
        self.shipFighterState = GetShipFighterState()
        self.michelle = sm.GetService('michelle')

    def GetSquadronVelocity(self, tubeFlagID):
        ball = self.GetSquadronBallInfo(tubeFlagID)
        if ball:
            velocity = ball.GetVectorDotAt(self.GetTimeNow()).Length()
            return velocity

    def GetSquadronDistance(self, tubeFlagID):
        ball = self.GetSquadronBallInfo(tubeFlagID)
        if ball:
            ball.GetVectorAt(self.GetTimeNow())
            return ball.surfaceDist

    def GetSquadronBallInfo(self, tubeFlagID):
        fightersItemID = self.GetFightersInSpaceItemID(tubeFlagID)
        if fightersItemID:
            ball = self.GetFightersBall(fightersItemID)
            return ball

    def GetFightersBall(self, fightersItemID):
        return self.michelle.GetBall(fightersItemID)

    def GetTimeNow(self):
        return gametime.GetSimTime()

    def GetFightersInSpaceItemID(self, tubeFlagID):
        fightersInSpace = self.shipFighterState.GetFightersInSpace(tubeFlagID)
        if fightersInSpace:
            return fightersInSpace.itemID

    def GetIsInSpace(self, tubeFlagID):
        fightersInSpace = self.shipFighterState.GetFightersInSpace(tubeFlagID)
        if fightersInSpace:
            return True
        return False

    def GetSquadronAction(self, tubeFlagID):
        tubeStatus = self.shipFighterState.GetTubeStatus(tubeFlagID)
        stateText = LABEL_BY_STATE[tubeStatus.statusID]
        if session.stationid2:
            stateColor = Color(*COLOR_OPEN)
        else:
            stateColor = Color(*COLOR_BY_STATE[tubeStatus.statusID])
        stateColor.a = 0.8
        return (stateText, stateColor)

    def GetAbilities(self, fighterTypeID):
        if fighterTypeID:
            abilities = fighters.IterTypeAbilities(fighterTypeID)
            return abilities

    def GetIncomingEwarEffects(self, fighterID):
        return self.shipFighterState.GetIncomingFighterEwar(fighterID)

    def GetSquadronHealth(self):
        return (12, 1, 4)
Пример #2
0
class FighterInvCont(invCont._InvContBase):
    __guid__ = 'invCont.FighterInvCont'
    __invControllerClass__ = None
    __notifyevents__ = invCont._InvContBase.__notifyevents__ + [
        'ProcessActiveShipChanged'
    ]

    def ApplyAttributes(self, attributes):
        self.squadrons = []
        invCont._InvContBase.ApplyAttributes(self, attributes)

    def ConstructUI(self):
        if self.IsCurrentShip():
            self.ConstructFighterManagementUI()
        invCont._InvContBase.ConstructUI(self)

    def ConstructFighterManagementUI(self):
        self.shipFighterState = GetShipFighterState()
        topCont = Container(parent=self, align=uiconst.TOTOP, height=216)
        inSpace = Container(parent=topCont, align=uiconst.TOTOP, height=20)
        self.lightSquadrons = SquadronLightContainer(parent=inSpace)
        self.supportSquadrons = SquadronSupportContainer(parent=inSpace)
        self.heavySquadrons = SquadronHeavyContainer(parent=inSpace)
        self.squadronsCont = Container(parent=topCont, align=uiconst.TOALL)
        self.numOfTubes = GetFighterTubesForShip()
        self.ConstructSquadrons()
        self.ConstructSquadronTypes()
        self.UpdateSquadronTypes()
        self.GetTypeIDs()
        self.shipFighterState.signalOnFighterTubeStateUpdate.connect(
            self.OnFighterTubeStateUpdate)

    def _OnClose(self, *args):
        if self.IsCurrentShip():
            self.shipFighterState.signalOnFighterTubeStateUpdate.disconnect(
                self.OnFighterTubeStateUpdate)
        invCont._InvContBase._OnClose(self, args)

    def IsCurrentShip(self):
        return self.itemID == session.shipid

    def ConstructSquadrons(self):
        for i, tubeFlagID in enumerate(const.fighterTubeFlags):
            if i < self.numOfTubes:
                squadron = FighterLaunchControlCont(parent=self.squadronsCont,
                                                    tubeFlagID=tubeFlagID,
                                                    left=2)
                self.squadrons.append(squadron)

    def ConstructSquadronTypes(self):
        light, support, heavy = GetLightSupportHeavySlotsForShip()
        if heavy:
            self.heavySquadrons.SetTotalSlots(heavy)
        else:
            self.heavySquadrons.display = False
        if support:
            self.supportSquadrons.SetTotalSlots(support)
        else:
            self.supportSquadrons.display = False
        if light:
            self.lightSquadrons.SetTotalSlots(light)
        else:
            self.lightSquadrons.display = False

    def OnFighterTubeStateUpdate(self, *args):
        self.UpdateSquadronTypes()

    def UpdateSquadronTypes(self):
        heavy, support, light = self.GetSquadronTypes()
        self.heavySquadrons.SetUsedSlots(heavy)
        self.supportSquadrons.SetUsedSlots(support)
        self.lightSquadrons.SetUsedSlots(light)

    def GetSquadronTypes(self):
        heavy = 0
        support = 0
        light = 0
        typeIDs = self.GetTypeIDs()
        for typeID in typeIDs:
            if SquadronIsHeavy(typeID):
                heavy += 1
            elif SquadronIsSupport(typeID):
                support += 1
            elif SquadronIsLight(typeID):
                light += 1

        return (heavy, support, light)

    def GetTypeIDs(self):
        squadronTypeIDs = []
        for i, tubeFlagID in enumerate(const.fighterTubeFlags):
            if i < self.numOfTubes:
                fighterInTube = self.shipFighterState.GetFightersInTube(
                    tubeFlagID)
                if fighterInTube is not None:
                    squadronTypeIDs.append(fighterInTube.typeID)
                fighterInSpace = self.shipFighterState.GetFightersInSpace(
                    tubeFlagID)
                if fighterInSpace is not None:
                    squadronTypeIDs.append(fighterInSpace.typeID)

        return squadronTypeIDs

    def ProcessActiveShipChanged(self, shipID, oldShipID):
        self.Flush()
        self.ConstructUI()
Пример #3
0
class SquadronUI(Container):
    __notifyevents__ = ['OnStateChange']
    default_width = SQUADRON_WIDTH
    default_height = 266
    default_name = 'squadronCont'

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        sm.RegisterNotify(self)
        self.squadronMgmtController = SquadronMgmtController()
        self.inSpace = False
        self.shipFighterState = GetShipFighterState()
        self.tubeFlagID = attributes.tubeFlagID
        fighters = self.GetFightersState()
        if fighters:
            fighterID = fighters.itemID
            fighterTypeID = fighters.typeID
            squadronSize = fighters.squadronSize
        else:
            fighterID = None
            fighterTypeID = None
            squadronSize = None
        self.fighterID = fighterID
        self.fighterTypeID = fighterTypeID
        self.controller = SquadronController()
        self.squadronCont = SquadronCont(parent=self,
                                         controller=self.controller,
                                         align=uiconst.BOTTOMLEFT,
                                         tubeFlagID=self.tubeFlagID,
                                         state=uiconst.UI_NORMAL)
        self.squadronCont.OnClick = self.OnSquadronClick
        self.squadronCont.GetMenu = self.GetSquadronMenu
        self.squadronCont.SetNewSquadron(fighterID, fighterTypeID,
                                         squadronSize)
        self.squadronContEmpty = SquadronContEmpty(parent=self,
                                                   controller=self.controller,
                                                   fighterID=fighterID,
                                                   fighterTypeID=fighterTypeID,
                                                   align=uiconst.BOTTOMLEFT,
                                                   tubeFlagID=self.tubeFlagID)
        self.squadronContEmpty.GetMenu = self.GetSquadronMenu
        if not fighterID and not fighterTypeID:
            self.ShowEmpty()
        else:
            self.HideEmpty()
        self.effectsCont = EffectsCont(parent=self,
                                       controller=self.controller,
                                       fighterID=fighterID,
                                       fighterTypeID=fighterTypeID,
                                       tubeFlagID=self.tubeFlagID,
                                       top=self.squadronCont.height,
                                       align=uiconst.BOTTOMLEFT)
        self.modulesCont = AbilitiesCont(parent=self,
                                         left=20,
                                         top=self.squadronCont.height,
                                         align=uiconst.BOTTOMLEFT)
        self.modulesCont.SetNewSquadron(fighterID, fighterTypeID)
        self.SetupFighters()
        self.shipFighterState.signalOnFighterTubeStateUpdate.connect(
            self.OnFighterTubeStateUpdate)
        self.shipFighterState.signalOnFighterTubeContentUpdate.connect(
            self.OnFighterTubeContentUpdate)
        self.shipFighterState.signalOnFighterInSpaceUpdate.connect(
            self.OnFighterInSpaceUpdate)
        self.shipFighterState.signalOnIncomingEwarStarted.connect(
            self.OnEwarUpdated)
        self.shipFighterState.signalOnIncomingEwarEnded.connect(
            self.OnEwarUpdated)

    def SetupFighters(self):
        if self.inSpace:
            self.ShowInSpaceUI()
        else:
            self.HideInSpaceUI()

    def ShowInSpaceUI(self):
        self.modulesCont.ShowModules()
        self.effectsCont.ShowEffects()

    def HideInSpaceUI(self):
        self.modulesCont.HideModules()
        self.effectsCont.HideEffects()

    def ShowEmpty(self):
        self.squadronContEmpty.display = True
        self.squadronCont.display = False

    def HideEmpty(self):
        self.squadronContEmpty.display = False
        self.squadronCont.display = True

    def GetFightersInSpaceState(self):
        fighterInSpace = self.shipFighterState.GetFightersInSpace(
            self.tubeFlagID)
        if fighterInSpace is not None:
            self.inSpace = True
            return fighterInSpace

    def GetFightersInTubeState(self):
        fighterInTube = self.shipFighterState.GetFightersInTube(
            self.tubeFlagID)
        if fighterInTube is not None:
            self.inSpace = False
            return fighterInTube

    def GetFightersState(self):
        fightersInTube = self.GetFightersInTubeState()
        if fightersInTube:
            return fightersInTube
        fightersInSpace = self.GetFightersInSpaceState()
        if fightersInSpace:
            return fightersInSpace

    def OnEwarUpdated(self, targetBallID, sourceBallID, sourceModuleID,
                      jammingType):
        if targetBallID != self.fighterID:
            return
        self.effectsCont.BuildEffectsData()

    def OnFighterTubeStateUpdate(self, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
            self.squadronCont.SetSquadronAction(self.tubeFlagID)
            if tubeStatus.statusID == TUBE_STATE_EMPTY:
                self.ShowEmpty()
            else:
                self.HideEmpty()
                if tubeStatus.endTime:
                    self.squadronCont.loadingGauge.display = True
                    now = gametime.GetSimTime()
                    duration = float(tubeStatus.endTime - tubeStatus.startTime)
                    loadingProgress = max(
                        0.0, min(1.0, (now - tubeStatus.startTime) / duration))
                    self.squadronCont.loadingGauge.SetValue(loadingProgress,
                                                            animate=False)
                    remainingTime = tubeStatus.endTime - now
                    remainingTimeSeconds = max(float(remainingTime) / SEC, 0.1)
                    self.squadronCont.loadingGauge.SetValueTimed(
                        1.0, remainingTimeSeconds)
                else:
                    self.squadronCont.loadingGauge.display = False

    def OnFighterTubeContentUpdate(self, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
            if tubeStatus.statusID in (TUBE_STATE_EMPTY, TUBE_STATE_READY,
                                       TUBE_STATE_UNLOADING):
                self.ShowEmpty()
                self.squadronCont.ClearFighters()
            else:
                self.HideEmpty()
                fightersInTube = self.GetFightersInTubeState()
                if fightersInTube:
                    self.squadronCont.SetNewSquadron(
                        fightersInTube.itemID, fightersInTube.typeID,
                        fightersInTube.squadronSize)
                    self.fighterID = fightersInTube.itemID
                    self.fighterTypeID = fightersInTube.typeID
                    self.effectsCont.UpdateFighterID(self.fighterID)

    def OnFighterInSpaceUpdate(self, fighterID, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            fightersInSpace = self.GetFightersInSpaceState()
            if fightersInSpace:
                self.squadronCont.SetNewSquadron(fightersInSpace.itemID,
                                                 fightersInSpace.typeID,
                                                 fightersInSpace.squadronSize)
                self.modulesCont.SetNewSquadron(fightersInSpace.itemID,
                                                fightersInSpace.typeID)
                self.squadronCont.SetSquadronInfo(tubeFlagID)
                self.ShowInSpaceUI()
            else:
                self.squadronCont.StopSquadronTimer()
                self.HideInSpaceUI()

    def Close(self):
        self.shipFighterState.signalOnFighterTubeStateUpdate.disconnect(
            self.OnFighterTubeStateUpdate)
        self.shipFighterState.signalOnFighterTubeContentUpdate.disconnect(
            self.OnFighterTubeContentUpdate)
        self.shipFighterState.signalOnFighterInSpaceUpdate.disconnect(
            self.OnFighterInSpaceUpdate)
        self.shipFighterState.signalOnIncomingEwarStarted.disconnect(
            self.OnEwarUpdated)
        self.shipFighterState.signalOnIncomingEwarEnded.disconnect(
            self.OnEwarUpdated)
        self.squadronCont.damageTimer = None
        Container.Close(self)

    def OnSquadronClick(self, *args):
        ctrl = uicore.uilib.Key(uiconst.VK_CONTROL)
        shift = uicore.uilib.Key(uiconst.VK_SHIFT)
        if not ctrl and not shift and uicore.cmd.IsSomeCombatCommandLoaded():
            uicore.cmd.ExecuteCombatCommand(self.fighterID, uiconst.UI_CLICK)
        elif shift:
            if self.parent.GetLastSelectedTube():
                self.parent.MultiSelectSquadrons(self.tubeFlagID)
                self.parent.SetLastSelectedTube(self.tubeFlagID)
        elif ctrl:
            if movementFunctions.IsSelectedForNavigation(self.fighterID):
                self.DeselectSquadron()
            else:
                self.SelectSquadron()
                self.parent.SetLastSelectedTube(self.tubeFlagID)
        else:
            self.parent.ClearSelection()
            if movementFunctions.IsSelectedForNavigation(session.shipid):
                movementFunctions.DeselectForNavigation(session.shipid)
            self.SelectSquadron()
            self.parent.SetLastSelectedTube(self.tubeFlagID)

    def IsSelected(self):
        if self.shipFighterState.GetFightersInSpace(self.tubeFlagID) is None:
            return False
        return movementFunctions.IsSelectedForNavigation(self.fighterID)

    def OnStateChange(self, itemID, flag, flagState, *args):
        if flag == states.selectedForNavigation and itemID == self.fighterID:
            if flagState:
                self.squadronCont.ShowSelectionHilite()
            else:
                self.squadronCont.HideSelectionHilite()

    def SelectSquadron(self):
        movementFunctions.SelectForNavigation(self.fighterID)

    def DeselectSquadron(self):
        movementFunctions.DeselectForNavigation(self.fighterID)

    def GetFighterItemID(self):
        return self.squadronCont.GetFighterItemID()

    def GetSquadronMenu(self):
        m = []
        ship = sm.GetService('godma').GetItem(session.shipid)
        if ship is None:
            return m
        tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
        if tubeStatus.statusID == TUBE_STATE_EMPTY:
            m += self._GetSquadronMenuForEmptyTube()
            return m
        if self.GetFightersInSpaceState():
            m.append((MenuLabel('UI/Inventory/Fighters/RecallToLaunchTube'),
                      self.RecallFighterToTube))
            m.append((MenuLabel('UI/Drones/ReturnDroneAndOrbit'),
                      self.ReturnAndOrbit))
            m.append(
                (MenuLabel('UI/Fighters/AbandonFighter'), self.AbandonFighter))
        elif self.GetFightersInTubeState():
            m.append((MenuLabel('UI/Inventory/Fighters/LaunchToSpace'),
                      self.LaunchFightersFromTube))
            m.append((MenuLabel('UI/Inventory/Fighters/UnloadFromLaunchTube'),
                      self.UnloadTubeToFighterBay))
        m += sm.GetService('menu').CelestialMenu(self.fighterID,
                                                 typeID=self.fighterTypeID)
        return m

    def _GetSquadronMenuForEmptyTube(self):
        HEAVY = 0
        LIGHT = 1
        SUPPORT = 2
        OTHER = 3
        m = []
        fightersInBay = sm.GetService('invCache').GetInventoryFromId(
            session.shipid).ListFighterBay()
        optionsByClass = defaultdict(list)
        for fighter in fightersInBay:
            typeID = fighter.typeID
            if SquadronIsHeavy(typeID):
                fighterClass = HEAVY
            elif SquadronIsLight(typeID):
                fighterClass = LIGHT
            elif SquadronIsSupport(typeID):
                fighterClass = SUPPORT
            else:
                fighterClass = OTHER
            fighterLabel = GetByLabel(
                'UI/Inflight/Drone/DroneBayEntryWithStacksize',
                drone=fighter.typeID,
                stacksize=fighter.stacksize)
            optionsByClass[fighterClass].append(
                (fighterLabel, self.LoadFighterToTube, (fighter.itemID, )))

        for fighterClass in (HEAVY, LIGHT, SUPPORT, OTHER):
            options = optionsByClass.get(fighterClass, [])
            if not options:
                continue
            sortedOptions = sorted(options, key=lambda x: x[0])
            m += sortedOptions
            m += [None]

        return m

    def RecallFighterToTube(self):
        self.squadronMgmtController.RecallFighterToTube(self.fighterID)

    def LoadFighterToTube(self, fighterID):
        self.squadronMgmtController.LoadFightersToTube(fighterID,
                                                       self.tubeFlagID)

    def UnloadTubeToFighterBay(self):
        self.squadronMgmtController.UnloadTubeToFighterBay(self.tubeFlagID)

    def LaunchFightersFromTube(self):
        self.squadronMgmtController.LaunchFightersFromTube(self.tubeFlagID)

    def AbandonFighter(self):
        sm.GetService('fighters').AbandonFighter(self.fighterID)

    def ReturnAndOrbit(self):
        sm.GetService('fighters').CmdReturnAndOrbit([self.fighterID])
Пример #4
0
class FighterLaunchControlCont(Container):
    default_height = 196
    default_width = 86
    default_align = uiconst.TOLEFT

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        self.controller = SquadronMgmtController()
        self.shipFighterState = GetShipFighterState()
        self.tubeFlagID = attributes.tubeFlagID
        self.leftTube = Sprite(
            parent=self,
            texturePath=
            'res:/UI/Texture/classes/CarrierBay/tubeSideElement.png',
            align=uiconst.TOLEFT_NOPUSH,
            width=15)
        self.rightTube = Sprite(
            parent=self,
            texturePath=
            'res:/UI/Texture/classes/CarrierBay/tubeSideElementRIGHT.png',
            align=uiconst.TORIGHT_NOPUSH,
            width=15)
        inSpaceCont = Container(parent=self, height=86, align=uiconst.TOTOP)
        inSpaceCont.OnDropData = self.OnDropToSpace
        inSpaceCont.GetMenu = self.GetMenu
        self.squadronNumber = SquadronNumber(parent=inSpaceCont, top=1, left=1)
        self.squadronNumber.SetText(self.tubeFlagID)
        self.inStationCont = Container(parent=inSpaceCont, align=uiconst.TOALL)
        cantLaunchIcon = Sprite(
            parent=self.inStationCont,
            width=44,
            height=44,
            align=uiconst.CENTER,
            texturePath='res:/UI/Texture/classes/CarrierBay/unableToLaunch.png'
        )
        self.stateCont = Container(parent=self,
                                   height=24,
                                   align=uiconst.TOTOP,
                                   state=uiconst.UI_NORMAL)
        self.stateContBG = Fill(bgParent=self.stateCont, color=(0, 0, 0, 0))
        deckCont = Container(parent=self,
                             height=86,
                             align=uiconst.TOTOP,
                             state=uiconst.UI_NORMAL)
        deckCont.OnDropData = self.OnDropToTube
        deckCont.GetMenu = self.GetMenu
        self.tubeStatusLabel = EveHeaderSmall(parent=self.stateCont,
                                              align=uiconst.CENTER,
                                              text='')
        self.loadingGauge = Gauge(parent=self.stateCont,
                                  align=uiconst.CENTERBOTTOM,
                                  backgroundColor=(0, 0, 0, 1),
                                  color=(0.2, 0.2, 0.2, 0.5),
                                  padLeft=1,
                                  padRight=1,
                                  top=1,
                                  width=75,
                                  value=0.0)
        self.loadingGauge.display = False
        spaceColor = Color(*COLOR_INSPACE)
        spaceColor.a = 1.0
        self.launchIcon = ButtonIcon(
            parent=inSpaceCont,
            align=uiconst.CENTER,
            width=86,
            height=86,
            iconSize=44,
            texturePath='res:/UI/Texture/classes/CarrierBay/tubeLaunch_Up.png',
            downTexture=
            'res:/UI/Texture/classes/CarrierBay/tubeLaunch_Down.png',
            hoverTexture=
            'res:/UI/Texture/classes/CarrierBay/tubeLaunch_Over.png',
            iconColor=spaceColor.GetRGBA(),
            showGlow=False)
        self.launchIcon.OnClick = self.LaunchFightersFromTube
        self.launchIcon.OnDropData = self.OnDropToSpace
        returnColor = Color(*COLOR_RETURNING)
        returnColor.a = 1.0
        self.scoopIcon = ButtonIcon(
            parent=deckCont,
            align=uiconst.CENTER,
            width=86,
            height=86,
            iconSize=44,
            texturePath='res:/UI/Texture/classes/CarrierBay/tubeRecall_Up.png',
            downTexture=
            'res:/UI/Texture/classes/CarrierBay/tubeRecall_Down.png',
            hoverTexture=
            'res:/UI/Texture/classes/CarrierBay/tubeRecall_Over.png',
            iconColor=returnColor.GetRGBA(),
            showGlow=False)
        self.scoopIcon.OnClick = self.RecallFighterToTube
        self.scoopIcon.OnDropData = self.OnDropToTube
        self.landingStrip = LandingStrip(parent=deckCont)
        self.landingStrip.display = False
        self.emptyTubeIcon = ButtonIcon(
            parent=deckCont,
            align=uiconst.CENTER,
            width=44,
            height=44,
            iconSize=44,
            texturePath='res:/UI/Texture/classes/CarrierBay/tubeOpen_Up.png',
            downTexture='res:/UI/Texture/classes/CarrierBay/tubeOpen_Down.png',
            hoverTexture='res:/UI/Texture/classes/CarrierBay/tubeOpen_Over.png',
            showGlow=False)
        self.emptyTubeIcon.OnDropData = self.OnDropToTube
        self.squadronInSpace = FightersHealthGauge(name='squadronInSpace',
                                                   parent=inSpaceCont,
                                                   align=uiconst.CENTER,
                                                   width=86,
                                                   height=86,
                                                   state=TUBE_STATE_INSPACE,
                                                   tubeFlagID=self.tubeFlagID)
        self.squadronInSpace.display = False
        self.squadronInSpace.GetMenu = self.GetMenu
        self.squadronInTube = FightersHealthGauge(name='squadronInTube',
                                                  parent=deckCont,
                                                  align=uiconst.CENTER,
                                                  width=86,
                                                  height=86,
                                                  state=TUBE_STATE_READY,
                                                  tubeFlagID=self.tubeFlagID)
        self.squadronInTube.OnDropData = self.OnDropToTube
        self.squadronInTube.display = False
        self.squadronInTube.GetMenu = self.GetMenu
        self.launchingStrip = LaunchingStrip(parent=inSpaceCont)
        self.launchingStrip.display = False
        self.UpdateLaunchTubeContentUI()
        self.UpdateLaunchTubeStateUI()
        self.UpdateInSpaceUI()
        self.shipFighterState.signalOnFighterTubeStateUpdate.connect(
            self.OnFighterTubeStateUpdate)
        self.shipFighterState.signalOnFighterTubeContentUpdate.connect(
            self.OnFighterTubeContentUpdate)
        self.shipFighterState.signalOnFighterInSpaceUpdate.connect(
            self.OnFighterInSpaceUpdate)

    def Close(self):
        self.shipFighterState.signalOnFighterTubeStateUpdate.disconnect(
            self.OnFighterTubeStateUpdate)
        self.shipFighterState.signalOnFighterTubeContentUpdate.disconnect(
            self.OnFighterTubeContentUpdate)
        self.shipFighterState.signalOnFighterInSpaceUpdate.disconnect(
            self.OnFighterInSpaceUpdate)

    def LaunchFightersFromTube(self):
        self.controller.LaunchFightersFromTube(self.tubeFlagID)

    def RecallFighterToTube(self):
        fighterInSpace = self.shipFighterState.GetFightersInSpace(
            self.tubeFlagID)
        self.controller.RecallFighterToTube(fighterInSpace.itemID)

    def ReturnAndOrbit(self):
        fighterInSpace = self.shipFighterState.GetFightersInSpace(
            self.tubeFlagID)
        sm.GetService('fighters').CmdReturnAndOrbit([fighterInSpace.itemID])

    def OnDropToSpace(self, dragSource, dragData):
        data = dragData[0]
        if data.tubeFlagID == self.tubeFlagID and data.squadronState == TUBE_STATE_READY:
            self.LaunchFightersFromTube()

    def OnDropToTube(self, dragSource, dragData):
        data = dragData[0]
        if data.__guid__ == 'uicls.FightersHealthGauge':
            if data.tubeFlagID == self.tubeFlagID and data.squadronState == TUBE_STATE_INSPACE:
                self.RecallFighterToTube()
        elif data.__guid__ in ('xtriui.InvItem', 'listentry.InvItem'):
            tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
            if tubeStatus.statusID in (TUBE_STATE_EMPTY, TUBE_STATE_READY):
                fighterID = data.itemID
                self.controller.LoadFightersToTube(fighterID, self.tubeFlagID)

    def UnloadTubeToFighterBay(self):
        self.controller.UnloadTubeToFighterBay(self.tubeFlagID)

    def UpdateLaunchTubeContentUI(self):
        fighterInTube = self.shipFighterState.GetFightersInTube(
            self.tubeFlagID)
        if fighterInTube is not None:
            self.squadronInTube.display = True
            if not self.ShouldShowStationUI():
                self.launchIcon.display = True
            self.scoopIcon.display = False
            self.landingStrip.display = False
            self.squadronInTube.LoadFighterToSquadron(fighterInTube.typeID)
            self.squadronInTube.SetSquadronSize(fighterInTube.squadronSize)
        else:
            self.squadronInTube.display = False
            self.launchIcon.display = False

    def ShowStationUI(self):
        self.inStationCont.display = True
        self.launchIcon.display = False

    def UpdateLaunchTubeStateUI(self):
        tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
        self.UpdateStatusUI(tubeStatus)
        if tubeStatus.endTime:
            if tubeStatus.statusID in (TUBE_STATE_RECALLING,
                                       TUBE_STATE_LANDING):
                self.landingStrip.display = True
                self.scoopIcon.display = False
            elif tubeStatus.statusID == TUBE_STATE_LAUNCHING:
                self.launchingStrip.display = True
                self.launchIcon.display = False
            else:
                self.loadingGauge.display = True
                now = gametime.GetSimTime()
                duration = float(tubeStatus.endTime - tubeStatus.startTime)
                loadingProgress = max(
                    0.0, min(1.0, (now - tubeStatus.startTime) / duration))
                self.loadingGauge.SetValue(loadingProgress, animate=False)
                remainingTime = tubeStatus.endTime - now
                remainingTimeSeconds = max(float(remainingTime) / SEC, 0.1)
                self.loadingGauge.SetValueTimed(1.0, remainingTimeSeconds)
                self.tubeStatusLabel.top = -2
        else:
            self.loadingGauge.SetValue(0)
            self.loadingGauge.display = False
            self.landingStrip.display = False
            self.launchingStrip.display = False
            self.tubeStatusLabel.top = 0
        if tubeStatus.statusID == TUBE_STATE_EMPTY:
            self.emptyTubeIcon.display = True
            self.scoopIcon.display = False
            self.squadronNumber.SetColor(True)
        else:
            self.emptyTubeIcon.display = False
            self.squadronNumber.SetColor(False)

    def UpdateStatusUI(self, tubeStatus):
        stateText = LABEL_BY_STATE[tubeStatus.statusID]
        self.tubeStatusLabel.text = GetByLabel(stateText)
        if self.ShouldShowStationUI():
            stateColor = Color(*COLOR_OPEN)
        else:
            stateColor = Color(*COLOR_BY_STATE[tubeStatus.statusID])
        self.leftTube.SetRGBA(*stateColor.GetRGBA())
        self.rightTube.SetRGBA(*stateColor.GetRGBA())
        stateColor.a = 0.8
        self.tubeStatusLabel.SetTextColor(stateColor.GetRGBA())

    def UpdateInSpaceUI(self):
        if self.ShouldShowStationUI():
            self.ShowStationUI()
            return
        self.inStationCont.display = False
        fighterInSpace = self.shipFighterState.GetFightersInSpace(
            self.tubeFlagID)
        if fighterInSpace is not None:
            self.scoopIcon.display = True
            self.squadronInSpace.display = True
            self.squadronInSpace.LoadFighterToSquadron(fighterInSpace.typeID)
            self.squadronInSpace.SetSquadronSize(fighterInSpace.squadronSize)
        else:
            self.scoopIcon.display = False
            self.squadronInSpace.display = False

    def GetMenu(self):
        m = []
        fighterInTube = self.shipFighterState.GetFightersInTube(
            self.tubeFlagID)
        if fighterInTube is not None:
            if not session.stationid2:
                m.append((MenuLabel('UI/Inventory/Fighters/LaunchToSpace'),
                          self.LaunchFightersFromTube))
            m.append((MenuLabel('UI/Inventory/Fighters/UnloadFromLaunchTube'),
                      self.UnloadTubeToFighterBay))
            m.append((MenuLabel('UI/Commands/ShowInfo'),
                      sm.GetService('menu').ShowInfo, (fighterInTube.typeID,
                                                       fighterInTube.itemID)))
        fighterInSpace = self.shipFighterState.GetFightersInSpace(
            self.tubeFlagID)
        if fighterInSpace is not None:
            m.append((MenuLabel('UI/Inventory/Fighters/RecallToLaunchTube'),
                      self.RecallFighterToTube))
            m.append((MenuLabel('UI/Drones/ReturnDroneAndOrbit'),
                      self.ReturnAndOrbit))
            m.append((MenuLabel('UI/Commands/ShowInfo'),
                      sm.GetService('menu').ShowInfo, (fighterInSpace.typeID,
                                                       fighterInSpace.itemID)))
        return m

    def OnFighterTubeStateUpdate(self, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            self.UpdateLaunchTubeStateUI()

    def OnFighterTubeContentUpdate(self, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            self.UpdateLaunchTubeContentUI()

    def OnFighterInSpaceUpdate(self, fighterID, tubeFlagID):
        if tubeFlagID == self.tubeFlagID:
            self.UpdateInSpaceUI()

    def ShouldShowStationUI(self):
        return session.stationid2