Example #1
0
def applyReps(rrMap, applicationMap):
    totalAmount = RRTypes(shield=0, armor=0, hull=0, capacitor=0)
    for key, repAmount in rrMap.items():
        totalAmount += repAmount * applicationMap.get(key, 0)
    # We do not want to include energy transfers into final value
    totalReps = totalAmount.shield + totalAmount.armor + totalAmount.hull
    return totalReps
Example #2
0
 def addRps(rrKey, addedTimeStart, addedTimeFinish, addedRepAmounts):
     if not addedRepAmounts:
         return
     repAmountSum = sum(addedRepAmounts, RRTypes(0, 0, 0, 0))
     if repAmountSum.shield > 0 or repAmountSum.armor > 0 or repAmountSum.hull > 0:
         addedRps = repAmountSum / (addedTimeFinish - addedTimeStart)
         rrCacheRps = intCacheRps.setdefault(rrKey, [])
         rrCacheRps.append((addedTimeStart, addedTimeFinish, addedRps))
Example #3
0
 def getRepAmountParameters(self, ignoreState=False):
     amount = self.amount if ignoreState else self.amountActive
     if amount <= 0:
         return {}
     if self.__baseRRAmount is None:
         self.__baseRRAmount = {}
         hullAmount = self.getModifiedItemAttr("structureDamageAmount", 0)
         armorAmount = self.getModifiedItemAttr("armorDamageAmount", 0)
         shieldAmount = self.getModifiedItemAttr("shieldBonus", 0)
         if shieldAmount:
             self.__baseRRAmount[0] = RRTypes(
                 shield=shieldAmount * amount,
                 armor=0, hull=0, capacitor=0)
         if armorAmount or hullAmount:
             self.__baseRRAmount[self.cycleTime] = RRTypes(
                 shield=0, armor=armorAmount * amount,
                 hull=hullAmount * amount, capacitor=0)
     return self.__baseRRAmount
Example #4
0
 def getRepAmountParameters(self, spoolOptions=None, ignoreState=False):
     if self.isEmpty or (self.state < FittingModuleState.ACTIVE
                         and not ignoreState):
         return {}
     remoteModuleGroups = {
         "Remote Armor Repairer": "Armor",
         "Ancillary Remote Armor Repairer": "Armor",
         "Mutadaptive Remote Armor Repairer": "Armor",
         "Remote Hull Repairer": "Hull",
         "Remote Shield Booster": "Shield",
         "Ancillary Remote Shield Booster": "Shield",
         "Remote Capacitor Transmitter": "Capacitor"
     }
     rrType = remoteModuleGroups.get(self.item.group.name)
     if rrType is None:
         return {}
     if self.__baseRRAmount is None:
         self.__baseRRAmount = {}
         shieldAmount = 0
         armorAmount = 0
         hullAmount = 0
         capacitorAmount = 0
         if rrType == "Hull":
             hullAmount += self.getModifiedItemAttr("structureDamageAmount",
                                                    0)
         elif rrType == "Armor":
             if self.item.group.name == "Ancillary Remote Armor Repairer" and self.charge:
                 mult = self.getModifiedItemAttr(
                     "chargedArmorDamageMultiplier", 1)
             else:
                 mult = 1
             armorAmount += self.getModifiedItemAttr(
                 "armorDamageAmount", 0) * mult
         elif rrType == "Shield":
             shieldAmount += self.getModifiedItemAttr("shieldBonus", 0)
         elif rrType == "Capacitor":
             capacitorAmount += self.getModifiedItemAttr(
                 "powerTransferAmount", 0)
         rrDelay = 0 if rrType == "Shield" else self.rawCycleTime
         self.__baseRRAmount[rrDelay] = RRTypes(shield=shieldAmount,
                                                armor=armorAmount,
                                                hull=hullAmount,
                                                capacitor=capacitorAmount)
     spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self)
     spoolBoost = calculateSpoolup(
         self.getModifiedItemAttr("repairMultiplierBonusMax", 0),
         self.getModifiedItemAttr("repairMultiplierBonusPerCycle", 0),
         self.rawCycleTime / 1000, spoolType, spoolAmount)[0]
     spoolMultiplier = 1 + spoolBoost
     adjustedRRAmount = {}
     for rrTime, rrAmount in self.__baseRRAmount.items():
         if spoolMultiplier == 1:
             adjustedRRAmount[rrTime] = rrAmount
         else:
             adjustedRRAmount[rrTime] = rrAmount * spoolMultiplier
     return adjustedRRAmount
Example #5
0
 def getRemoteReps(self, ignoreState=False):
     rrDuringCycle = RRTypes(0, 0, 0, 0)
     cycleParams = self.getCycleParameters()
     if cycleParams is None:
         return rrDuringCycle
     repAmountParams = self.getRepAmountParameters(ignoreState=ignoreState)
     avgCycleTime = cycleParams.averageTime
     if len(repAmountParams) == 0 or avgCycleTime == 0:
         return rrDuringCycle
     for rrAmount in repAmountParams.values():
         rrDuringCycle += rrAmount
     rrFactor = 1 / (avgCycleTime / 1000)
     rrDuringCycle *= rrFactor
     return rrDuringCycle
Example #6
0
 def getRemoteReps(self, spoolOptions=None, ignoreState=False, reloadOverride=None):
     rrDuringCycle = RRTypes(0, 0, 0, 0)
     cycleParams = self.getCycleParameters(reloadOverride=reloadOverride)
     if cycleParams is None:
         return rrDuringCycle
     repAmountParams = self.getRepAmountParameters(spoolOptions=spoolOptions, ignoreState=ignoreState)
     avgCycleTime = cycleParams.averageTime
     if len(repAmountParams) == 0 or avgCycleTime == 0:
         return rrDuringCycle
     for rrAmount in repAmountParams.values():
         rrDuringCycle += rrAmount
     rrFactor = 1 / (avgCycleTime / 1000)
     rps = rrDuringCycle * rrFactor
     return rps
Example #7
0
 def prepareRpsData(self, src, ancReload, 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, ancReload=ancReload, maxTime=maxTime)
     fitCache = self._data[src.item.ID][ancReload]
     # Final cache has been generated already, don't do anything
     if 'finalRps' in fitCache:
         return
     # Convert cache from segments with assigned values into points
     # which are located at times when rps value changes
     pointCache = {}
     for key, rpsList in fitCache['internalRps'].items():
         pointData = pointCache[key] = {}
         prevRps = None
         prevTimeEnd = None
         for timeStart, timeEnd, rps in rpsList:
             # First item
             if not pointData:
                 pointData[timeStart] = rps
             # Gap between items
             elif floatUnerr(prevTimeEnd) < floatUnerr(timeStart):
                 pointData[prevTimeEnd] = RRTypes(0, 0, 0, 0)
                 pointData[timeStart] = rps
             # Changed value
             elif rps != prevRps:
                 pointData[timeStart] = rps
             prevRps = rps
             prevTimeEnd = timeEnd
     # We have data in another form, do not need old one any longer
     del fitCache['internalRps']
     changesByTime = {}
     for key, rpsMap in pointCache.items():
         for time in rpsMap:
             changesByTime.setdefault(time, []).append(key)
     # Here we convert cache to following format:
     # {time: {key: rps}
     finalRpsCache = fitCache['finalRps'] = {}
     timeRpsData = {}
     for time in sorted(changesByTime):
         timeRpsData = copy(timeRpsData)
         for key in changesByTime[time]:
             timeRpsData[key] = pointCache[key][time]
         finalRpsCache[time] = timeRpsData
Example #8
0
    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"])
Example #9
0
def repsSection(fit):
    """ Returns the text of the repairs section"""
    selfRep = [
        fit.effectiveTank[tankType + "Repair"] for tankType in tankTypes
    ]
    sustainRep = [
        fit.effectiveSustainableTank[tankType + "Repair"]
        for tankType in tankTypes
    ]
    remoteRepObj = fit.getRemoteReps()
    remoteRep = [remoteRepObj.shield, remoteRepObj.armor, remoteRepObj.hull]
    shieldRegen = [fit.effectiveSustainableTank["passiveShield"], 0, 0]
    shieldRechargeModuleMultipliers = [
        module.item.attributes["shieldRechargeRateMultiplier"].value
        for module in fit.modules if module.item
        and "shieldRechargeRateMultiplier" in module.item.attributes
    ]
    shieldRechargeMultiplierByModules = reduce(
        lambda x, y: x * y, shieldRechargeModuleMultipliers, 1)
    if shieldRechargeMultiplierByModules >= 0.9:  # If the total affect of modules on the shield recharge is negative or insignificant, we don't care about it
        shieldRegen[0] = 0
    totalRep = list(zip(selfRep, remoteRep, shieldRegen))
    totalRep = list(map(sum, totalRep))

    selfRep.append(sum(selfRep))
    sustainRep.append(sum(sustainRep))
    remoteRep.append(sum(remoteRep))
    shieldRegen.append(sum(shieldRegen))
    totalRep.append(sum(totalRep))

    totalSelfRep = selfRep[-1]
    totalRemoteRep = remoteRep[-1]
    totalShieldRegen = shieldRegen[-1]

    text = ""

    if sum(
            totalRep
    ) > 0:  # Most commonly, there are no reps at all; then we skip this section
        singleTypeRep = None
        singleTypeRepName = None
        if totalRemoteRep == 0 and totalShieldRegen == 0:  # Only self rep
            singleTypeRep = selfRep[:-1]
            singleTypeRepName = "Self"
        if totalSelfRep == 0 and totalShieldRegen == 0:  # Only remote rep
            singleTypeRep = remoteRep[:-1]
            singleTypeRepName = "Remote"
        if totalSelfRep == 0 and totalRemoteRep == 0:  # Only shield regen
            singleTypeRep = shieldRegen[:-1]
            singleTypeRepName = "Regen"
        if singleTypeRep and sum(
                x > 0 for x in singleTypeRep
        ) == 1:  # Only one type of reps and only one tank type is repaired
            index = next(i for i, v in enumerate(singleTypeRep) if v > 0)
            if singleTypeRepName == "Regen":
                text += "Shield regeneration: {} EHP/s".format(
                    formatAmount(singleTypeRep[index], 3, 0, 9))
            else:
                text += "{} {} repair: {} EHP/s".format(
                    singleTypeRepName, tankTypes[index],
                    formatAmount(singleTypeRep[index], 3, 0, 9))
            if (singleTypeRepName
                    == "Self") and (sustainRep[index] != singleTypeRep[index]):
                text += " (Sustained: {} EHP/s)".format(
                    formatAmount(sustainRep[index], 3, 0, 9))
            text += "\n"
        else:  # Otherwise show a table
            selfRepStr = [formatAmount(rep, 3, 0, 9) for rep in selfRep]
            sustainRepStr = [formatAmount(rep, 3, 0, 9) for rep in sustainRep]
            remoteRepStr = [formatAmount(rep, 3, 0, 9) for rep in remoteRep]
            shieldRegenStr = [
                formatAmount(rep, 3, 0, 9) if rep != 0 else ""
                for rep in shieldRegen
            ]
            totalRepStr = [formatAmount(rep, 3, 0, 9) for rep in totalRep]

            lines = RRTypes.names(postProcessor=lambda v: v.capitalize())
            lines.append("Total")
            lines = ["{:<8}".format(line) for line in lines]

            showSelfRepColumn = totalSelfRep > 0
            showSustainRepColumn = sustainRep != selfRep
            showRemoteRepColumn = totalRemoteRep > 0
            showShieldRegenColumn = totalShieldRegen > 0

            header = "REPS    "
            header, lines = _addFormattedColumn(
                (showSelfRepColumn + showSustainRepColumn +
                 showRemoteRepColumn + showShieldRegenColumn > 1), "TOTAL",
                header, lines, totalRepStr)
            header, lines = _addFormattedColumn(showSelfRepColumn, "SELF",
                                                header, lines, selfRepStr)
            header, lines = _addFormattedColumn(showSustainRepColumn, "SUST",
                                                header, lines, sustainRepStr)
            header, lines = _addFormattedColumn(showRemoteRepColumn, "REMOTE",
                                                header, lines, remoteRepStr)
            header, lines = _addFormattedColumn(showShieldRegenColumn, "REGEN",
                                                header, lines, shieldRegenStr)

            text += header + "\n"
            repsByTank = zip(totalRep, selfRep, sustainRep, remoteRep,
                             shieldRegen)
            for line in lines:
                reps = next(repsByTank)
                if sum(reps) > 0:
                    text += line + "\n"
    return text
Example #10
0
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:
Example #11
0
def test_rrtypes_names_lambda():
    assert RRTypes.names(
        True, lambda v: v.capitalize()) == ['Shield', 'Armor', 'Hull']
    assert RRTypes.names(postProcessor=lambda v: v.upper(), ehpOnly=False) == [
        'SHIELD', 'ARMOR', 'HULL', 'CAPACITOR'
    ]
Example #12
0
def test_rrtypes_names():
    assert RRTypes.names() == ['shield', 'armor', 'hull']
    assert RRTypes.names(True) == ['shield', 'armor', 'hull']
    assert RRTypes.names(ehpOnly=True) == ['shield', 'armor', 'hull']
    assert RRTypes.names(False) == ['shield', 'armor', 'hull', 'capacitor']
Example #13
0
def setup_rr_types():
    return RRTypes(10, 20, 30, 40)