fightersSvc.py (11741B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\fightersSvc.py 2 import dogma.data as dogma_data 3 from carbon.common.script.sys.service import Service 4 from eve.client.script.parklife import states 5 from eve.client.script.ui.inflight.squadrons.fighterDebugWindow import FighterDebugWindow 6 from eve.client.script.ui.services.menuSvcExtras import movementFunctions 7 from eve.common.script.sys import idCheckers 8 from eve.common.script.util.systemExclusions import IsStarterSystem 9 import localization 10 from carbonui.control.message import QuickMessage 11 from eveexceptions import UserError 12 from fighters.abilityAttributes import GetDogmaEffectIDForAbilityID 13 from carbonui.const import YESNO, ID_YES 14 from eve.client.script.ui.inflight.squadrons.shipFighterState import ShipFighterState 15 from eve.common.script.mgt import fighterConst 16 from eve.common.script.mgt.fighterConst import TUBE_STATE_RECALLING, TUBE_STATE_INSPACE, TUBE_STATE_READY 17 import evetypes 18 from fighters import GetAbilityIDForSlot, GetAbilityNameIDForSlot, DEFAULT_CONTROLLER_ORBIT_DISTANCE 19 from inventorycommon.const import categoryFighter 20 import carbonui.const as uiconst 21 from carbonui.uicore import uicore 22 from player_messaging.client.ui_message import prompt_player_fsd_dialog 23 24 class FightersSvc(Service): 25 __dependencies__ = ['michelle', 'consider', 'crimewatchSvc'] 26 __guid__ = 'svc.fighters' 27 __servicename__ = 'fighters' 28 __displayname__ = 'Fighters service' 29 __notifyevents__ = ['OnStateChange'] 30 shipFighterState = None 31 32 def Run(self, memStream = None): 33 self.LogInfo('Starting fighters service') 34 self.shipFighterState = ShipFighterState(self) 35 36 def ShowDebugWindow(self): 37 wnd = FighterDebugWindow.GetIfOpen() 38 if wnd: 39 wnd.Maximize() 40 else: 41 FighterDebugWindow.Open() 42 43 def FightersMenu(self): 44 45 def SpawnFighterInBay(fighterTypeID): 46 self.LogInfo('Spawning fighter via /fit', fighterTypeID, evetypes.GetEnglishName(fighterTypeID)) 47 sm.RemoteSvc('slash').SlashCmd('/fit me %d %d' % (fighterTypeID, 1)) 48 49 groupMenu = [] 50 for fighterGroupID in evetypes.GetGroupIDsByCategory(categoryFighter): 51 groupName = evetypes.GetGroupNameByGroup(fighterGroupID) 52 typeMenu = [] 53 for fighterTypeID in evetypes.GetTypeIDsByGroup(fighterGroupID): 54 fighterName = evetypes.GetEnglishName(fighterTypeID) 55 typeMenu.append((fighterName, SpawnFighterInBay, (fighterTypeID,))) 56 57 typeMenu.sort() 58 groupMenu.append((groupName, typeMenu)) 59 60 groupMenu.sort() 61 return [('NEW FIGHTERS', groupMenu)] 62 63 def CmdReturnAndOrbit(self, fighterIDs): 64 self.CmdMovementOrbit(fighterIDs, session.shipid, DEFAULT_CONTROLLER_ORBIT_DISTANCE) 65 66 def CmdMovementOrbit(self, fighterIDs, targetID, followRange): 67 self._ExecuteMovementCommandOnFighters(fighterConst.MOVEMENT_COMMAND_ORBIT, fighterIDs, targetID, followRange) 68 69 def CmdMovementFollow(self, fighterIDs, targetID, followRange): 70 self._ExecuteMovementCommandOnFighters(fighterConst.MOVEMENT_COMMAND_FOLLOW, fighterIDs, targetID, followRange) 71 72 def CmdMovementStop(self, fighterIDs): 73 self._ExecuteMovementCommandOnFighters(fighterConst.MOVEMENT_COMMAND_STOP, fighterIDs) 74 75 def CmdGotoPoint(self, fighterIDs, point): 76 self._ExecuteMovementCommandOnFighters(fighterConst.MOVEMENT_COMMAND_GOTO_POINT, fighterIDs, point) 77 78 def _ExecuteMovementCommandOnFighters(self, command, fighterIDs, *args, **kwargs): 79 if fighterIDs: 80 sm.RemoteSvc('fighterMgr').ExecuteMovementCommandOnFighters(fighterIDs, command, *args, **kwargs) 81 82 def GetFightersForShip(self): 83 return sm.RemoteSvc('fighterMgr').GetFightersForShip() 84 85 def LoadFightersToTube(self, fighterID, tubeFlagID): 86 return sm.RemoteSvc('fighterMgr').LoadFightersToTube(fighterID, tubeFlagID) 87 88 def UnloadTubeToFighterBay(self, tubeFlagID): 89 fighterInTube = self.shipFighterState.GetFightersInTube(tubeFlagID) 90 if fighterInTube is not None: 91 return sm.RemoteSvc('fighterMgr').UnloadTubeToFighterBay(tubeFlagID) 92 93 def LaunchFightersFromTubes(self, tubeFlagIDs): 94 tubeFlagIDs = [ tubeFlagID for tubeFlagID in tubeFlagIDs if self.shipFighterState.GetTubeStatus(tubeFlagID).statusID == TUBE_STATE_READY ] 95 if not tubeFlagIDs: 96 return 97 errorsByTubeID = sm.RemoteSvc('fighterMgr').LaunchFightersFromTubes(tubeFlagIDs) 98 for tubeID, error in errorsByTubeID.iteritems(): 99 if error: 100 sm.GetService('gameui').OnRemoteMessage(*error.args) 101 102 def RecallFightersToTubes(self, fighterIDs): 103 fighterTubesByID = {} 104 for fighterID in fighterIDs: 105 fighterInSpace = self.shipFighterState.GetFighterInSpaceByID(fighterID) 106 if fighterInSpace is None: 107 continue 108 tubeStatus = self.shipFighterState.GetTubeStatus(fighterInSpace.tubeFlagID) 109 if tubeStatus.statusID != TUBE_STATE_INSPACE: 110 continue 111 fighterTubesByID[fighterID] = fighterInSpace.tubeFlagID 112 113 if not fighterTubesByID: 114 return 115 errorsByFighterID = sm.RemoteSvc('fighterMgr').RecallFightersToTubes(fighterTubesByID.keys()) 116 for fighterID, error in errorsByFighterID.iteritems(): 117 if error: 118 sm.GetService('gameui').OnRemoteMessage(*error.args) 119 else: 120 tubeFlagID = fighterTubesByID[fighterID] 121 self.shipFighterState.OnFighterTubeTaskStatus(tubeFlagID, TUBE_STATE_RECALLING, None, None) 122 123 def _CheckSafetyLevelForAbility(self, fighterID, abilitySlotID, targetID = None): 124 fighterInSpace = self.shipFighterState.GetFighterInSpaceByID(fighterID) 125 if fighterInSpace is None: 126 raise ValueError('Cannot activate ability for unknown fighter') 127 abilityID = GetAbilityIDForSlot(fighterInSpace.typeID, abilitySlotID) 128 effectID = GetDogmaEffectIDForAbilityID(abilityID) 129 effect = dogma_data.get_effect(effectID) 130 requiredSafetyLevel = self.crimewatchSvc.GetRequiredSafetyLevelForEffect(effect, targetID) 131 if not self.consider.SafetyCheckPasses(requiredSafetyLevel): 132 abilityNameID = GetAbilityNameIDForSlot(fighterInSpace.typeID, abilitySlotID) 133 raise UserError('CannotActivateAbilityViolatesSafety', {'fighterTypeID': fighterInSpace.typeID, 134 'abilityNameID': abilityNameID}) 135 136 def ActivateAbilitySlotsOnTarget(self, fighterIDs, abilitySlotID, targetID): 137 if not targetID: 138 fighterInSpace = self.shipFighterState.GetFighterInSpaceByID(fighterIDs[0]) 139 abilityNameID = GetAbilityNameIDForSlot(fighterInSpace.typeID, abilitySlotID) 140 raise UserError('CannotActivateAbilityRequiresTarget', {'fighterTypeID': fighterInSpace.typeID, 141 'abilityNameID': abilityNameID}) 142 if IsStarterSystem(session.solarsystemid): 143 targetItem = self.michelle.GetItem(targetID) 144 if targetItem and idCheckers.IsCharacter(targetItem.ownerID): 145 errorMsg = localization.GetByLabel('UI/Corporations/AccessRestrictions/StarterSpaceAggressionBlocked') 146 QuickMessage.show_message(errorMsg) 147 return 148 [ self._CheckSafetyLevelForAbility(fighterID, abilitySlotID) for fighterID in fighterIDs ] 149 errorsByFighterID = self._ActivateAbilitySlots(fighterIDs, abilitySlotID, targetID) 150 for fighterID, error in errorsByFighterID.iteritems(): 151 if not error: 152 self.shipFighterState.OnAbilityActivatedAtTarget(fighterID, abilitySlotID, targetID) 153 154 def ActivateAbilitySlotsOnSelf(self, fighterIDs, abilitySlotID): 155 [ self._CheckSafetyLevelForAbility(fighterID, abilitySlotID) for fighterID in fighterIDs ] 156 self._ActivateAbilitySlots(fighterIDs, abilitySlotID) 157 158 def ActivateAbilitySlotsAtPoint(self, fighterIDs, abilitySlotID, selectedPoint): 159 [ self._CheckSafetyLevelForAbility(fighterID, abilitySlotID) for fighterID in fighterIDs ] 160 self._ActivateAbilitySlots(fighterIDs, abilitySlotID, selectedPoint) 161 162 def _ActivateAbilitySlots(self, fighterIDs, abilitySlotID, *abilityArgs, **abilityKwargs): 163 if not fighterIDs: 164 return 165 fighterMgr = sm.RemoteSvc('fighterMgr') 166 errorsByFighterID = fighterMgr.CmdActivateAbilitySlots(fighterIDs, abilitySlotID, *abilityArgs, **abilityKwargs) 167 for fighterID, error in errorsByFighterID.iteritems(): 168 if error: 169 sm.GetService('gameui').OnRemoteMessage(*error.args) 170 else: 171 self.shipFighterState.OnAbilityActivationPending(fighterID, abilitySlotID) 172 173 return errorsByFighterID 174 175 def DeactivateAbilitySlots(self, fighterIDs, abilitySlotID): 176 if not fighterIDs: 177 return 178 fighterMgr = sm.RemoteSvc('fighterMgr') 179 errorsByFighterID = fighterMgr.CmdDeactivateAbilitySlots(fighterIDs, abilitySlotID) 180 for fighterID, error in errorsByFighterID.iteritems(): 181 if error: 182 sm.GetService('gameui').OnRemoteMessage(*error.args) 183 else: 184 self.shipFighterState.OnAbilityDeactivationPending(fighterID, abilitySlotID) 185 186 def LaunchAllFighters(self): 187 tubeIDsToLaunch = self.shipFighterState.fightersInLaunchTubes.keys() 188 self.LaunchFightersFromTubes(tubeIDsToLaunch) 189 190 def RecallAllFightersToTubes(self): 191 fighterIDsInSpace = self.shipFighterState.GetAllFighterIDsInSpace() 192 self.RecallFightersToTubes(fighterIDsInSpace) 193 194 def RecallAllFightersAndOrbit(self): 195 fighterIDsInSpace = self.shipFighterState.GetAllFighterIDsInSpace() 196 self.CmdReturnAndOrbit(fighterIDsInSpace) 197 198 def AbandonFighter(self, fighterID): 199 if prompt_player_fsd_dialog('ConfirmAbandonFighter', {}, YESNO) != ID_YES: 200 return 201 return sm.RemoteSvc('fighterMgr').CmdAbandonFighter(fighterID) 202 203 def ScoopAbandonedFighterFromSpace(self, fighterID, toFlagID): 204 return sm.RemoteSvc('fighterMgr').CmdScoopAbandonedFighterFromSpace(fighterID, toFlagID) 205 206 def OnStateChange(self, itemID, flag, status, *args): 207 if flag == states.selected and status: 208 if itemID in self.shipFighterState.GetAllFighterIDsInSpace() or itemID == session.shipid: 209 if not uicore.uilib.Key(uiconst.VK_CONTROL): 210 movementFunctions.DeselectAllForNavigation() 211 movementFunctions.SelectForNavigation(itemID) 212 213 def ToggleSelectionForFightersForTube(self, tubeFlagID): 214 fighters = self.shipFighterState.GetFightersForTubeID(tubeFlagID) 215 if fighters: 216 movementFunctions.ToggleSelectForNavigation(fighters.itemID) 217 218 def LaunchSelectedFighters(self): 219 tubeIDsToLaunch = movementFunctions.GetSelectedFightersByTubeIDs().keys() 220 if tubeIDsToLaunch: 221 self.LaunchFightersFromTubes(tubeIDsToLaunch) 222 223 def RecallSelectedFightersToTubes(self): 224 fightersToRecall = movementFunctions.GetSelectedFightersByTubeIDs().values() 225 self.RecallFightersToTubes(fightersToRecall) 226 227 def SelectAllFighters(self): 228 fightersToSelect = self.shipFighterState.GetAllFightersIDs() 229 for eachFighterID in fightersToSelect: 230 movementFunctions.SelectForNavigation(eachFighterID) 231 232 def DeselectAllFighters(self): 233 fightersToDeselect = self.shipFighterState.GetAllFightersIDs() 234 for eachFighterID in fightersToDeselect: 235 movementFunctions.DeselectForNavigation(eachFighterID)