def getVolley(self, targetResists=None): if not self.active or self.amountActive <= 0: return DmgTypes(0, 0, 0, 0) if self.__baseVolley is None: em = 0 therm = 0 kin = 0 exp = 0 for ability in self.abilities: # Not passing resists here as we want to calculate and store base volley abilityVolley = ability.getVolley() em += abilityVolley.em therm += abilityVolley.thermal kin += abilityVolley.kinetic exp += abilityVolley.explosive self.__baseVolley = DmgTypes(em, therm, kin, exp) volley = DmgTypes(em=self.__baseVolley.em * (1 - getattr(targetResists, "emAmount", 0)), thermal=self.__baseVolley.thermal * (1 - getattr(targetResists, "thermalAmount", 0)), kinetic=self.__baseVolley.kinetic * (1 - getattr(targetResists, "kineticAmount", 0)), explosive=self.__baseVolley.explosive * (1 - getattr(targetResists, "explosiveAmount", 0))) return volley
def getDps(self, targetResists=None): if not self.active or self.amountActive <= 0: return DmgTypes(0, 0, 0, 0) # Analyze cooldowns when reload is factored in if self.owner.factorReload: activeTimes = [] reloadTimes = [] peakEm = 0 peakTherm = 0 peakKin = 0 peakExp = 0 steadyEm = 0 steadyTherm = 0 steadyKin = 0 steadyExp = 0 for ability in self.abilities: abilityDps = ability.getDps(targetResists=targetResists) # Peak dps peakEm += abilityDps.em peakTherm += abilityDps.thermal peakKin += abilityDps.kinetic peakExp += abilityDps.explosive # Infinite use - add to steady dps if ability.numShots == 0: steadyEm += abilityDps.em steadyTherm += abilityDps.thermal steadyKin += abilityDps.kinetic steadyExp += abilityDps.explosive else: activeTimes.append(ability.numShots * ability.cycleTime) reloadTimes.append(ability.reloadTime) steadyDps = DmgTypes(steadyEm, steadyTherm, steadyKin, steadyExp) if len(activeTimes) > 0: shortestActive = sorted(activeTimes)[0] longestReload = sorted(reloadTimes, reverse=True)[0] peakDps = DmgTypes(peakEm, peakTherm, peakKin, peakExp) peakAdjustFactor = shortestActive / (shortestActive + longestReload) peakDpsAdjusted = DmgTypes( em=peakDps.em * peakAdjustFactor, thermal=peakDps.thermal * peakAdjustFactor, kinetic=peakDps.kinetic * peakAdjustFactor, explosive=peakDps.explosive * peakAdjustFactor) dps = max(steadyDps, peakDpsAdjusted, key=lambda d: d.total) return dps else: return steadyDps # Just sum all abilities when not taking reload into consideration else: em = 0 therm = 0 kin = 0 exp = 0 for ability in self.abilities: abilityDps = ability.getDps(targetResists=targetResists) em += abilityDps.em therm += abilityDps.thermal kin += abilityDps.kinetic exp += abilityDps.explosive return DmgTypes(em, therm, kin, exp)
def getVolley(self, spoolOptions=None, targetResists=None, ignoreState=False): if self.isEmpty or (self.state < FittingModuleState.ACTIVE and not ignoreState): return DmgTypes(0, 0, 0, 0) if self.__baseVolley is None: dmgGetter = self.getModifiedChargeAttr if self.charge else self.getModifiedItemAttr dmgMult = self.getModifiedItemAttr("damageMultiplier", 1) self.__baseVolley = DmgTypes( em=(dmgGetter("emDamage", 0)) * dmgMult, thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) spoolBoost = calculateSpoolup( self.getModifiedItemAttr("damageMultiplierBonusMax", 0), self.getModifiedItemAttr("damageMultiplierBonusPerCycle", 0), self.rawCycleTime / 1000, spoolType, spoolAmount)[0] spoolMultiplier = 1 + spoolBoost volley = DmgTypes(em=self.__baseVolley.em * spoolMultiplier * (1 - getattr(targetResists, "emAmount", 0)), thermal=self.__baseVolley.thermal * spoolMultiplier * (1 - getattr(targetResists, "thermalAmount", 0)), kinetic=self.__baseVolley.kinetic * spoolMultiplier * (1 - getattr(targetResists, "kineticAmount", 0)), explosive=self.__baseVolley.explosive * spoolMultiplier * (1 - getattr(targetResists, "explosiveAmount", 0))) return volley
def getVolley(self, targetResists=None): if not self.dealsDamage or not self.active: return DmgTypes(0, 0, 0, 0) if self.attrPrefix == "fighterAbilityLaunchBomb": em = self.fighter.getModifiedChargeAttr("emDamage", 0) therm = self.fighter.getModifiedChargeAttr("thermalDamage", 0) kin = self.fighter.getModifiedChargeAttr("kineticDamage", 0) exp = self.fighter.getModifiedChargeAttr("explosiveDamage", 0) else: em = self.fighter.getModifiedItemAttr( "{}DamageEM".format(self.attrPrefix), 0) therm = self.fighter.getModifiedItemAttr( "{}DamageTherm".format(self.attrPrefix), 0) kin = self.fighter.getModifiedItemAttr( "{}DamageKin".format(self.attrPrefix), 0) exp = self.fighter.getModifiedItemAttr( "{}DamageExp".format(self.attrPrefix), 0) dmgMult = self.fighter.amountActive * self.fighter.getModifiedItemAttr( "{}DamageMultiplier".format(self.attrPrefix), 1) volley = DmgTypes(em=em * dmgMult * (1 - getattr(targetResists, "emAmount", 0)), thermal=therm * dmgMult * (1 - getattr(targetResists, "thermalAmount", 0)), kinetic=kin * dmgMult * (1 - getattr(targetResists, "kineticAmount", 0)), explosive=exp * dmgMult * (1 - getattr(targetResists, "explosiveAmount", 0))) return volley
def getVolleyParameters(self, spoolOptions=None, targetProfile=None, ignoreState=False): if self.isEmpty or (self.state < FittingModuleState.ACTIVE and not ignoreState): return {0: DmgTypes(0, 0, 0, 0)} if self.__baseVolley is None: self.__baseVolley = {} dmgGetter = self.getModifiedChargeAttr if self.charge else self.getModifiedItemAttr dmgMult = self.getModifiedItemAttr("damageMultiplier", 1) # Some delay attributes have non-0 default value, so we have to pick according to effects if { 'superWeaponAmarr', 'superWeaponCaldari', 'superWeaponGallente', 'superWeaponMinmatar', 'lightningWeapon' }.intersection(self.item.effects): dmgDelay = self.getModifiedItemAttr("damageDelayDuration", 0) elif {'doomsdayBeamDOT', 'doomsdaySlash', 'doomsdayConeDOT'}.intersection(self.item.effects): dmgDelay = self.getModifiedItemAttr("doomsdayWarningDuration", 0) else: dmgDelay = 0 dmgDuration = self.getModifiedItemAttr("doomsdayDamageDuration", 0) dmgSubcycle = self.getModifiedItemAttr("doomsdayDamageCycleTime", 0) # Reaper DD can damage each target only once if dmgDuration != 0 and dmgSubcycle != 0 and 'doomsdaySlash' not in self.item.effects: subcycles = math.floor(floatUnerr(dmgDuration / dmgSubcycle)) else: subcycles = 1 for i in range(subcycles): self.__baseVolley[dmgDelay + dmgSubcycle * i] = DmgTypes( em=(dmgGetter("emDamage", 0)) * dmgMult, thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) spoolBoost = calculateSpoolup( self.getModifiedItemAttr("damageMultiplierBonusMax", 0), self.getModifiedItemAttr("damageMultiplierBonusPerCycle", 0), self.rawCycleTime / 1000, spoolType, spoolAmount)[0] spoolMultiplier = 1 + spoolBoost adjustedVolley = {} for volleyTime, volleyValue in self.__baseVolley.items(): adjustedVolley[volleyTime] = DmgTypes( em=volleyValue.em * spoolMultiplier * (1 - getattr(targetProfile, "emAmount", 0)), thermal=volleyValue.thermal * spoolMultiplier * (1 - getattr(targetProfile, "thermalAmount", 0)), kinetic=volleyValue.kinetic * spoolMultiplier * (1 - getattr(targetProfile, "kineticAmount", 0)), explosive=volleyValue.explosive * spoolMultiplier * (1 - getattr(targetProfile, "explosiveAmount", 0))) return adjustedVolley
def getDps(self, targetResists=None): volley = self.getVolley(targetResists=targetResists) if not volley: return DmgTypes(0, 0, 0, 0) dpsFactor = 1 / (self.cycleTime / 1000) dps = DmgTypes(em=volley.em * dpsFactor, thermal=volley.thermal * dpsFactor, kinetic=volley.kinetic * dpsFactor, explosive=volley.explosive * dpsFactor) return dps
def _prepareDpsVolleyData(self, src, maxTime): # Time is none means that time parameter has to be ignored, # we do not need cache for that if maxTime is None: return True self._generateInternalForm(src=src, maxTime=maxTime) fitCache = self._data[src.item.ID] # Final cache has been generated already, don't do anything if 'finalDps' in fitCache and 'finalVolley' in fitCache: return # Convert cache from segments with assigned values into points # which are located at times when dps/volley values change pointCache = {} for key, dmgList in fitCache['internalDpsVolley'].items(): pointData = pointCache[key] = {} prevDps = None prevVolley = None prevTimeEnd = None for timeStart, timeEnd, dps, volley in dmgList: # First item if not pointData: pointData[timeStart] = (dps, volley) # Gap between items elif floatUnerr(prevTimeEnd) < floatUnerr(timeStart): pointData[prevTimeEnd] = (DmgTypes(0, 0, 0, 0), DmgTypes(0, 0, 0, 0)) pointData[timeStart] = (dps, volley) # Changed value elif dps != prevDps or volley != prevVolley: pointData[timeStart] = (dps, volley) prevDps = dps prevVolley = volley prevTimeEnd = timeEnd # We have data in another form, do not need old one any longer del fitCache['internalDpsVolley'] changesByTime = {} for key, dmgMap in pointCache.items(): for time in dmgMap: changesByTime.setdefault(time, []).append(key) # Here we convert cache to following format: # {time: {key: (dps, volley}} finalDpsCache = fitCache['finalDps'] = {} finalVolleyCache = fitCache['finalVolley'] = {} timeDpsData = {} timeVolleyData = {} for time in sorted(changesByTime): timeDpsData = copy(timeDpsData) timeVolleyData = copy(timeVolleyData) for key in changesByTime[time]: dps, volley = pointCache[key][time] timeDpsData[key] = dps timeVolleyData[key] = volley finalDpsCache[time] = timeDpsData finalVolleyCache[time] = timeVolleyData
def applyDamage(dmgMap, applicationMap, tgtResists): total = DmgTypes(em=0, thermal=0, kinetic=0, explosive=0) for key, dmg in dmgMap.items(): total += dmg * applicationMap.get(key, 0) if not GraphSettings.getInstance().get('ignoreResists'): emRes, thermRes, kinRes, exploRes = tgtResists total = DmgTypes(em=total.em * (1 - emRes), thermal=total.thermal * (1 - thermRes), kinetic=total.kinetic * (1 - kinRes), explosive=total.explosive * (1 - exploRes)) return total
def getDps(self, targetProfile=None, cycleTimeOverride=None): volley = self.getVolley(targetProfile=targetProfile) if not volley: return DmgTypes(0, 0, 0, 0) cycleTime = cycleTimeOverride if cycleTimeOverride is not None else self.cycleTime dpsFactor = 1 / (cycleTime / 1000) dps = DmgTypes(em=volley.em * dpsFactor, thermal=volley.thermal * dpsFactor, kinetic=volley.kinetic * dpsFactor, explosive=volley.explosive * dpsFactor) return dps
def getDps(self, targetResists=None): volley = self.getVolley(targetResists=targetResists) if not volley: return DmgTypes(0, 0, 0, 0) cycleAttr = "missileLaunchDuration" if self.hasAmmo else "speed" cycleTime = self.getModifiedItemAttr(cycleAttr) dpsFactor = 1 / (cycleTime / 1000) dps = DmgTypes(em=volley.em * dpsFactor, thermal=volley.thermal * dpsFactor, kinetic=volley.kinetic * dpsFactor, explosive=volley.explosive * dpsFactor) return dps
def getDps(self, targetProfile=None): volley = self.getVolley(targetProfile=targetProfile) if not volley: return DmgTypes(0, 0, 0, 0) cycleParams = self.getCycleParameters() if cycleParams is None: return DmgTypes(0, 0, 0, 0) dpsFactor = 1 / (cycleParams.averageTime / 1000) dps = DmgTypes(em=volley.em * dpsFactor, thermal=volley.thermal * dpsFactor, kinetic=volley.kinetic * dpsFactor, explosive=volley.explosive * dpsFactor) return dps
def getDps(self, spoolOptions=None, targetResists=None, ignoreState=False): volley = self.getVolley(spoolOptions=spoolOptions, targetResists=targetResists, ignoreState=ignoreState) if not volley: return DmgTypes(0, 0, 0, 0) # Some weapons repeat multiple times in one cycle (bosonic doomsdays). Get the number of times it fires off volleysPerCycle = max(self.getModifiedItemAttr("doomsdayDamageDuration", 1) / self.getModifiedItemAttr("doomsdayDamageCycleTime", 1), 1) dpsFactor = volleysPerCycle / (self.cycleTime / 1000) dps = DmgTypes( em=volley.em * dpsFactor, thermal=volley.thermal * dpsFactor, kinetic=volley.kinetic * dpsFactor, explosive=volley.explosive * dpsFactor) return dps
def getDpsPerEffect(self, targetResists=None): if not self.active or self.amountActive <= 0: return {} uptime = self.getUptime() if uptime == 1: return { a.effectID: a.getDps(targetResists=targetResists) for a in self.abilities } # Decide if it's better to keep steady dps up and never reload or reload from time to time dpsMapSteady = {} dpsMapPeakAdjusted = {} for ability in self.abilities: abilityDps = ability.getDps(targetResists=targetResists) dpsMapPeakAdjusted[ability.effectID] = DmgTypes( em=abilityDps.em * uptime, thermal=abilityDps.thermal * uptime, kinetic=abilityDps.kinetic * uptime, explosive=abilityDps.explosive * uptime) # Infinite use - add to steady dps if ability.numShots == 0: dpsMapSteady[ability.effectID] = abilityDps totalSteady = sum(i.total for i in dpsMapSteady.values()) totalPeakAdjusted = sum(i.total for i in dpsMapPeakAdjusted.values()) return dpsMapSteady if totalSteady >= totalPeakAdjusted else dpsMapPeakAdjusted
def getVolleyParameters(self, targetResists=None): if not self.dealsDamage or self.amountActive <= 0: return {0: DmgTypes(0, 0, 0, 0)} if self.__baseVolley is None: dmgGetter = self.getModifiedChargeAttr if self.hasAmmo else self.getModifiedItemAttr dmgMult = self.amountActive * (self.getModifiedItemAttr("damageMultiplier", 1)) self.__baseVolley = DmgTypes( em=(dmgGetter("emDamage", 0)) * dmgMult, thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) volley = DmgTypes( em=self.__baseVolley.em * (1 - getattr(targetResists, "emAmount", 0)), thermal=self.__baseVolley.thermal * (1 - getattr(targetResists, "thermalAmount", 0)), kinetic=self.__baseVolley.kinetic * (1 - getattr(targetResists, "kineticAmount", 0)), explosive=self.__baseVolley.explosive * (1 - getattr(targetResists, "explosiveAmount", 0))) return {0: volley}
def getVolleyParameters(self, spoolOptions=None, targetResists=None, ignoreState=False): if self.isEmpty or (self.state < FittingModuleState.ACTIVE and not ignoreState): return {0: DmgTypes(0, 0, 0, 0)} if self.__baseVolley is None: self.__baseVolley = {} dmgGetter = self.getModifiedChargeAttr if self.charge else self.getModifiedItemAttr dmgMult = self.getModifiedItemAttr("damageMultiplier", 1) dmgDelay = self.getModifiedItemAttr( "damageDelayDuration", 0) or self.getModifiedItemAttr( "doomsdayWarningDuration", 0) dmgDuration = self.getModifiedItemAttr("doomsdayDamageDuration", 0) dmgSubcycle = self.getModifiedItemAttr("doomsdayDamageCycleTime", 0) if dmgDuration != 0 and dmgSubcycle != 0: subcycles = math.floor(floatUnerr(dmgDuration / dmgSubcycle)) else: subcycles = 1 for i in range(subcycles): self.__baseVolley[dmgDelay + dmgSubcycle * i] = DmgTypes( em=(dmgGetter("emDamage", 0)) * dmgMult, thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) spoolBoost = calculateSpoolup( self.getModifiedItemAttr("damageMultiplierBonusMax", 0), self.getModifiedItemAttr("damageMultiplierBonusPerCycle", 0), self.rawCycleTime / 1000, spoolType, spoolAmount)[0] spoolMultiplier = 1 + spoolBoost adjustedVolley = {} for volleyTime, volleyValue in self.__baseVolley.items(): adjustedVolley[volleyTime] = DmgTypes( em=volleyValue.em * spoolMultiplier * (1 - getattr(targetResists, "emAmount", 0)), thermal=volleyValue.thermal * spoolMultiplier * (1 - getattr(targetResists, "thermalAmount", 0)), kinetic=volleyValue.kinetic * spoolMultiplier * (1 - getattr(targetResists, "kineticAmount", 0)), explosive=volleyValue.explosive * spoolMultiplier * (1 - getattr(targetResists, "explosiveAmount", 0))) return adjustedVolley
def getDps(self, spoolOptions=None, targetProfile=None, ignoreState=False): dmgDuringCycle = DmgTypes(0, 0, 0, 0) cycleParams = self.getCycleParameters() if cycleParams is None: return dmgDuringCycle volleyParams = self.getVolleyParameters(spoolOptions=spoolOptions, targetProfile=targetProfile, ignoreState=ignoreState) avgCycleTime = cycleParams.averageTime if len(volleyParams) == 0 or avgCycleTime == 0: return dmgDuringCycle for volleyValue in volleyParams.values(): dmgDuringCycle += volleyValue dpsFactor = 1 / (avgCycleTime / 1000) dps = DmgTypes( em=dmgDuringCycle.em * dpsFactor, thermal=dmgDuringCycle.thermal * dpsFactor, kinetic=dmgDuringCycle.kinetic * dpsFactor, explosive=dmgDuringCycle.explosive * dpsFactor) return dps
def getVolley(self, spoolOptions=None, targetProfile=None, ignoreState=False): volleyParams = self.getVolleyParameters(spoolOptions=spoolOptions, targetProfile=targetProfile, ignoreState=ignoreState) if len(volleyParams) == 0: return DmgTypes(0, 0, 0, 0) return volleyParams[min(volleyParams)]
def getDps(self, targetProfile=None): em = 0 thermal = 0 kinetic = 0 explosive = 0 for dps in self.getDpsPerEffect(targetProfile=targetProfile).values(): em += dps.em thermal += dps.thermal kinetic += dps.kinetic explosive += dps.explosive return DmgTypes(em=em, thermal=thermal, kinetic=kinetic, explosive=explosive)
def missileSorter(charge): # Get charge damage type and total damage chargeDamageType, totalDamage = getChargeDamageInfo(charge) # Find its position in sort list try: position = DmgTypes.names().index(chargeDamageType) # Put charges which have non-standard damage type after charges with # standard damage type except ValueError: position = math.inf return position, totalDamage, charge.name
def getVolley(self, targetProfile=None): volleyParams = self.getVolleyParametersPerEffect(targetProfile=targetProfile) em = 0 therm = 0 kin = 0 exp = 0 for volleyData in volleyParams.values(): em += volleyData[0].em therm += volleyData[0].thermal kin += volleyData[0].kinetic exp += volleyData[0].explosive return DmgTypes(em, therm, kin, exp)
def addDpsVolley(ddKey, addedTimeStart, addedTimeFinish, addedVolleys): if not addedVolleys: return volleySum = sum(addedVolleys, DmgTypes(0, 0, 0, 0)) if volleySum.total > 0: addedDps = volleySum / (addedTimeFinish - addedTimeStart) # We can take "just best" volley, no matter target resistances, because all # known items have the same damage type ratio throughout their cycle - and # applying resistances doesn't change final outcome bestVolley = max(addedVolleys, key=lambda v: v.total) ddCacheDps = intCacheDpsVolley.setdefault(ddKey, []) ddCacheDps.append( (addedTimeStart, addedTimeFinish, addedDps, bestVolley))
def turretSorter(charge): damage = 0 range_ = (mod.item.getAttribute('maxRange')) * \ (charge.getAttribute('weaponRangeMultiplier') or 1) falloff = (mod.item.getAttribute('falloff') or 0) * \ (charge.getAttribute('fallofMultiplier') or 1) for type_ in DmgTypes.names(): d = charge.getAttribute('%sDamage' % type_) if d > 0: damage += d # Take optimal and falloff as range factor rangeFactor = range_ + falloff return -rangeFactor, charge.typeName.rsplit( )[-2:], damage, charge.name
def getVolleyParametersPerEffect(self, targetProfile=None): if not self.active or self.amountActive <= 0: return {} if self.__baseVolley is None: self.__baseVolley = {} for ability in self.abilities: # Not passing resists here as we want to calculate and store base volley self.__baseVolley[ability.effectID] = {0: ability.getVolley()} adjustedVolley = {} for effectID, effectData in self.__baseVolley.items(): adjustedVolley[effectID] = {} for volleyTime, volleyValue in effectData.items(): adjustedVolley[effectID][volleyTime] = DmgTypes( em=volleyValue.em * (1 - getattr(targetProfile, "emAmount", 0)), thermal=volleyValue.thermal * (1 - getattr(targetProfile, "thermalAmount", 0)), kinetic=volleyValue.kinetic * (1 - getattr(targetProfile, "kineticAmount", 0)), explosive=volleyValue.explosive * (1 - getattr(targetProfile, "explosiveAmount", 0))) return adjustedVolley
def getChargeDamageInfo(charge): # Set up data storage for missile damage stuff damageMap = {} totalDamage = 0 # Fill them with the data about charge for damageType in DmgTypes.names(): currentDamage = charge.getAttribute( '{}Damage'.format(damageType)) or 0 damageMap[damageType] = currentDamage totalDamage += currentDamage # Detect type of ammo chargeDamageType = None for damageType in damageMap: # If all damage belongs to certain type purely, set appropriate # ammoType if damageMap[damageType] == totalDamage: chargeDamageType = damageType break # Else consider ammo as mixed damage if chargeDamageType is None: chargeDamageType = 'mixed' return chargeDamageType, totalDamage
def generalOutput(): rowNames = ["EHP"] rowNames.extend(RRTypes.names(postProcessor=lambda v: v.capitalize())) colNames = DmgTypes.names(short=True, postProcessor=lambda v: " " + v.capitalize()) colNames[0] = colNames[0][1::] outputScheme = [] for index, rowName in enumerate(rowNames): row = rowName + ": {:>} (" subsValue = " {:.0%}," if index > 0 else " {:>}," row += ''.join([(colName + ":" + subsValue) for colName in colNames]) row = row[:-1:] + ")\n" outputScheme.append(row) return \ outputScheme[0].format(ehpStr[3], *ehpAgainstDamageTypeStr) + \ outputScheme[1].format(ehpStr[0], *resists["shield"]) + \ outputScheme[2].format(ehpStr[1], *resists["armor"]) + \ outputScheme[3].format(ehpStr[2], *resists["hull"])
from functools import reduce from eos.saveddata.damagePattern import DamagePattern from eos.utils.stats import RRTypes, DmgTypes from gui.utils.numberFormatter import formatAmount tankTypes = RRTypes.names() damageTypes = DmgTypes.names() damagePatterns = [ DamagePattern.oneType(damageType) for damageType in damageTypes ] damageTypeResonanceNames = [ damageType.capitalize() + "DamageResonance" for damageType in damageTypes ] resonanceNames = { tankTypes[0]: [tankTypes[0] + s for s in damageTypeResonanceNames], tankTypes[1]: [tankTypes[1] + s for s in damageTypeResonanceNames], tankTypes[2]: [s[0].lower() + s[1:] for s in damageTypeResonanceNames] } def firepowerSection(fit): """ Returns the text of the firepower section""" totalDps = fit.getTotalDps().total weaponDps = fit.getWeaponDps().total droneDps = fit.getDroneDps().total totalVolley = fit.getTotalVolley().total firepower = [totalDps, weaponDps, droneDps, totalVolley] firepowerStr = [formatAmount(dps, 3, 0, 0) for dps in firepower] # showWeaponAndDroneDps = (weaponDps > 0) and (droneDps > 0) if sum(firepower) == 0:
def setup_damage_types(): return DmgTypes(10, 20, 30, 40)
def test_dmgtypes_names(): assert DmgTypes.names() == ['em', 'thermal', 'kinetic', 'explosive'] assert DmgTypes.names(True) == ['em', 'th', 'kin', 'exp'] assert DmgTypes.names(short=True) == ['em', 'th', 'kin', 'exp']
def test_dmgtypes_names_lambda(): assert DmgTypes.names(False, lambda v: v.capitalize()) == [ 'Em', 'Thermal', 'Kinetic', 'Explosive' ] assert DmgTypes.names(True, lambda v: v.upper()) == ['EM', 'TH', 'KIN', 'EXP']