activeShipController.py (12597B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\shipHud\activeShipController.py 2 import math 3 from eve.client.script.ui.inflight.shipHud.action_indication.hud_action_indication_controller import HudActionIndicationController, IndicationData 4 from player_messaging.client.ui_message import message_player 5 from eve.common.script.sys.eveCfg import GetActiveShip, IsControllingStructure 6 from eve.common.script.sys.idCheckers import IsModule 7 from localization import GetByLabel 8 import blue 9 import destiny 10 import trinity 11 import signals 12 import log 13 from carbonui.uicore import uicore 14 from eveservices.menu import GetMenuService 15 16 class ActiveShipController(object): 17 __notifyevents__ = ['DoBallClear', 'ProcessActiveShipChanged'] 18 19 def __init__(self): 20 sm.RegisterNotify(self) 21 self.ball = None 22 self.on_new_itemID = signals.Signal(signalName='on_new_itemID') 23 self.wantedspeed = None 24 25 def GetItemID(self): 26 return GetActiveShip() 27 28 def GetTypeID(self): 29 shipItem = self._GetShipItem() 30 if shipItem: 31 return shipItem.typeID 32 33 def _GetShipItem(self): 34 if not self._IsShipItemReady(): 35 log.LogWarn('ActiveShipController queried for ship godma item before loading has finished! Hopefully the caller can handle a None return!') 36 return None 37 return sm.GetService('godma').GetItem(self.GetItemID()) 38 39 def GetModules(self): 40 shipItem = self._GetShipItem() 41 if not shipItem: 42 return [] 43 return shipItem.modules 44 45 def GetBall(self): 46 if self.ball and self.ball.id == self.GetItemID() and self.ball.ballpark is not None and not getattr(self.ball, 'released', False): 47 return self.ball 48 bp = sm.GetService('michelle').GetBallpark() 49 if bp is None or self.GetItemID() is None: 50 return 51 self.ball = bp.GetBall(self.GetItemID()) 52 return self.ball 53 54 def InvalidateBall(self): 55 self.ball = None 56 57 def Close(self): 58 sm.UnregisterNotify(self) 59 60 def DoBallClear(self, solItem): 61 self.InvalidateBall() 62 63 def ProcessActiveShipChanged(self, *args): 64 self.on_new_itemID() 65 self.InvalidateBall() 66 67 def IsLoaded(self): 68 if not session.charid: 69 return False 70 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 71 if not self.GetBall(): 72 return False 73 if not self.GetItemID() or not dogmaLocation.IsItemLoaded(self.GetItemID()): 74 return False 75 if not self._IsShipItemReady(): 76 return False 77 return True 78 79 def _IsShipItemReady(self): 80 return sm.GetService('godma').IsItemReady(self.GetItemID()) 81 82 def GetArmorHP(self): 83 return max(0.0, self._GetShipItem().armorHP - self._GetShipItem().armorDamage) 84 85 def GetArmorHPMax(self): 86 return self._GetShipItem().armorHP 87 88 def GetArmorHPPortion(self): 89 armor = 0.0 90 try: 91 return max(0.0, min(1.0, round(self.GetArmorHP() / self.GetArmorHPMax(), 2))) 92 except ZeroDivisionError: 93 return 0.0 94 95 def GetStructureHP(self): 96 return max(0.0, self._GetShipItem().hp - self._GetShipItem().damage) 97 98 def GetStructureHPMax(self): 99 return self._GetShipItem().hp 100 101 def GetStructureHPPortion(self): 102 try: 103 return max(0.0, min(1.0, round(self.GetStructureHP() / self.GetStructureHPMax(), 2))) 104 except ZeroDivisionError: 105 return 0.0 106 107 def GetShieldHP(self): 108 return self._GetShipItem().shieldCharge 109 110 def GetShieldHPMax(self): 111 return self._GetShipItem().shieldCapacity 112 113 def GetShieldHPPortion(self): 114 try: 115 return max(0.0, min(1.0, round(self.GetShieldHP() / self.GetShieldHPMax(), 2))) 116 except ZeroDivisionError: 117 return 0.0 118 119 def GetTotalHpMax(self): 120 return self.GetShieldHPMax() + self.GetArmorHPMax() + self.GetStructureHPMax() 121 122 def GetCapacitorCapacity(self): 123 return self._GetShipItem().charge 124 125 def GetCapacitorCapacityMax(self): 126 shipItem = self._GetShipItem() 127 if shipItem is None: 128 return 0 129 return float(shipItem.capacitorCapacity) 130 131 def GetCharges(self): 132 shipItem = self._GetShipItem() 133 if not shipItem: 134 return [] 135 return shipItem.sublocations 136 137 def IsControllingTurret(self): 138 return bool(sm.GetService('pwn').GetCurrentControl()) 139 140 def IsControllingStructure(self): 141 return IsControllingStructure() 142 143 def GetMenu(self): 144 itemID = self.GetItemID() 145 if not itemID: 146 return [] 147 return GetMenuService().CelestialMenu(itemID) 148 149 def GetSpeed(self): 150 return self.GetBall().GetVectorDotAt(blue.os.GetSimTime()).Length() 151 152 def GetSpeedFormatted(self): 153 return self._GetSpeedFormatted(self.GetSpeed()) 154 155 def GetSpeedAt(self, speedRatio): 156 return speedRatio * self.GetSpeedMax() 157 158 def GetSpeedAtFormatted(self, speedRatio): 159 return self._GetSpeedFormatted(self.GetSpeedAt(speedRatio)) 160 161 def GetSpeedMax(self): 162 return self.GetBall().maxVelocity 163 164 def GetSpeedMaxFormatted(self): 165 return self._GetSpeedFormatted(self.GetSpeedMax()) 166 167 def _GetSpeedFormatted(self, speed): 168 if math.isnan(speed): 169 return '' 170 if speed < 100: 171 return GetByLabel('UI/Inflight/MetersPerSecond', speed=round(speed, 1)) 172 return GetByLabel('UI/Inflight/MetersPerSecond', speed=int(speed)) 173 174 def GetSpeedPortion(self): 175 try: 176 speedPortion = max(0.0, min(1.0, self.GetSpeed() / self.GetSpeedMax())) 177 except ZeroDivisionError: 178 speedPortion = 0.0 179 180 return speedPortion 181 182 def StopShip(self): 183 self.wantedspeed = 0.0 184 uicore.cmd.GetCommandAndExecute('CmdStopShip') 185 186 def SetSpeed(self, speedRatio, initing = 0): 187 if (not self.GetBall() or self.IsInWarp()) and speedRatio > 0: 188 return 189 if self.GetBall() and self.GetBall().ballpark is None: 190 self.InvalidateBall() 191 return 192 if self.wantedspeed is not None and int(self.GetBall().speedFraction * 1000) == int(speedRatio * 1000) == int(self.wantedspeed * 1000) and speedRatio > 0: 193 return 194 if speedRatio <= 0.0: 195 self.StopShip() 196 elif speedRatio != self.wantedspeed: 197 rbp = sm.GetService('michelle').GetRemotePark() 198 bp = sm.GetService('michelle').GetBallpark() 199 if bp and not initing: 200 ownBall = bp.GetBall(session.shipid) 201 if ownBall and rbp is not None and ownBall.mode == destiny.DSTBALL_STOP: 202 if not sm.GetService('autoPilot').GetState(): 203 direction = trinity.TriVector(0.0, 0.0, 1.0) 204 currentDirection = self.GetBall().GetQuaternionAt(blue.os.GetSimTime()) 205 direction.TransformQuaternion(currentDirection) 206 rbp.CmdGotoDirection(direction.x, direction.y, direction.z) 207 if rbp is not None: 208 rbp.CmdSetSpeedFraction(min(1.0, speedRatio)) 209 if not initing and self.GetBall(): 210 speedText = GetByLabel('UI/Inflight/SpeedChangedTo', speed=self.GetSpeedAtFormatted(speedRatio)) 211 sm.GetService('logger').AddText(speedText, 'notify') 212 message_player(speedText) 213 if not initing: 214 self.wantedspeed = max(speedRatio, 0.0) 215 216 def SetMaxSpeed(self, *args): 217 bp = sm.GetService('michelle').GetBallpark() 218 rbp = sm.GetService('michelle').GetRemotePark() 219 if bp: 220 ownBall = bp.GetBall(session.shipid) 221 if ownBall and rbp is not None and ownBall.mode == destiny.DSTBALL_STOP: 222 if not sm.GetService('autoPilot').GetState(): 223 direction = trinity.TriVector(0.0, 0.0, 1.0) 224 currentDirection = self.GetBall().GetQuaternionAt(blue.os.GetSimTime()) 225 direction.TransformQuaternion(currentDirection) 226 rbp.CmdGotoDirection(direction.x, direction.y, direction.z) 227 if rbp is not None: 228 rbp.CmdSetSpeedFraction(1.0) 229 speed = self.GetSpeedMaxFormatted() 230 speedText = GetByLabel('UI/Inflight/SpeedChangedTo', speed=speed) 231 sm.GetService('logger').AddText(speedText, 'notify') 232 HudActionIndicationController.get_instance().set_temporary_indication(IndicationData(GetByLabel('UI/Inflight/Messages/ShipFullSpeedHeader'), speedText), blink=True) 233 self.wantedspeed = 1.0 234 else: 235 self.wantedspeed = None 236 237 def IsInWarp(self): 238 ball = self.GetBall() 239 return ball is None or ball.mode == destiny.DSTBALL_WARP 240 241 def _GetHeatStates(self): 242 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 243 return dogmaLocation.GetCurrentShipHeatStates() 244 245 def GetHeatLowPortion(self): 246 return self._GetHeatStates()[const.attributeHeatLow] 247 248 def GetHeatMedPortion(self): 249 return self._GetHeatStates()[const.attributeHeatMed] 250 251 def GetHeatHiPortion(self): 252 return self._GetHeatStates()[const.attributeHeatHi] 253 254 def GetNumHiSlots(self): 255 return int(getattr(self._GetShipItem(), 'hiSlots', 0)) 256 257 def GetNumMedSlots(self): 258 return int(getattr(self._GetShipItem(), 'medSlots', 0)) 259 260 def GetNumLowSlots(self): 261 return int(getattr(self._GetShipItem(), 'lowSlots', 0)) 262 263 def GetModuleGroupDamage(self, itemID, *args): 264 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 265 moduleDamage = dogmaLocation.GetAccurateAttributeValue(itemID, const.attributeDamage) 266 masterID = dogmaLocation.IsInWeaponBank(self.GetItemID(), itemID) 267 if not masterID: 268 return moduleDamage 269 allModulesInBank = dogmaLocation.GetModulesInBank(self.GetItemID(), masterID) 270 maxDamage = moduleDamage 271 for slaveID in allModulesInBank: 272 damage = dogmaLocation.GetAccurateAttributeValue(slaveID, const.attributeDamage) 273 if damage > maxDamage: 274 maxDamage = damage 275 276 return maxDamage 277 278 def GetDamagedModulesAndRepairCost(self): 279 damagedModulesAndCost = set() 280 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 281 godmaStateManager = sm.GetService('godma').GetStateManager() 282 for moduleInfo in self.GetModules(): 283 if not IsModule(moduleInfo.categoryID): 284 continue 285 if godmaStateManager.IsBeingRepaired(moduleInfo.itemID): 286 continue 287 moduleDamage = dogmaLocation.GetAccurateAttributeValue(moduleInfo.itemID, const.attributeDamage) 288 if moduleDamage: 289 repairCost = self.GetNumUnitsToRepairModule(dogmaLocation, moduleInfo.typeID, moduleInfo.itemID) 290 damagedModulesAndCost.add((moduleInfo.itemID, repairCost)) 291 292 return damagedModulesAndCost 293 294 def GetAllRepairingModules(self): 295 godmaStateManager = sm.GetService('godma').GetStateManager() 296 moduleRepairing = set() 297 for moduleInfo in self.GetModules(): 298 if godmaStateManager.IsBeingRepaired(moduleInfo.itemID): 299 moduleRepairing.add(moduleInfo.itemID) 300 301 return moduleRepairing 302 303 def GetNumUnitsToRepairModuleBank(self, typeID, itemID): 304 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 305 masterID = dogmaLocation.IsInWeaponBank(self.GetItemID(), itemID) 306 if masterID: 307 allModulesInBank = dogmaLocation.GetModulesInBank(self.GetItemID(), masterID) 308 else: 309 allModulesInBank = [itemID] 310 repairAmount = 0 311 for eachModuleID in allModulesInBank: 312 unitsToRepair = self.GetNumUnitsToRepairModule(dogmaLocation, typeID, eachModuleID) 313 repairAmount += unitsToRepair 314 315 return repairAmount 316 317 def GetNumUnitsToRepairModule(self, dogmaLocation, typeID, moduleID): 318 moduleDamage = dogmaLocation.GetAccurateAttributeValue(moduleID, const.attributeDamage) 319 hp = dogmaLocation.GetAccurateAttributeValue(moduleID, const.attributeHp) 320 try: 321 unitsToRepair = dogmaLocation.FindNumUnitsToRepairModule(session.charid, moduleDamage, hp, typeID, moduleID) or 0 322 except TypeError: 323 unitsToRepair = 0 324 325 return unitsToRepair