Exemplo n.º 1
0
 def dpsToolTip(preSpool, fullSpool, prec, lowest, highest):
     if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
         return ""
     else:
         return "Spool up: {}-{}".format(
             formatAmount(preSpool, prec, lowest, highest),
             formatAmount(fullSpool, prec, lowest, highest))
Exemplo n.º 2
0
 def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest):
     if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
         return False, text
     else:
         return True, "{}\nSpool up: {}-{}".format(
             text, formatAmount(preSpool, prec, lowest, highest),
             formatAmount(fullSpool, prec, lowest, highest))
Exemplo n.º 3
0
 def dpsToolTip(preSpool, fullSpool, prec, lowest, highest):
     if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
         return ""
     else:
         return "Spool up: {}-{}".format(
             formatAmount(preSpool, prec, lowest, highest),
             formatAmount(fullSpool, prec, lowest, highest))
Exemplo n.º 4
0
 def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest):
     if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
         return False, text
     else:
         return True, "{}\nSpool up: {}-{}".format(
             text,
             formatAmount(preSpool, prec, lowest, highest),
             formatAmount(fullSpool, prec, lowest, highest))
Exemplo n.º 5
0
 def getYForX(self, fit, extraData, x):
     time = x * 1000
     cache = self._cache[fit.ID]
     closestTime = max((t for t in cache if t <= time), default=None)
     if closestTime is None:
         return 0
     return roundToPrec(cache[closestTime], 6)
Exemplo n.º 6
0
 def getYForX(self, fit, extraData, x):
     time = x * 1000
     cache = self._cache[fit.ID]
     closestTime = max((t for t in cache if t <= time), default=None)
     if closestTime is None:
         return 0
     return roundToPrec(cache[closestTime], 6)
Exemplo n.º 7
0
 def addYMark(val):
     if val is None:
         return
     rounded = roundToPrec(val, 4)
     # If due to some bug or insufficient plot density we're
     # out of bounds, do not add anything
     if minY <= val <= maxY or minY <= rounded <= maxY:
         yMarks.add(rounded)
Exemplo n.º 8
0
 def addYMark(val):
     if val is None:
         return
     # If due to some bug or insufficient plot density we're
     # out of bounds, do not add anything
     if minY <= val <= maxY:
         if abs(val) < 0.0001:
             val = 0
         else:
             val = roundToPrec(val, 4)
         yMarks.add(val)
Exemplo n.º 9
0
 def addYMark(val):
     if val is None:
         return
     # Round according to shown Y range - the bigger the range,
     # the rougher the rounding
     if yDiff != 0:
         rounded = roundToPrec(val, 4, nsValue=yDiff)
     else:
         rounded = val
     # If due to some bug or insufficient plot density we're
     # out of bounds, do not add anything
     if minY <= val <= maxY or minY <= rounded <= maxY:
         yMarks.add(rounded)
Exemplo n.º 10
0
Arquivo: muta.py Projeto: tarr43/m-t-p
def renderMutant(mutant, firstPrefix='', prefix=''):
    exportLines = []
    mutatedAttrs = {}
    for attrID, mutator in mutant.mutators.items():
        attrName = getAttributeInfo(attrID).name
        mutatedAttrs[attrName] = mutator.value
    exportLines.append('{}{}'.format(firstPrefix, mutant.baseItem.name))
    exportLines.append('{}{}'.format(prefix, mutant.mutaplasmid.item.name))
    # Round to 7th significant number to avoid exporting float errors
    customAttrsLine = ', '.join(
        '{} {}'.format(a, roundToPrec(mutatedAttrs[a], 7))
        for a in sorted(mutatedAttrs))
    exportLines.append('{}{}'.format(prefix, customAttrsLine))
    return '\n'.join(exportLines)
Exemplo n.º 11
0
def renderMutant(mutant, firstPrefix='', prefix=''):
    exportLines = []
    mutatedAttrs = {}
    for attrID, mutator in mutant.mutators.items():
        attrName = getAttributeInfo(attrID).name
        mutatedAttrs[attrName] = mutator.value
    exportLines.append('{}{}'.format(firstPrefix, mutant.baseItem.name))
    exportLines.append('{}{}'.format(prefix, mutant.mutaplasmid.item.name))
    # Round to 7th significant number to avoid exporting float errors
    customAttrsLine = ', '.join(
        '{} {}'.format(a, roundToPrec(mutatedAttrs[a], 7))
        for a in sorted(mutatedAttrs))
    exportLines.append('{}{}'.format(prefix, customAttrsLine))
    return '\n'.join(exportLines)
Exemplo n.º 12
0
 def getPlotPoints(self, fit, extraData, xRange, xAmount):
     # We deliberately ignore xAmount here to build graph which will reflect
     # all steps of building up the damage
     minX, maxX = self._limitXRange(xRange, fit, extraData)
     if fit.ID not in self._cache:
         self.__generateCache(fit, maxX)
     currentY = None
     prevY = None
     xs = []
     ys = []
     cache = self._cache[fit.ID]
     for time in sorted(cache):
         prevY = currentY
         currentX = time / 1000
         currentY = roundToPrec(cache[time], 6)
         if currentX < minX:
             continue
         # First set of data points
         if not xs:
             # Start at exactly requested time, at last known value
             initialY = prevY or 0
             xs.append(minX)
             ys.append(initialY)
             # If current time is bigger then starting, extend plot to that time with old value
             if currentX > minX:
                 xs.append(currentX)
                 ys.append(initialY)
             # If new value is different, extend it with new point to the new value
             if currentY != prevY:
                 xs.append(currentX)
                 ys.append(currentY)
             continue
         # Last data point
         if currentX >= maxX:
             xs.append(maxX)
             ys.append(prevY)
             break
         # Anything in-between
         if currentY != prevY:
             if prevY is not None:
                 xs.append(currentX)
                 ys.append(prevY)
             xs.append(currentX)
             ys.append(currentY)
     if max(xs) < maxX:
         xs.append(maxX)
         ys.append(currentY or 0)
     return xs, ys
Exemplo n.º 13
0
 def getToolTip(self, mod):
     lines = []
     missileRangeData = mod.missileMaxRangeData if hasattr(
         mod, "missileMaxRangeData") else None
     if missileRangeData is not None:
         lines.append('Missile flight range')
         lowerRange, higherRange, higherChance = missileRangeData
         if roundToPrec(higherChance, 3) not in (0, 1):
             lines.append('{}% chance to fly {}m'.format(
                 formatAmount((1 - higherChance) * 100,
                              prec=3,
                              lowest=0,
                              highest=0),
                 formatAmount(lowerRange, prec=3, lowest=0, highest=3)))
             lines.append('{}% chance to fly {}m'.format(
                 formatAmount(higherChance * 100,
                              prec=3,
                              lowest=0,
                              highest=0),
                 formatAmount(higherRange, prec=3, lowest=0, highest=3)))
     else:
         lines.append("Optimal + Falloff")
     return '\n'.join(lines)
Exemplo n.º 14
0
 def hasSpoolUp(preSpool, fullSpool):
     if preSpool is None or fullSpool is None:
         return False
     return roundToPrec(preSpool.total, prec) != roundToPrec(
         fullSpool.total, prec)
Exemplo n.º 15
0
    def draw(self, accurateMarks=True):
        self.subplot.clear()
        self.subplot.grid(True)
        allXs = set()
        allYs = set()
        plotData = {}
        legendData = []
        chosenX = self.graphFrame.ctrlPanel.xType
        chosenY = self.graphFrame.ctrlPanel.yType
        self.subplot.set(xlabel=self.graphFrame.ctrlPanel.formatLabel(chosenX),
                         ylabel=self.graphFrame.ctrlPanel.formatLabel(chosenY))

        mainInput, miscInputs = self.graphFrame.ctrlPanel.getValues()
        view = self.graphFrame.getView()
        sources = self.graphFrame.ctrlPanel.sources
        if view.hasTargets:
            iterList = tuple(
                itertools.product(sources, self.graphFrame.ctrlPanel.targets))
        else:
            iterList = tuple((f, None) for f in sources)

        # Draw plot lines and get data for legend
        for source, target in iterList:
            # Get line style data
            try:
                colorData = BASE_COLORS[source.colorID]
            except KeyError:
                pyfalog.warning('Invalid color "{}" for "{}"'.format(
                    source.colorID, source.name))
                continue
            color = colorData.hsl
            lineStyle = 'solid'
            if target is not None:
                try:
                    lightnessData = LIGHTNESSES[target.lightnessID]
                except KeyError:
                    pyfalog.warning('Invalid lightness "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                color = lightnessData.func(color)
                try:
                    lineStyleData = STYLES[target.lineStyleID]
                except KeyError:
                    pyfalog.warning('Invalid line style "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                lineStyle = lineStyleData.mplSpec
            color = hsv_to_rgb(hsl_to_hsv(color))

            # Get point data
            try:
                xs, ys = view.getPlotPoints(mainInput=mainInput,
                                            miscInputs=miscInputs,
                                            xSpec=chosenX,
                                            ySpec=chosenY,
                                            src=source,
                                            tgt=target)
                if not self.__checkNumbers(xs, ys):
                    pyfalog.warning(
                        'Failed to plot "{}" vs "{}" due to inf or NaN in values'
                        .format(source.name,
                                '' if target is None else target.name))
                    continue
                plotData[(source, target)] = (xs, ys)
                allXs.update(xs)
                allYs.update(ys)
                # If we have single data point, show marker - otherwise line won't be shown
                if len(xs) == 1 and len(ys) == 1:
                    self.subplot.plot(xs,
                                      ys,
                                      color=color,
                                      linestyle=lineStyle,
                                      marker='.')
                else:
                    self.subplot.plot(xs, ys, color=color, linestyle=lineStyle)
                # Fill data for legend
                if target is None:
                    legendData.append((color, lineStyle, source.shortName))
                else:
                    legendData.append(
                        (color, lineStyle,
                         '{} vs {}'.format(source.shortName,
                                           target.shortName)))
            except Exception:
                pyfalog.warning('Failed to plot "{}" vs "{}"'.format(
                    source.name, '' if target is None else target.name))
                self.canvas.draw()
                self.Refresh()
                return

        # Setting Y limits for canvas
        if self.graphFrame.ctrlPanel.showY0:
            allYs.add(0)
        canvasMinY, canvasMaxY = self._getLimits(allYs,
                                                 minExtra=0.05,
                                                 maxExtra=0.1)
        canvasMinX, canvasMaxX = self._getLimits(allXs,
                                                 minExtra=0.02,
                                                 maxExtra=0.02)
        self.subplot.set_ylim(bottom=canvasMinY, top=canvasMaxY)
        self.subplot.set_xlim(left=canvasMinX, right=canvasMaxX)
        # Process X marks line
        if self.xMark is not None:
            minX = min(allXs, default=None)
            maxX = max(allXs, default=None)
            if minX is not None and maxX is not None:
                minY = min(allYs, default=None)
                maxY = max(allYs, default=None)
                xMark = max(min(self.xMark, maxX), minX)
                # If in top 10% of X coordinates, align labels differently
                if xMark > canvasMinX + 0.9 * (canvasMaxX - canvasMinX):
                    labelAlignment = 'right'
                    labelPrefix = ''
                    labelSuffix = ' '
                else:
                    labelAlignment = 'left'
                    labelPrefix = ' '
                    labelSuffix = ''
                # Draw line
                self.subplot.axvline(x=xMark,
                                     linestyle='dotted',
                                     linewidth=1,
                                     color=(0, 0, 0))
                # Draw its X position
                if chosenX.unit is None:
                    xLabel = '{}{}{}'.format(labelPrefix,
                                             roundToPrec(xMark,
                                                         4), labelSuffix)
                else:
                    xLabel = '{}{} {}{}'.format(labelPrefix,
                                                roundToPrec(xMark, 4),
                                                chosenX.unit, labelSuffix)
                self.subplot.annotate(xLabel,
                                      xy=(xMark, canvasMaxY - 0.01 *
                                          (canvasMaxY - canvasMinY)),
                                      xytext=(0, 0),
                                      annotation_clip=False,
                                      textcoords='offset pixels',
                                      ha=labelAlignment,
                                      va='top',
                                      fontsize='small')
                # Get Y values
                yMarks = set()

                def addYMark(val):
                    if val is None:
                        return
                    # If due to some bug or insufficient plot density we're
                    # out of bounds, do not add anything
                    if minY <= val <= maxY:
                        if abs(val) < 0.0001:
                            val = 0
                        else:
                            val = roundToPrec(val, 4)
                        yMarks.add(val)

                for source, target in iterList:
                    xs, ys = plotData[(source, target)]
                    if not xs or xMark < min(xs) or xMark > max(xs):
                        continue
                    # Fetch values from graphs when we're asked to provide accurate data
                    if accurateMarks:
                        try:
                            y = view.getPoint(x=xMark,
                                              miscInputs=miscInputs,
                                              xSpec=chosenX,
                                              ySpec=chosenY,
                                              src=source,
                                              tgt=target)
                            addYMark(y)
                        except Exception:
                            pyfalog.warning(
                                'Failed to get X mark for "{}" vs "{}"'.format(
                                    source.name,
                                    '' if target is None else target.name))
                            # Silently skip this mark, otherwise other marks and legend display will fail
                            continue
                    # Otherwise just do linear interpolation between two points
                    else:
                        if xMark in xs:
                            # We might have multiples of the same value in our sequence, pick value for the last one
                            idx = len(xs) - xs[::-1].index(xMark) - 1
                            addYMark(ys[idx])
                            continue
                        idx = bisect(xs, xMark)
                        yMark = self._interpolateX(x=xMark,
                                                   x1=xs[idx - 1],
                                                   y1=ys[idx - 1],
                                                   x2=xs[idx],
                                                   y2=ys[idx])
                        addYMark(yMark)

                # Draw Y values
                for yMark in yMarks:
                    self.subplot.annotate('{}{}{}'.format(
                        labelPrefix, yMark, labelSuffix),
                                          xy=(xMark, yMark),
                                          xytext=(0, 0),
                                          textcoords='offset pixels',
                                          ha=labelAlignment,
                                          va='center',
                                          fontsize='small')

        legendLines = []
        for i, iData in enumerate(legendData):
            color, lineStyle, label = iData
            legendLines.append(
                Line2D([0], [0],
                       color=color,
                       linestyle=lineStyle,
                       label=label.replace('$', '\$')))

        if len(legendLines) > 0 and self.graphFrame.ctrlPanel.showLegend:
            legend = self.subplot.legend(handles=legendLines)
            for t in legend.get_texts():
                t.set_fontsize('small')
            for l in legend.get_lines():
                l.set_linewidth(1)

        self.canvas.draw()
        self.Refresh()
Exemplo n.º 16
0
def exportEft(fit, options):
    # EFT formatted export is split in several sections, each section is
    # separated from another using 2 blank lines. Sections might have several
    # sub-sections, which are separated by 1 blank line
    sections = []

    header = '[{}, {}]'.format(fit.ship.item.name, fit.name)

    # Section 1: modules, rigs, subsystems, services
    modsBySlotType = {}
    sFit = svcFit.getInstance()
    for module in fit.modules:
        modsBySlotType.setdefault(module.slot, []).append(module)
    modSection = []

    mutants = {}  # Format: {reference number: module}
    mutantReference = 1
    for slotType in SLOT_ORDER:
        rackLines = []
        modules = modsBySlotType.get(slotType, ())
        for module in modules:
            if module.item:
                mutated = bool(module.mutators)
                # if module was mutated, use base item name for export
                if mutated:
                    modName = module.baseItem.name
                else:
                    modName = module.item.name
                if mutated and options & Options.MUTATIONS.value:
                    mutants[mutantReference] = module
                    mutationSuffix = ' [{}]'.format(mutantReference)
                    mutantReference += 1
                else:
                    mutationSuffix = ''
                modOfflineSuffix = ' {}'.format(OFFLINE_SUFFIX) if module.state == State.OFFLINE else ''
                if module.charge and sFit.serviceFittingOptions['exportCharges']:
                    rackLines.append('{}, {}{}{}'.format(
                        modName, module.charge.name, modOfflineSuffix, mutationSuffix))
                else:
                    rackLines.append('{}{}{}'.format(modName, modOfflineSuffix, mutationSuffix))
            else:
                rackLines.append('[Empty {} slot]'.format(
                    Slot.getName(slotType).capitalize() if slotType is not None else ''))
        if rackLines:
            modSection.append('\n'.join(rackLines))
    if modSection:
        sections.append('\n\n'.join(modSection))

    # Section 2: drones, fighters
    minionSection = []
    droneLines = []
    for drone in sorted(fit.drones, key=lambda d: d.item.name):
        droneLines.append('{} x{}'.format(drone.item.name, drone.amount))
    if droneLines:
        minionSection.append('\n'.join(droneLines))
    fighterLines = []
    for fighter in sorted(fit.fighters, key=lambda f: f.item.name):
        fighterLines.append('{} x{}'.format(fighter.item.name, fighter.amountActive))
    if fighterLines:
        minionSection.append('\n'.join(fighterLines))
    if minionSection:
        sections.append('\n\n'.join(minionSection))

    # Section 3: implants, boosters
    if options & Options.IMPLANTS.value:
        charSection = []
        implantLines = []
        for implant in fit.implants:
            implantLines.append(implant.item.name)
        if implantLines:
            charSection.append('\n'.join(implantLines))
        boosterLines = []
        for booster in fit.boosters:
            boosterLines.append(booster.item.name)
        if boosterLines:
            charSection.append('\n'.join(boosterLines))
        if charSection:
            sections.append('\n\n'.join(charSection))

    # Section 4: cargo
    cargoLines = []
    for cargo in sorted(
        fit.cargo,
        key=lambda c: (c.item.group.category.name, c.item.group.name, c.item.name)
    ):
        cargoLines.append('{} x{}'.format(cargo.item.name, cargo.amount))
    if cargoLines:
        sections.append('\n'.join(cargoLines))

    # Section 5: mutated modules' details
    mutationLines = []
    if mutants and options & Options.MUTATIONS.value:
        for mutantReference in sorted(mutants):
            mutant = mutants[mutantReference]
            mutatedAttrs = {}
            for attrID, mutator in mutant.mutators.items():
                attrName = getAttributeInfo(attrID).name
                mutatedAttrs[attrName] = mutator.value
            mutationLines.append('[{}] {}'.format(mutantReference, mutant.baseItem.name))
            mutationLines.append('  {}'.format(mutant.mutaplasmid.item.name))
            # Round to 7th significant number to avoid exporting float errors
            customAttrsLine = ', '.join(
                '{} {}'.format(a, roundToPrec(mutatedAttrs[a], 7))
                for a in sorted(mutatedAttrs))
            mutationLines.append('  {}'.format(customAttrsLine))
    if mutationLines:
        sections.append('\n'.join(mutationLines))

    return '{}\n\n{}'.format(header, '\n\n\n'.join(sections))