class AbilityIcon(Container): default_width = 48 default_height = 48 default_align = uiconst.TOPLEFT default_state = uiconst.UI_NORMAL tooltipPanelClassInfo = SquadronTooltipModuleWrapper() def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.activeCurve = None self.activationPendingCurve = None self.deactivationCurve = None self.ramp_active = False self.buttonDisabled = False self.shipFighterState = GetShipFighterState() self.crimewatchSvc = sm.GetService('crimewatchSvc') self.innerCont = Container(name='innerCont', parent=self, align=uiconst.TOBOTTOM, height=self.height) self.stateLabel = EveLabelSmall(parent=self.innerCont, align=uiconst.CENTER) self.controller = attributes.controller self.slotID = self.controller.slotID self.fighterID = attributes.fighterID self.fighterTypeID = attributes.fighterTypeID ability = self.GetAbilityInfo() self.abilityNameID = ability.displayNameID iconID = ability.iconID self.abilityIcon = Icon(parent=self.innerCont, align=uiconst.CENTER, width=32, height=32, icon=iconID, state=uiconst.UI_DISABLED) self.hilite = Sprite( parent=self.innerCont, name='hilite', width=44, height=44, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/slotHilite.png', blendMode=trinity.TR2_SBM_ADDX2) self.hilite.display = False bgSprite = Sprite( parent=self.innerCont, align=uiconst.CENTER, width=64, height=64, texturePath= 'res:/UI/Texture/classes/ShipUI/Fighters/slotFighterAbility.png', state=uiconst.UI_DISABLED) self.abilityIcon.SetSize(32, 32) self.DrawQtyCont() self.DrawTimer() self.DrawCoolDownTimer() self.DrawSafetyGlow() self.targetMode = ability.targetMode abilityID = GetAbilityIDForSlot(self.fighterTypeID, self.slotID) effectID = GetDogmaEffectIDForAbilityID(abilityID) self.abilityEffect = cfg.dgmeffects.Get(effectID) self.OnAbilityStatusUpdated(self.fighterID, self.slotID) self.shipFighterState.signalOnAbilityActivationStatusUpdate.connect( self.OnAbilityStatusUpdated) def GetSafetyWarning(self): requiredSafetyLevel = self.GetRequiredSafetyLevel() if self.crimewatchSvc.CheckUnsafe(requiredSafetyLevel): return requiredSafetyLevel else: return None def GetRequiredSafetyLevel(self): requiredSafetyLevel = self.crimewatchSvc.GetRequiredSafetyLevelForEffect( self.abilityEffect) return requiredSafetyLevel def OnMouseEnter(self, *args): self.hilite.display = True requiredSafetyLevel = self.GetSafetyWarning() if requiredSafetyLevel is not None: if requiredSafetyLevel == const.shipSafetyLevelNone: color = crimewatchConst.Colors.Criminal else: color = crimewatchConst.Colors.Suspect self.safetyGlow.color.SetRGBA(*color.GetRGBA()) self.safetyGlow.display = True def OnMouseExit(self, *args): self.hilite.display = False self.safetyGlow.display = False def DrawSafetyGlow(self): self.safetyGlow = Sprite( parent=self.innerCont, name='safetyGlow', width=64, height=64, padding=2, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/slotGlow.png', color=crimewatchConst.Colors.Yellow.GetRGBA()) self.safetyGlow.display = False def DrawTimer(self): self.glow = Sprite( parent=self.innerCont, name='glow', width=64, height=64, padding=2, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/slotGlow.png', color=GLOWCOLOR) self.glow.display = False self.busy = Sprite( parent=self.innerCont, name='busy', width=64, height=64, padding=2, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/slotGlow.png', color=BUSYCOLOR) self.busy.display = False self.ramps = ShipModuleButtonRamps(parent=self.innerCont, idx=0, top=-8) self.ramps.display = False def DrawCoolDownTimer(self): self.coolDownRamps = ShipModuleReactivationTimer(parent=self.innerCont, name='coolDown', idx=-1) self.coolDownRamps.display = False def DrawQtyCont(self): self.quantityParent = Container(parent=self.innerCont, name='quantityParent', pos=(16, 6, 24, 10), align=uiconst.BOTTOMRIGHT, state=uiconst.UI_DISABLED, idx=0) self.chargeCountLabel = Label(text='', parent=self.quantityParent, fontsize=9, letterspace=1, left=3, width=30, state=uiconst.UI_DISABLED) underlay = Sprite( parent=self.quantityParent, align=uiconst.TOALL, state=uiconst.UI_DISABLED, texturePath= 'res:/UI/Texture/classes/ShipUI/slotQuantityUnderlay.png', color=(0, 0, 0, 1)) def GetAbilityInfo(self): ability = self.controller.GetAbilityInfo() return ability def OnAbilityStatusUpdated(self, fighterID, slotID): if fighterID == self.fighterID and slotID == self.slotID: abilityActivationStatus = self.shipFighterState.GetAbilityActivationStatus( self.fighterID, self.slotID) if abilityActivationStatus: if abilityActivationStatus.isPending: self._StartActivationPendingAnimation() else: self._StopActivationPendingAnimation() if abilityActivationStatus.isDeactivating: self._StartDeactivationAnimation() else: self._StopDeactivationAnimation() if not abilityActivationStatus.isPending and not abilityActivationStatus.isDeactivating: self._StartActiveAnimation() self.buttonDisabled = False else: self._StopActiveAnimation() self.buttonDisabled = True if abilityActivationStatus.startTime and abilityActivationStatus.durationMs: self._StartCycleAnimation( abilityActivationStatus.startTime, abilityActivationStatus.durationMs) else: self._StopCycleAnimation() else: self._StopActivationPendingAnimation() self._StopDeactivationAnimation() self._StopActiveAnimation() self._StopCycleAnimation() cooldown = self.shipFighterState.GetAbilityCooldown( self.fighterID, self.slotID) if cooldown is not None: self.buttonDisabled = True uthread.new(self._StartCoolDownAnimation, cooldown) else: self.buttonDisabled = False self._UpdateChargeCountLabel() def _UpdateChargeCountLabel(self): maxChargeCount = GetChargeCountForTypeAndSlot(self.fighterTypeID, self.slotID) if maxChargeCount is not None: currentChargeCount = self.shipFighterState.GetAbilityChargeCount( self.fighterID, self.slotID) self.quantityParent.Show() self.chargeCountLabel.SetText(currentChargeCount) else: self.quantityParent.Hide() def _StartCycleAnimation(self, startTime, durationMs): if self.ramp_active: return uthread.new(self._StartCycleAnimationThread, startTime, durationMs) def _StartCycleAnimationThread(self, startTime, durationMs): duration = durationMs * MSEC self.ramp_active = True self.ramps.display = True self.coolDownRamps.display = False while self.ramp_active: now = blue.os.GetSimTime() portionDone = (now - startTime) / duration if portionDone > 1: iterations = int(portionDone) startTime += long(duration * iterations) portionDone -= iterations self.ramps.SetRampValues(portionDone) blue.pyos.synchro.Yield() def _StopCycleAnimation(self): self.ramp_active = False self.ramps.display = False def _StartCoolDownAnimation(self, cooldown): self.coolDownRamps.display = True startTime, endTime = cooldown coolDownTime = int(endTime - startTime) self.coolDownRamps.AnimateTimer(startTime, coolDownTime) if endTime <= blue.os.GetSimTime(): self.coolDownRamps.display = False self.buttonDisabled = False def _StartActiveAnimation(self): self.glow.display = True self.activeCurve = animations.FadeTo(self.glow, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE) animations.SyncPlayback(self.activeCurve) def _StopActiveAnimation(self): self.glow.display = False if self.activeCurve: self.activeCurve.Stop() self.activeCurve = None def _StartActivationPendingAnimation(self): self.activationPendingCurve = animations.FadeTo( self.abilityIcon, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE) animations.SyncPlayback(self.activationPendingCurve) def _StopActivationPendingAnimation(self): if self.activationPendingCurve: self.activationPendingCurve.Stop() self.activationPendingCurve = None animations.FadeIn(self.abilityIcon) def _StartDeactivationAnimation(self): self.busy.display = True self.deactivationCurve = animations.FadeTo(self.busy, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE) animations.SyncPlayback(self.deactivationCurve) def _StopDeactivationAnimation(self): self.busy.display = False if self.deactivationCurve: self.deactivationCurve.Stop() self.deactivationCurve = None def OnClick(self, *args): if self.buttonDisabled: return self.controller.OnAbilityClick(self.targetMode) def Close(self): self._StopActiveAnimation() self._StopActivationPendingAnimation() self._StopDeactivationAnimation() self.shipFighterState.signalOnAbilityActivationStatusUpdate.disconnect( self.OnAbilityStatusUpdated) super(AbilityIcon, self).Close() def OnMouseDown(self, *args): if self.buttonDisabled: return self.innerCont.top = 2 def OnMouseUp(self, *args): if self.buttonDisabled: return self.innerCont.top = 0
class SquadronsUI(ContainerAutoSize): default_width = SQUADRON_WIDTH default_height = 266 def ApplyAttributes(self, attributes): ContainerAutoSize.ApplyAttributes(self, attributes) self.shipFighterState = GetShipFighterState() self.parentFunc = attributes.parentFunc self.squadrons = [] self.lastSelected = None left = BUTTONCONT_WIDTH + 4 numOfTubes = GetFighterTubesForShip() self.DrawControlButtons() for i, tubeFlagID in enumerate(const.fighterTubeFlags): if i < numOfTubes: squadron = SquadronUI(parent=self, align=uiconst.BOTTOMLEFT, tubeFlagID=tubeFlagID, left=left) left = squadron.left + squadron.width + 6 self.squadrons.append(squadron) self.width += SQUADRON_WIDTH def DrawControlButtons(self): buttonCont = Container(parent=self, align=uiconst.BOTTOMLEFT, width=BUTTONCONT_WIDTH, height=120) self.fighterToggleBtn = FighterDragButton( name='fighterToggleBtn', parent=buttonCont, align=uiconst.BOTTOMLEFT, top=0, left=2, iconSize=24, texturePath= 'res:/UI/Texture/classes/ShipUI/Fighters/positionFighters_Up.png', downTexture= 'res:/UI/Texture/classes/ShipUI/Fighters/positionFighters_Down.png', hoverTexture= 'res:/UI/Texture/classes/ShipUI/Fighters/positionFighters_Over.png', func=self.OnToggleFightersDetached) self.recallAll = FightersButtonRecallAll(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25) self.openFighterBay = self.GetFighterBayBtn(buttonCont) self.launchAll = FightersButtonLaunchAll(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT * 2) def GetFighterBayBtn(self, buttonCont): if session.structureid: return FightersButtonOpenStructureBay(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT) else: return FightersButtonOpenBay(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT) def OnToggleFightersDetached(self, *args): self.parentFunc(args) self.KeepSelection() def KeepSelection(self): selectedFighters = movementFunctions.GetFightersSelectedForNavigation() for fighterID in selectedFighters: movementFunctions.SelectForNavigation(fighterID) def SelectAll(self): for squadron in self.squadrons: squadron.SelectSquadron() def ClearSelection(self): for squadron in self.squadrons: squadron.DeselectSquadron() def GetSelectedSquadrons(self): selectedSquadrons = [] for squadron in self.squadrons: if squadron.IsSelected(): selectedSquadrons.append( SelectedFighterTuple( fighterItemID=squadron.GetFighterItemID(), tubeFlagID=squadron.tubeFlagID, squadron=squadron)) return selectedSquadrons def OnF(self, abilitySlotID): untargetedAbilityFighters = [] itemTargetedAbilityFighters = [] pointTargetedAbilityFighters = [] isAllAbilitiesActive = self.shipFighterState.IsAllAbilitiesInSlotActiveOrInCooldown( abilitySlotID) for squadron in self.GetSelectedSquadrons(): try: ability = squadron.squadron.modulesCont.abilityIcons[ abilitySlotID] except KeyError: continue abilityActivationStatus = self.shipFighterState.GetAbilityActivationStatus( squadron.fighterItemID, abilitySlotID) if isAllAbilitiesActive: if abilityActivationStatus: if abilityActivationStatus.isPending: continue if abilityActivationStatus.isDeactivating: continue else: if abilityActivationStatus: continue if self.shipFighterState.GetAbilityCooldown( squadron.fighterItemID, abilitySlotID): continue if ability.targetMode == TARGET_MODE_UNTARGETED: untargetedAbilityFighters.append(squadron.fighterItemID) elif ability.targetMode == TARGET_MODE_ITEMTARGETED: itemTargetedAbilityFighters.append(squadron.fighterItemID) elif ability.targetMode == TARGET_MODE_POINTTARGETED: pointTargetedAbilityFighters.append(squadron.fighterItemID) fightersSvc = sm.GetService('fighters') if isAllAbilitiesActive: fighterIDs = untargetedAbilityFighters + itemTargetedAbilityFighters + pointTargetedAbilityFighters fightersSvc.DeactivateAbilitySlots(fighterIDs, abilitySlotID) else: if untargetedAbilityFighters: fightersSvc.ActivateAbilitySlotsOnSelf( untargetedAbilityFighters, abilitySlotID) if itemTargetedAbilityFighters: targetID = sm.GetService('target').GetActiveTargetID() fightersSvc.ActivateAbilitySlotsOnTarget( itemTargetedAbilityFighters, abilitySlotID, targetID) if pointTargetedAbilityFighters: eveCommands = sm.GetService('cmd') eveCommands.CmdAimMultiSquadronFighterAbilities( pointTargetedAbilityFighters, abilitySlotID) def SetLastSelectedTube(self, tubeFlagID): self.lastSelected = tubeFlagID def GetLastSelectedTube(self): return self.lastSelected def MultiSelectSquadrons(self, selectedSquadron): if selectedSquadron <= self.lastSelected: minSelected = selectedSquadron maxSelected = self.lastSelected else: minSelected = self.lastSelected maxSelected = selectedSquadron for squadron in self.squadrons: if squadron.tubeFlagID >= minSelected and squadron.tubeFlagID <= maxSelected: squadron.SelectSquadron()