fittingDogmaLocationUtil.py (26079B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\shipfitting\fittingDogmaLocationUtil.py 2 import math 3 from carbon.common.script.util.mathCommon import FloatCloseEnough 4 from collections import defaultdict 5 from math import sqrt, log, exp 6 import evetypes 7 from inventorycommon.const import groupMissileLauncherDot 8 from itertoolsext import Bundle 9 from fighters import ABILITY_SLOT_0, ABILITY_SLOT_2, GetAbilityIDForSlot 10 from fighters.abilityAttributes import GetDogmaAttributeIDsForAbilityID, FIGHTER_DAMAGE_ATTRIBUTES, GetDamageMultiplierAttributeFromAbilityID, GetAbilityDurationAttributeID, GetAbilityRangeAndFalloffAttributeIDs 11 from fighters import GetMaxSquadronSize 12 from utillib import KeyVal 13 CAP_STABLE_TIME = const.HOUR 14 DAMAGE_ATTRIBUTES = (const.attributeEmDamage, 15 const.attributeExplosiveDamage, 16 const.attributeKineticDamage, 17 const.attributeThermalDamage) 18 DURATION_ATTRIBUTES = [const.attributeFighterAbilityAttackMissileDuration, const.attributeFighterAbilityMissilesDuration, const.attributeFighterAbilityAttackTurretDuration] 19 20 def GetFittingItemDragData(itemID, dogmaLocation): 21 dogmaItem = dogmaLocation.dogmaItems[itemID] 22 data = Bundle() 23 data.__guid__ = 'listentry.Item' 24 data.item = KeyVal(itemID=dogmaItem.itemID, typeID=dogmaItem.typeID, groupID=dogmaItem.groupID, categoryID=dogmaItem.categoryID, flagID=dogmaItem.flagID, ownerID=dogmaItem.ownerID, locationID=dogmaItem.locationID, stacksize=dogmaLocation.GetAccurateAttributeValue(itemID, const.attributeQuantity) or getattr(dogmaItem, 'stacksize', 1), singleton=False) 25 data.flagID = dogmaItem.flagID 26 data.isFitted = True 27 data.rec = data.item 28 data.typeID = dogmaItem.typeID 29 data.itemID = itemID 30 data.viewMode = 'icons' 31 return [data] 32 33 34 def GetFittedItemsByFlag(dogmaLocation): 35 typeHasEffectFunc = dogmaLocation.dogmaStaticMgr.TypeHasEffect 36 chargesByFlag = {} 37 turretsByFlag = {} 38 launchersByFlag = {} 39 aoeWeaponsByFlag = {} 40 dotLaunchersByFlag = {} 41 IsTurret = lambda typeID: typeHasEffectFunc(typeID, const.effectTurretFitted) 42 IsLauncher = lambda typeID: typeHasEffectFunc(typeID, const.effectLauncherFitted) or typeHasEffectFunc(typeID, const.effectUseMissiles) 43 IsAOE = lambda itemID: dogmaLocation.GetAccurateAttributeValue(itemID, const.attributeEmpFieldRange) 44 for module in dogmaLocation.GetFittedItemsToShip().itervalues(): 45 if IsTurret(module.typeID): 46 if not dogmaLocation.IsModuleIncludedInCalculation(module): 47 continue 48 turretsByFlag[module.flagID] = module.itemID 49 elif IsLauncher(module.typeID): 50 if not dogmaLocation.IsModuleIncludedInCalculation(module): 51 continue 52 if module.groupID == groupMissileLauncherDot: 53 dotLaunchersByFlag[module.flagID] = module.itemID 54 else: 55 launchersByFlag[module.flagID] = module.itemID 56 elif module.categoryID == const.categoryCharge: 57 chargesByFlag[module.flagID] = module.itemID 58 elif IsAOE(module.itemID): 59 if not dogmaLocation.IsModuleIncludedInCalculation(module): 60 continue 61 aoeWeaponsByFlag[module.flagID] = module.itemID 62 63 return (chargesByFlag, 64 launchersByFlag, 65 turretsByFlag, 66 aoeWeaponsByFlag, 67 dotLaunchersByFlag) 68 69 70 def GetAlphaStrike(dogmaLocation): 71 chargesByFlag, launchersByFlag, turretsByFlag, aoeWeaponsByFlag, dotLaunchersByFlag = GetFittedItemsByFlag(dogmaLocation) 72 GAV = dogmaLocation.GetAccurateAttributeValue 73 alpha = 0.0 74 ownerID = session.charid 75 for flagID, itemID in launchersByFlag.iteritems(): 76 chargeKey = chargesByFlag.get(flagID) 77 damagePerShot = _GetLauncherDamagePerShot(dogmaLocation, chargeKey, itemID, ownerID, GAV) 78 alpha += damagePerShot 79 80 for flagID, itemID in turretsByFlag.iteritems(): 81 chargeKey = chargesByFlag.get(flagID) 82 damagePerShot = _GetTurretDamagePerShot(dogmaLocation, chargeKey, itemID, GAV) 83 alpha += damagePerShot 84 85 for flagID, itemID in dotLaunchersByFlag.iteritems(): 86 chargeKey = chargesByFlag.get(flagID) 87 damagePerHit = GetDotDps(chargeKey, itemID, GAV) 88 alpha += damagePerHit 89 90 for flagID, itemID in aoeWeaponsByFlag.iteritems(): 91 damagePerHit = GetDamageFromItem(dogmaLocation, itemID) 92 alpha += damagePerHit 93 94 return alpha 95 96 97 def _GetTurretDps(GAV, chargesByFlag, dogmaLocation, turretsByFlag, getMaxValue = False): 98 turretDps = 0.0 99 turretDpsWithReload = 0.0 100 for flagID, itemID in turretsByFlag.iteritems(): 101 chargeKey = chargesByFlag.get(flagID) 102 thisTurretDps, thisTurretDpsWithReload = GetTurretDps(dogmaLocation, chargeKey, itemID, GAV, getMaxValue) 103 turretDps += thisTurretDps 104 turretDpsWithReload += thisTurretDpsWithReload 105 106 return (turretDps, turretDpsWithReload) 107 108 109 def _GetMissileDps(GAV, chargesByFlag, dogmaLocation, launchersByFlag, shipDogmaItem): 110 missileDps = 0.0 111 missilDpsWithReload = 0.0 112 for flagID, itemID in launchersByFlag.iteritems(): 113 chargeKey = chargesByFlag.get(flagID) 114 if chargeKey is None: 115 continue 116 ownerID = session.charid 117 thisLauncherDps, thisLauncherDpsWithReload = GetLauncherDps(dogmaLocation, chargeKey, itemID, ownerID, GAV) 118 missileDps += thisLauncherDps 119 missilDpsWithReload += thisLauncherDpsWithReload 120 121 return (missileDps, missilDpsWithReload) 122 123 124 def _GetDotDps(GAV, chargesByFlag, dotLaunchersByFlagID): 125 dotDps = 0.0 126 for flagID, itemID in dotLaunchersByFlagID.iteritems(): 127 chargeKey = chargesByFlag.get(flagID) 128 if chargeKey is None: 129 continue 130 dotDps += GetDotDps(chargeKey, itemID, GAV) 131 132 return dotDps 133 134 135 def _GetAoeDps(GAV, aoeWeaponsByFlag, dogmaLocation): 136 dps = 0.0 137 for flagID, itemID in aoeWeaponsByFlag.iteritems(): 138 damage = GetDamageFromItem(dogmaLocation, itemID) 139 duration = GAV(itemID, const.attributeDuration) 140 if not duration: 141 continue 142 missileDps = damage / duration 143 dps += missileDps 144 145 return dps * 1000 146 147 148 def GetAllDpsInfo(shipID, dogmaLocation): 149 dpsInfo = GetTurretMissileAndAoeDps(shipID, dogmaLocation) 150 from shipfitting.droneUtil import GetDroneDps 151 droneDps, _ = GetDroneDps(shipID, dogmaLocation) 152 dpsInfo.droneDps = droneDps 153 fighterDamage, dpsByTubeID, dpsByPrimaryAbilityID, dpsBySecondaryAbilityID = GetFighterDamage(dogmaLocation) 154 totalFighterDps = sum(dpsByTubeID.values()) 155 dpsInfo.fighterDps = totalFighterDps 156 dpsInfo.dpsByPrimaryAbilityID = dpsByPrimaryAbilityID 157 dpsInfo.dpsBySecondaryAbilityID = dpsBySecondaryAbilityID 158 dpsInfo.totalDps += droneDps + totalFighterDps 159 dpsInfo.totalDpsWithReload += droneDps + totalFighterDps 160 return dpsInfo 161 162 163 def GetTotalFighterDps(dogmaLocation): 164 fighterDamage, dpsByTubeID, dpsByPrimaryAbilityID, dpsBySecondaryAbilityID = GetFighterDamage(dogmaLocation) 165 totalFighterDps = sum(dpsByTubeID.values()) 166 return totalFighterDps 167 168 169 def GetTurretMissileAndAoeDps(shipID, dogmaLocation): 170 shipDogmaItem = dogmaLocation.dogmaItems[shipID] 171 GAV = dogmaLocation.GetAttributeValue 172 if getattr(dogmaLocation, 'godma', False): 173 godmaShipItem = dogmaLocation.godma.GetItem(shipID) 174 if godmaShipItem is not None: 175 GAV = dogmaLocation.GetGodmaAttributeValue 176 chargesByFlag, launchersByFlag, turretsByFlag, aoeWeaponsByFlag, dotLaunchersByFlag = GetFittedItemsByFlag(dogmaLocation) 177 turretDps, turretDpsWithReload = _GetTurretDps(GAV, chargesByFlag, dogmaLocation, turretsByFlag) 178 maxTurretDps, maxTurretDpsWithReload = _GetTurretDps(GAV, chargesByFlag, dogmaLocation, turretsByFlag, True) 179 if maxTurretDps and FloatCloseEnough(turretDps, maxTurretDps): 180 maxTurretDps = None 181 maxTurretDpsWithReload = None 182 missileDps, missileDpsWithReload = _GetMissileDps(GAV, chargesByFlag, dogmaLocation, launchersByFlag, shipDogmaItem) 183 dotDps = _GetDotDps(GAV, chargesByFlag, dotLaunchersByFlag) 184 aoeDps = _GetAoeDps(GAV, aoeWeaponsByFlag, dogmaLocation) 185 totalDps = (maxTurretDps or turretDps) + missileDps + aoeDps + dotDps 186 totalDpsWithReload = (maxTurretDpsWithReload or turretDpsWithReload) + missileDpsWithReload + aoeDps + dotDps 187 dpsInfo = KeyVal(turretDps=turretDps, turretDpsWithReload=turretDpsWithReload, maxTurretDps=maxTurretDps, maxTurretDpsWithReload=maxTurretDpsWithReload, missileDps=missileDps, missileDpsWithReload=missileDpsWithReload, aoeDps=aoeDps, totalDps=totalDps, totalDpsWithReload=totalDpsWithReload, dotDps=dotDps) 188 return dpsInfo 189 190 191 def GetChanceToHit(shipID, dogmaLocation): 192 chargesByFlag, launchersByFlag, turretsByFlag, aoeWeaponsByFlag, dotLaunchersByFlag = GetFittedItemsByFlag(dogmaLocation) 193 trackingSpeed = falloff = maxRange = optimalSig = 0 194 numTurrets = len(turretsByFlag) 195 for turret in turretsByFlag.itervalues(): 196 trackingSpeed += dogmaLocation.GetAttributeValue(turret, const.attributeTrackingSpeed) 197 falloff += dogmaLocation.GetAttributeValue(turret, const.attributeFalloff) 198 maxRange += dogmaLocation.GetAttributeValue(turret, const.attributeMaxRange) 199 optimalSig += dogmaLocation.GetAttributeValue(turret, const.attributeOptimalSigRadius) 200 201 trackingSpeed /= numTurrets 202 falloff /= numTurrets 203 maxRange /= numTurrets 204 optimalSig /= numTurrets 205 return (trackingSpeed, 206 falloff, 207 maxRange, 208 optimalSig) 209 210 211 def GetLauncherDps(dogmaLocation, chargeKey, itemID, ownerID, GAV): 212 damagePerShot = _GetLauncherDamagePerShot(dogmaLocation, chargeKey, itemID, ownerID, GAV) 213 duration = GAV(itemID, const.attributeRateOfFire) 214 missileDps = damagePerShot / duration 215 missileDpsWithReload = _GetDpsWithReload(chargeKey, itemID, GAV, damagePerShot, duration) 216 return (missileDps * 1000, missileDpsWithReload * 1000) 217 218 219 def _GetLauncherDamagePerShot(dogmaLocation, chargeKey, moduleID, ownerID, GAV): 220 if chargeKey is None: 221 return 0 222 damageMultiplier = GetMissleDamageMultiplier(dogmaLocation, moduleID, ownerID, GAV) 223 damage = GetDamageFromItem(dogmaLocation, chargeKey) 224 damagePerShot = damage * damageMultiplier 225 return damagePerShot 226 227 228 def GetMissleDamageMultiplier(dogmaLocation, moduleID, ownerID, GAV): 229 dogmaItem = dogmaLocation.SafeGetDogmaItem(moduleID) 230 if dogmaItem and dogmaItem.groupID == const.groupMissileLauncherBomb: 231 damageMultiplier = 1 232 else: 233 damageMultiplier = GAV(ownerID, const.attributeMissileDamageMultiplier) 234 return damageMultiplier 235 236 237 def GetTurretDpsWithMax(dogmaLocation, chargeKey, itemID, GAV, *args): 238 dps, dpsWithReload = GetTurretDps(dogmaLocation, chargeKey, itemID, GAV, False) 239 maxDps, maxDpsWithReload = GetTurretDps(dogmaLocation, chargeKey, itemID, GAV, True) 240 if not maxDps or FloatCloseEnough(dps, maxDps): 241 maxDps = None 242 maxDpsWithReload = None 243 return (dps, 244 dpsWithReload, 245 maxDps, 246 maxDpsWithReload) 247 248 249 def GetTurretDps(dogmaLocation, chargeKey, itemID, GAV, getMaxValue = False, *args): 250 turretDps = 0.0 251 turretDpsWithReload = 0.0 252 damagePerShot = _GetTurretDamagePerShot(dogmaLocation, chargeKey, itemID, GAV, getMaxValue) 253 if abs(damagePerShot) > 0: 254 duration = GAV(itemID, const.attributeRateOfFire) 255 if abs(duration) > 0: 256 turretDps = damagePerShot / duration 257 turretDpsWithReload = _GetDpsWithReload(chargeKey, itemID, GAV, damagePerShot, duration) 258 return (turretDps * 1000, turretDpsWithReload * 1000) 259 260 261 def _GetTurretDamagePerShot(dogmaLocation, chargeKey, itemID, GAV, getMaxValue = False): 262 if chargeKey is not None: 263 damage = GetDamageFromItem(dogmaLocation, chargeKey) 264 else: 265 damage = GetDamageFromItem(dogmaLocation, itemID) 266 if damage > 0: 267 damageMultiplier = GAV(itemID, const.attributeDamageMultiplier) 268 if getMaxValue: 269 extraMaxDamageMultiplier = dogmaLocation.GetMaxDamageMultiplier(itemID) 270 damageMultiplier *= extraMaxDamageMultiplier 271 damage *= damageMultiplier 272 return damage 273 274 275 def _GetDpsWithReload(chargeKey, itemID, GAV, damagePerShot, duration): 276 if chargeKey is None: 277 return damagePerShot / duration 278 reloadTime = GAV(itemID, const.attributeReloadTime) 279 reactivationDelay = GAV(itemID, const.attributeModuleReactivationDelay) 280 numShotBeforeReload = GetNumChargesFullyLoaded(chargeKey, itemID, GAV) 281 if reactivationDelay > reloadTime: 282 missileDpsWithReload = damagePerShot / (reactivationDelay + duration) 283 return missileDpsWithReload 284 if numShotBeforeReload: 285 missileDpsWithReload = numShotBeforeReload * damagePerShot / (numShotBeforeReload * duration + reloadTime) 286 return missileDpsWithReload 287 return 0 288 289 290 def GetDotDps(chargeKey, itemID, GAV, *args): 291 if chargeKey is None: 292 return 0 293 dotMaxDamagePerTick = GAV(chargeKey, const.attributeDotMaxDamagePerTick) 294 damageMultiplier = GAV(itemID, const.attributeDamageMultiplier) 295 return dotMaxDamagePerTick * damageMultiplier 296 297 298 def GetNumChargesFullyLoaded(chargeKey, itemID, GAV): 299 launcherCapacity = GAV(itemID, const.attributeCapacity) 300 chargeVolume = GAV(chargeKey, const.attributeVolume) 301 if chargeVolume: 302 numShotBeforeReload = int(launcherCapacity / float(chargeVolume)) 303 return numShotBeforeReload 304 else: 305 return 0 306 307 308 def GetDamageFromItem(dogmaLocation, itemID): 309 accDamage = 0 310 for attributeID in DAMAGE_ATTRIBUTES: 311 d = dogmaLocation.GetAccurateAttributeValue(itemID, attributeID) 312 accDamage += d 313 314 return accDamage 315 316 317 def CapacitorSimulator(dogmaLocation, shipID): 318 dogmaItem = dogmaLocation.dogmaItems[shipID] 319 capacitorCapacity = dogmaLocation.GetAccurateAttributeValue(shipID, const.attributeCapacitorCapacity) 320 rechargeTime = dogmaLocation.GetAccurateAttributeValue(shipID, const.attributeRechargeRate) 321 modules = [] 322 totalCapNeed = 0 323 modulesByFlag = {} 324 chargesByFlag = {} 325 for moduleID, module in dogmaItem.GetFittedItems().iteritems(): 326 if module.categoryID == const.categoryCharge: 327 chargesByFlag[module.flagID] = module 328 else: 329 modulesByFlag[module.flagID] = module 330 331 for flagID, module in modulesByFlag.iteritems(): 332 moduleID = module.itemID 333 if not dogmaLocation.IsModuleIncludedInCalculation(module): 334 continue 335 try: 336 defaultEffectID = dogmaLocation.dogmaStaticMgr.GetDefaultEffect(module.typeID) 337 except KeyError: 338 defaultEffectID = None 339 340 if defaultEffectID is None: 341 continue 342 defaultEffect = dogmaLocation.dogmaStaticMgr.effects[defaultEffectID] 343 durationAttributeID = defaultEffect.durationAttributeID 344 dischargeAttributeID = defaultEffect.dischargeAttributeID 345 if durationAttributeID is None: 346 continue 347 duration = dogmaLocation.GetAccurateAttributeValue(moduleID, durationAttributeID) 348 reactivationDelay = dogmaLocation.GetAccurateAttributeValue(moduleID, const.attributeModuleReactivationDelay) 349 reloadInfo = None 350 moduleGroupID = evetypes.GetGroupID(module.typeID) 351 if moduleGroupID == const.groupCapacitorBooster: 352 charges = chargesByFlag.get(flagID, None) 353 if not charges: 354 continue 355 avgCapInjectedEachCycle, capInjectedPerCycle, reloadInfo = _GetAvgInjectedEachCycle(dogmaLocation, moduleID, charges, duration) 356 avgCapNeed = -avgCapInjectedEachCycle 357 capNeed = -capInjectedPerCycle 358 elif moduleGroupID == const.groupEnergyVampire: 359 capInjectedPerCycle = dogmaLocation.GetAccurateAttributeValue(moduleID, const.attributePowerTransferAmount) 360 capNeed = -capInjectedPerCycle 361 avgCapNeed = -capInjectedPerCycle 362 elif dischargeAttributeID is None: 363 continue 364 else: 365 avgCapNeed = capNeed = dogmaLocation.GetAccurateAttributeValue(moduleID, dischargeAttributeID) 366 k = KeyVal(capNeeded=capNeed, durationValue=long(duration * const.dgmTauConstant), nextRun=0, cyclesSinceReload=0, reloadInfo=reloadInfo, reactivationDelay=reactivationDelay) 367 modules.append(k) 368 totalCapNeed += avgCapNeed / (duration + reactivationDelay) 369 370 rechargeRateAverage = capacitorCapacity / rechargeTime 371 peakRechargeRate = 2.5 * rechargeRateAverage 372 tau = rechargeTime / 5 373 totalPositiveCapNeeded = max(0, totalCapNeed) 374 TTL = None 375 runSimulation = totalCapNeed > peakRechargeRate 376 if runSimulation or totalCapNeed / peakRechargeRate > 0.95: 377 TTL = RunSimulation(capacitorCapacity, rechargeTime, modules) 378 if TTL >= CAP_STABLE_TIME: 379 TTL = None 380 if TTL is not None: 381 loadBalance = 0 382 else: 383 c = 2 * capacitorCapacity / tau 384 k = totalPositiveCapNeeded / c 385 fourK = min(1, 4 * k) 386 exponent = (1 - sqrt(1 - fourK)) / 2 387 if exponent == 0: 388 loadBalance = 1 389 else: 390 t = -log(exponent) * tau 391 loadBalance = (1 - exp(-t / tau)) ** 2 392 return (peakRechargeRate, 393 totalCapNeed, 394 loadBalance, 395 TTL) 396 397 398 def _GetReloadInfo(dogmaLocation, moduleID, charges): 399 GAV = dogmaLocation.GetAccurateAttributeValue 400 reloadTime = GAV(moduleID, const.attributeReloadTime) 401 moduleCapacity = GAV(moduleID, const.attributeCapacity) 402 chargeVolume = GAV(charges.itemID, const.attributeVolume) 403 maxChargesInModule = int(moduleCapacity / float(chargeVolume)) 404 moduleRechargeInfo = KeyVal(reloadTime=reloadTime, maxChargesInModule=maxChargesInModule) 405 return moduleRechargeInfo 406 407 408 def _GetAvgInjectedEachCycle(dogmaLocation, moduleID, charges, duration): 409 moduleRechargeInfo = _GetReloadInfo(dogmaLocation, moduleID, charges) 410 capInjectedPerCycle = dogmaLocation.GetAccurateAttributeValue(charges.itemID, const.attributeCapacitorBonus) 411 injectedInOneLoad = moduleRechargeInfo.maxChargesInModule * capInjectedPerCycle 412 durationOfFullLoad = moduleRechargeInfo.maxChargesInModule * duration 413 avgCapInjectedEachCycle = injectedInOneLoad / (durationOfFullLoad + moduleRechargeInfo.reloadTime) * duration 414 return (avgCapInjectedEachCycle, capInjectedPerCycle, moduleRechargeInfo) 415 416 417 def RunSimulation(capacitorCapacity, rechargeRate, modules): 418 capacitor = capacitorCapacity 419 tauThingy = float(const.dgmTauConstant) * (rechargeRate / 5.0) 420 currentTime = nextTime = 0 421 while capacitor > 0.0 and nextTime < CAP_STABLE_TIME: 422 capacitor = (1.0 + (math.sqrt(capacitor / capacitorCapacity) - 1.0) * math.exp((currentTime - nextTime) / tauThingy)) ** 2 * capacitorCapacity 423 currentTime = nextTime 424 nextTime = CAP_STABLE_TIME 425 for data in modules: 426 if data.nextRun == currentTime: 427 capacitor -= data.capNeeded 428 data.cyclesSinceReload += 1 429 if data.reloadInfo: 430 if data.cyclesSinceReload >= data.reloadInfo.maxChargesInModule: 431 data.nextRun += data.reloadInfo.reloadTime * const.SEC 432 data.cyclesSinceReload = 0 433 if data.reactivationDelay: 434 data.nextRun += data.reactivationDelay * const.SEC 435 data.nextRun += data.durationValue 436 nextTime = min(nextTime, data.nextRun) 437 438 if capacitor > 0.0: 439 return CAP_STABLE_TIME 440 return currentTime 441 442 443 LN_025 = math.log(0.25) 444 445 def GetAlignTime(dogmaLocation): 446 shipID = dogmaLocation.GetCurrentShipID() 447 agility = dogmaLocation.GetAttributeValue(shipID, const.attributeAgility) 448 mass = dogmaLocation.GetAttributeValue(shipID, const.attributeMass) 449 return GetAlignTimeFromAgilityAndMass(agility, mass) 450 451 452 def GetAlignTimeFromAgilityAndMass(agility, mass): 453 alignTime = -LN_025 * agility * mass / 1000000 454 return alignTime 455 456 457 def GetFuelUsage(dogmaLocation): 458 totalFuelPerHour = GetFuelUsagePerHour(dogmaLocation) 459 return totalFuelPerHour * 24 460 461 462 def GetFuelUsagePerHour(dogmaLocation): 463 ship = dogmaLocation.GetShip() 464 totalFuelPerHour = 0 465 for itemID, dogmaItem in ship.GetFittedItems().iteritems(): 466 fuelPerHour = dogmaLocation.GetAccurateAttributeValue(itemID, const.attributeServiceModuleFuelAmount) 467 if fuelPerHour and dogmaItem.IsOnline(): 468 totalFuelPerHour += fuelPerHour 469 470 return totalFuelPerHour 471 472 473 def GetFighterDamage(dogmaLocation): 474 totalDmgFromFighters = 0 475 dpsByPrimaryAbilityID = defaultdict(int) 476 dpsBySecondaryAbilityID = defaultdict(int) 477 dpsByTubeID = defaultdict(int) 478 for eachTubeFlagID in const.fighterTubeFlags: 479 fighterBelongingToTube = dogmaLocation.GetFightersForTube(eachTubeFlagID) 480 if fighterBelongingToTube is None: 481 continue 482 fighterID = fighterBelongingToTube.itemID 483 qty = fighterBelongingToTube.squadronSize 484 primaryDmg, primaryDps, primaryAbilityID = GetPrimaryDamageForSquadron(dogmaLocation, fighterID, fighterBelongingToTube.typeID, qty) 485 secondaryDmg, secondaryDps, secondaryAbilityID = GetSecondaryForSquadron(dogmaLocation, fighterID, fighterBelongingToTube.typeID, qty) 486 totalDmgFromFighters += primaryDmg + secondaryDmg 487 dpsByPrimaryAbilityID[primaryAbilityID] += primaryDps 488 if secondaryDps and secondaryAbilityID is not None: 489 dpsBySecondaryAbilityID[secondaryAbilityID] += secondaryDps 490 dpsByTubeID[eachTubeFlagID] += primaryDps + secondaryDps 491 492 return (totalDmgFromFighters, 493 dpsByTubeID, 494 dpsByPrimaryAbilityID, 495 dpsBySecondaryAbilityID) 496 497 498 def GetPrimaryDamageForSquadron(dogmaLocation, fighterID, typeID, qty): 499 dps, squadronDmg, abilityID = GetDamageForAbilitySlot(dogmaLocation, fighterID, typeID, qty, abilitySlotID=ABILITY_SLOT_0) 500 return (squadronDmg, dps, abilityID) 501 502 503 def GetSecondaryForSquadron(dogmaLocation, fighterID, typeID, qty): 504 dps, squadronDmg, abilityID = GetDamageForAbilitySlot(dogmaLocation, fighterID, typeID, qty, abilitySlotID=ABILITY_SLOT_2) 505 return (squadronDmg, dps, abilityID) 506 507 508 def GetDamageForAbilitySlot(dogmaLocation, fighterID, typeID, qty, abilitySlotID): 509 squadronDmg = 0 510 dps = 0 511 abilityID = GetAbilityIDForSlot(typeID, abilitySlotID) 512 if abilityID: 513 squadronDmg, dps = GetDamageForSquadron(dogmaLocation, fighterID, qty, abilityID) 514 return (dps, squadronDmg, abilityID) 515 516 517 def GetDamageForSquadron(dogmaLocation, fighterID, qty, abilityID): 518 dItem = dogmaLocation.SafeGetDogmaItem(fighterID) 519 if dItem is None: 520 return (0, 0) 521 dmg, dps = GetDamageFromFighter(dogmaLocation, dItem.itemID, abilityID) 522 totalDmg = qty * dmg 523 totalDps = qty * dps 524 return (totalDmg, totalDps) 525 526 527 def GetDamageFromFighter(dogmaLocation, itemID, abilityID): 528 damageMultiplierAttributeID = GetDamageMultiplierAttributeFromAbilityID(abilityID) 529 if damageMultiplierAttributeID is None: 530 return (0, 0) 531 multiplier = dogmaLocation.GetAccurateAttributeValue(itemID, damageMultiplierAttributeID) 532 accDamage = 0 533 abilityAttributeIDs = GetDogmaAttributeIDsForAbilityID(abilityID) 534 durationAttributeID = GetAbilityDurationAttributeID(dogmaLocation.dogmaStaticMgr, abilityID) 535 for attributeID in abilityAttributeIDs: 536 if attributeID not in FIGHTER_DAMAGE_ATTRIBUTES: 537 if attributeID in DURATION_ATTRIBUTES: 538 durationAttributeID = attributeID 539 continue 540 d = dogmaLocation.GetAccurateAttributeValue(itemID, attributeID) 541 accDamage += d * multiplier 542 543 dps = 0 544 if durationAttributeID: 545 duration = dogmaLocation.GetAccurateAttributeValue(itemID, durationAttributeID) 546 if duration: 547 dps = accDamage / duration 548 return (accDamage, dps * 1000) 549 550 551 def GetRangesForAbilitySlot(dogmaLocation, fighterID, typeID, abilitySlotID): 552 maxRange = None 553 falloffDist = None 554 abilityID = GetAbilityIDForSlot(typeID, abilitySlotID) 555 if abilityID: 556 rangeAttributeID, falloffAttributeID = GetAbilityRangeAndFalloffAttributeIDs(dogmaLocation.dogmaStaticMgr, abilityID) 557 if rangeAttributeID: 558 maxRange = dogmaLocation.GetAccurateAttributeValue(fighterID, rangeAttributeID) 559 if falloffAttributeID: 560 falloffDist = dogmaLocation.GetAccurateAttributeValue(fighterID, falloffAttributeID) 561 return (maxRange, falloffDist, abilityID) 562 563 564 def AddDogmaOwnerModifiers(fittingDogmaLocation, fighterID): 565 fighterDogmaItem = fittingDogmaLocation.SafeGetDogmaItem(fighterID) 566 if fighterDogmaItem is not None: 567 fighterDogmaItem.AddFighterControllerOwnerModifiers() 568 569 570 def GetFullAndPartialSquadrons(dogmaLocation): 571 full = 0 572 partial = 0 573 for flagID in const.fighterTubeFlags: 574 dogmaItem = dogmaLocation.GetFightersForTube(flagID) 575 if dogmaItem: 576 squadronSize = dogmaItem.squadronSize 577 if not squadronSize: 578 continue 579 maxInSquadron = GetMaxSquadronSize(dogmaItem.typeID) 580 if squadronSize < maxInSquadron: 581 partial += 1 582 else: 583 full += 1 584 585 return (full, partial) 586 587 588 def GetHardware(dogmaLocation): 589 shipDogmaItem = dogmaLocation.GetShipItem() 590 if not shipDogmaItem: 591 return [] 592 hardwareDict = {} 593 for module in shipDogmaItem.GetFittedItems().itervalues(): 594 typeID = module.typeID 595 if IsCharge(typeID): 596 continue 597 flagID = module.flagID 598 flagInHardware = hardwareDict.get(typeID, None) 599 if flagInHardware: 600 flagID = min(flagInHardware, flagID) 601 hardwareDict[typeID] = flagID 602 603 hardwareList = [ (flagID, typeID) for typeID, flagID in hardwareDict.iteritems() ] 604 lst = sorted(hardwareList, key=lambda data: data[0]) 605 return [ x[1] for x in lst ] 606 607 608 def IsCharge(typeID): 609 return evetypes.GetCategoryID(typeID) == const.categoryCharge