Exemplo n.º 1
0
 def __handleProjectedItem(self, mainItem, selection):
     fitID = self.mainFrame.getActiveFit()
     if isinstance(mainItem, EosFit):
         self.mainFrame.command.Submit(cmd.GuiRemoveProjectedItemsCommand(
             fitID=fitID, items=selection, amount=math.inf))
     elif isinstance(mainItem, EosModule):
         if wx.GetMouseState().GetModifiers() == wx.MOD_ALT:
             fit = Fit.getInstance().getFit(fitID)
             positions = getSimilarModPositions(fit.projectedModules, mainItem)
             items = [fit.projectedModules[p] for p in positions]
         else:
             items = selection
         self.mainFrame.command.Submit(cmd.GuiRemoveProjectedItemsCommand(
             fitID=fitID, items=items, amount=math.inf))
     elif isinstance(mainItem, EosDrone):
         self.mainFrame.command.Submit(cmd.GuiRemoveProjectedItemsCommand(
             fitID=fitID, items=selection, amount=math.inf))
     elif isinstance(mainItem, EosFighter):
         if wx.GetMouseState().GetModifiers() == wx.MOD_ALT:
             fit = Fit.getInstance().getFit(fitID)
             items = getSimilarFighters(fit.projectedFighters, mainItem)
         else:
             items = selection
         self.mainFrame.command.Submit(cmd.GuiRemoveProjectedItemsCommand(
             fitID=fitID, items=items, amount=math.inf))
     else:
         self.mainFrame.command.Submit(cmd.GuiRemoveProjectedItemsCommand(
             fitID=fitID, items=selection, amount=math.inf))
Exemplo n.º 2
0
 def click(self, event):
     mainRow, _ = self.HitTest(event.Position)
     if mainRow != -1:
         col = self.getColumn(event.Position)
         if col == self.getColIndex(State):
             mainItem = self.get(mainRow)
             if mainItem is None:
                 return
             selection = self.getSelectedProjectors()
             if mainItem not in selection:
                 selection = [mainItem]
             modPressed = wx.GetMouseState().GetModifiers() == wx.MOD_ALT
             fitID = self.mainFrame.getActiveFit()
             if isinstance(mainItem, EosModule) and modPressed:
                 fit = Fit.getInstance().getFit(fitID)
                 positions = getSimilarModPositions(fit.projectedModules, mainItem)
                 selection = [fit.projectedModules[p] for p in positions]
             elif isinstance(mainItem, EosFighter) and modPressed:
                 fit = Fit.getInstance().getFit(fitID)
                 selection = getSimilarFighters(fit.projectedFighters, mainItem)
             self.mainFrame.command.Submit(cmd.GuiChangeProjectedItemStatesCommand(
                 fitID=fitID,
                 mainItem=mainItem,
                 items=selection,
                 click='right' if event.GetButton() == 3 else 'left'))
             return
     event.Skip()
Exemplo n.º 3
0
 def Undo(self):
     for _ in self.internal_history.Commands:
         self.internal_history.Undo()
     eos.db.commit()
     Fit.getInstance().recalc(self.fitID)
     wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID))
     return True
Exemplo n.º 4
0
Arquivo: port.py Projeto: Ebag333/Pyfa
    def importCrest(str_):
        fit = json.loads(str_)
        sMkt = Market.getInstance()

        f = Fit()
        f.name = fit['name']

        try:
            try:
                f.ship = Ship(sMkt.getItem(fit['ship']['id']))
            except ValueError:
                f.ship = Citadel(sMkt.getItem(fit['ship']['id']))
        except:
            return None

        items = fit['items']
        items.sort(key=lambda k: k['flag'])

        moduleList = []
        for module in items:
            try:
                item = sMkt.getItem(module['type']['id'], eager="group.category")
                if module['flag'] == INV_FLAG_DRONEBAY:
                    d = Drone(item)
                    d.amount = module['quantity']
                    f.drones.append(d)
                elif module['flag'] == INV_FLAG_CARGOBAY:
                    c = Cargo(item)
                    c.amount = module['quantity']
                    f.cargo.append(c)
                elif module['flag'] == INV_FLAG_FIGHTER:
                    fighter = Fighter(item)
                    f.fighters.append(fighter)
                else:
                    try:
                        m = Module(item)
                    # When item can't be added to any slot (unknown item or just charge), ignore it
                    except ValueError:
                        continue
                    # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                    if item.category.name == "Subsystem":
                        if m.fits(f):
                            f.modules.append(m)
                    else:
                        if m.isValidState(State.ACTIVE):
                            m.state = State.ACTIVE

                        moduleList.append(m)

            except:
                continue

        # Recalc to get slot numbers correct for T3 cruisers
        svcFit.getInstance().recalc(f)

        for module in moduleList:
            if module.fits(f):
                f.modules.append(module)

        return f
Exemplo n.º 5
0
    def getText(self, stuff):
        if isinstance(stuff, Drone):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fighter):
            return "%d/%d %s" % \
                   (stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
        elif isinstance(stuff, Cargo):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fit):
            if self.projectedView:
                # we need a little more information for the projected view
                fitID = self.mainFrame.getActiveFit()
                info = stuff.getProjectionInfo(fitID)

                if info:
                    return "%dx %s (%s)" % (stuff.getProjectionInfo(fitID).amount, stuff.name, stuff.ship.item.name)

                pyfalog.warning("Projected View trying to display things that aren't there. stuff: {}, info: {}", repr(stuff),
                                info)
                return "<unknown>"
            else:
                return "%s (%s)" % (stuff.name, stuff.ship.item.name)
        elif isinstance(stuff, Rack):
            if FitSvc.getInstance().serviceFittingOptions["rackLabels"]:
                if stuff.slot == FittingSlot.MODE:
                    return '─ Tactical Mode ─'
                else:
                    return '─ {} {} Slot{}─'.format(stuff.num, FittingSlot(stuff.slot).name.capitalize(), '' if stuff.num == 1 else 's')
            else:
                return ""
        elif isinstance(stuff, Module):
            if self.projectedView:
                # check for projected abyssal name
                name_check = stuff.item.name[0:-2]
                type = WhProjector.abyssal_mapping.get(name_check, None)
                if type:
                    sMkt = Market.getInstance()
                    type = sMkt.getItem(type)
                    return "{} {}".format(type.name, stuff.item.name[-1:])

            if stuff.isEmpty:
                return "%s Slot" % FittingSlot(stuff.slot).name.capitalize()
            else:
                return stuff.item.name
        elif isinstance(stuff, Implant):
            return stuff.item.name
        else:
            item = getattr(stuff, "item", stuff)

            if FitSvc.getInstance().serviceFittingOptions["showMarketShortcuts"]:
                marketShortcut = getattr(item, "marketShortcut", None)

                if marketShortcut:
                    # use unicode subscript to display shortcut value
                    shortcut = chr(marketShortcut + 8320) + " "
                    del item.marketShortcut
                    return shortcut + item.name

            return item.name
Exemplo n.º 6
0
    def display(self, srcContext, mainItem):
        if not self.settings.get('changeAffectingSkills'):
            return False

        if srcContext not in (
            "fittingModule", "fittingCharge",
            "fittingShip", "droneItem",
            "fighterItem"
        ):
            return False

        fitID = self.mainFrame.getActiveFit()
        if fitID is None:
            return False

        if (mainItem is None or getattr(mainItem, "isEmpty", False)) and srcContext != "fittingShip":
            return False

        self.sChar = Character.getInstance()
        self.sFit = Fit.getInstance()
        fit = self.sFit.getFit(fitID)

        self.charID = fit.character.ID

        # if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
        #    return False

        if srcContext == "fittingShip":
            sFit = Fit.getInstance()
            self.stuff = sFit.getFit(fitID).ship
            cont = sFit.getFit(fitID).ship.itemModifiedAttributes
        elif srcContext == "fittingCharge":
            cont = mainItem.chargeModifiedAttributes
        else:
            cont = mainItem.itemModifiedAttributes

        skills = set()

        for attrName in cont.iterAfflictions():
            if cont[attrName] == 0:
                continue

            for fit, afflictors in cont.getAfflictions(attrName).items():
                for afflictor, modifier, amount, used in afflictors:
                    # only add Skills
                    if not isinstance(afflictor, Skill):
                        continue

                    skills.add(afflictor)

        self.skills = sorted(skills, key=lambda x: x.item.name)
        return len(self.skills) > 0
Exemplo n.º 7
0
    def getText(self, stuff):
        if isinstance(stuff, Drone):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fighter):
            return "%d/%d %s" % \
                   (stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
        elif isinstance(stuff, Cargo):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fit):
            if self.projectedView:
                # we need a little more information for the projected view
                fitID = self.mainFrame.getActiveFit()
                info = stuff.getProjectionInfo(fitID)

                if info:
                    return "%dx %s (%s)" % (stuff.getProjectionInfo(fitID).amount, stuff.name, stuff.ship.item.name)

                pyfalog.warning("Projected View trying to display things that aren't there. stuff: {}, info: {}", repr(stuff),
                                info)
                return "<unknown>"
            else:
                return "%s (%s)" % (stuff.name, stuff.ship.item.name)
        elif isinstance(stuff, Rack):
            if FitSvc.getInstance().serviceFittingOptions["rackLabels"]:
                if stuff.slot == Slot.MODE:
                    return u'─ Tactical Mode ─'
                else:
                    return u'─ {} Slots ─'.format(Slot.getName(stuff.slot).capitalize())
            else:
                return ""
        elif isinstance(stuff, Module):
            if stuff.isEmpty:
                return "%s Slot" % Slot.getName(stuff.slot).capitalize()
            else:
                return stuff.item.name
        elif isinstance(stuff, Implant):
            return stuff.item.name
        else:
            item = getattr(stuff, "item", stuff)

            if FitSvc.getInstance().serviceFittingOptions["showMarketShortcuts"]:
                marketShortcut = getattr(item, "marketShortcut", None)

                if marketShortcut:
                    # use unicode subscript to display shortcut value
                    shortcut = unichr(marketShortcut + 8320) + u" "
                    del item.marketShortcut
                    return shortcut + item.name

            return item.name
Exemplo n.º 8
0
 def __init__(self, fitID, position):
     wx.Command.__init__(self, True, "")
     self.mainFrame = gui.mainFrame.MainFrame.getInstance()
     self.sFit = Fit.getInstance()
     self.internal_history = wx.CommandProcessor()
     self.fitID = fitID
     self.position = position
Exemplo n.º 9
0
    def swapItems(self, x, y, srcIdx):
        """Swap two modules in fitting window"""
        mstate = wx.GetMouseState()
        sFit = Fit.getInstance()
        fit = sFit.getFit(self.activeFitID)

        dstRow, _ = self.HitTest((x, y))

        if dstRow != -1 and dstRow not in self.blanks:
            mod1 = fit.modules[srcIdx]
            mod2 = self.mods[dstRow]

            if not isinstance(mod2, Module):
                return

            # can't swap modules to different racks
            if mod1.slot != mod2.slot:
                return

            clone = mstate.CmdDown() and mod2.isEmpty

            fitID = self.mainFrame.getActiveFit()
            if getattr(mod2, "modPosition") is not None:
                self.mainFrame.command.Submit(cmd.GuiModuleSwapOrCloneCommand(fitID, srcIdx, mod2.modPosition, clone))
            else:
                pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
Exemplo n.º 10
0
    def run(self):
        # wait 1 second just in case a lot of modifications get made
        time.sleep(1)
        if self.stopRunning:
            return

        sMkt = Market.getInstance()
        sFit = Fit.getInstance()
        settings = HTMLExportSettings.getInstance()

        minimal = settings.getMinimalEnabled()
        dnaUrl = "https://o.smium.org/loadout/dna/"

        if minimal:
            HTML = self.generateMinimalHTML(sMkt, sFit, dnaUrl)
        else:
            HTML = self.generateFullHTML(sMkt, sFit, dnaUrl)

        try:
            FILE = open(settings.getPath(), "w", encoding='utf-8')
            FILE.write(HTML)
            FILE.close()
        except IOError as ex:
            print(("Failed to write to " + settings.getPath()))
            pass
        except Exception as ex:
            pass

        if self.callback:
            wx.CallAfter(self.callback, -1)
Exemplo n.º 11
0
    def fitSelected(self, event):
        count = -1
        # @todo pheonix: _pages is supposed to be private?
        for index, page in enumerate(self.multiSwitch._pages):
            if not isinstance(page, gui.builtinViews.emptyView.BlankPage):  # Don't try and process it if it's a blank page.
                try:
                    if page.activeFitID == event.fitID:
                        count += 1
                        self.multiSwitch.SetSelection(index)
                        wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=event.fitID))
                        break
                except Exception as e:
                    pyfalog.critical("Caught exception in fitSelected")
                    pyfalog.critical(e)
        if count < 0:
            startup = getattr(event, "startup", False)  # see OpenFitsThread in gui.mainFrame
            from_import = getattr(event, "from_import", False)  # always open imported into a new tab
            sFit = Fit.getInstance()
            openFitInNew = sFit.serviceFittingOptions["openFitInNew"]
            mstate = wx.GetMouseState()

            if from_import or (not openFitInNew and mstate.CmdDown()) or startup or (openFitInNew and not mstate.CmdDown()):
                self.multiSwitch.AddPage()

            view = self.multiSwitch.GetSelectedPage()

            if not isinstance(view, FittingView):
                view = FittingView(self.multiSwitch)
                pyfalog.debug("###################### Created new view:" + repr(view))
                self.multiSwitch.ReplaceActivePage(view)

            view.fitSelected(event)
Exemplo n.º 12
0
    def fitRemoved(self, event):
        """
        If fit is removed and active, the page is deleted.
        We also refresh the fit of the new current page in case
        delete fit caused change in stats (projected)
        todo: move this to the notebook, not the page. We don't want the page being responsible for deleting itself
        """
        pyfalog.debug("FittingView::fitRemoved")
        if not self:
            event.Skip()
            return
        if event.fitID == self.getActiveFit():
            pyfalog.debug("    Deleted fit is currently active")
            self.parent.DeletePage(self.parent.GetPageIndex(self))

            try:
                # Sometimes there is no active page after deletion, hence the try block
                sFit = Fit.getInstance()

                # stopgap for #1384
                fit = sFit.getFit(self.getActiveFit())
                if fit:
                    sFit.refreshFit(self.getActiveFit())
                    wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
            except RuntimeError:
                pyfalog.warning("Caught dead object")
                pass

        event.Skip()
Exemplo n.º 13
0
    def appendItem(self, event):
        """
        Adds items that are double clicks from the market browser. We handle both modules and ammo
        """
        if not self:
            event.Skip()
            return
        if self.parent.IsActive(self):
            itemID = event.itemID
            fitID = self.activeFitID
            if fitID is not None:
                sFit = Fit.getInstance()
                if sFit.isAmmo(itemID):
                    # If we've selected ammo, then apply to the selected module(s)
                    modules = []
                    sel = self.GetFirstSelected()
                    while sel != -1 and sel not in self.blanks:
                        mod = self.mods[self.GetItemData(sel)]
                        if isinstance(mod, Module) and not mod.isEmpty:
                            modules.append(self.mods[self.GetItemData(sel)])
                        sel = self.GetNextSelected(sel)

                    if len(modules) > 0:
                        self.mainFrame.command.Submit(cmd.GuiModuleAddChargeCommand(fitID, itemID, modules))
                else:
                    self.mainFrame.command.Submit(cmd.GuiModuleAddCommand(fitID, itemID))

        event.Skip()
Exemplo n.º 14
0
    def spawnMenu(self):
        sel = self.GetFirstSelected()
        menu = None

        sFit = Fit.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())

        if not fit:
            return

        if sel != -1:
            implant = fit.appliedImplants[sel]

            sMkt = Market.getInstance()
            sourceContext = "implantItem" if fit.implantSource == ImplantLocation.FIT else "implantItemChar"
            itemContext = sMkt.getCategoryByItem(implant.item).name

            menu = ContextMenu.getMenu((implant,), (sourceContext, itemContext))
        elif sel == -1 and fit.implantSource == ImplantLocation.FIT:
            fitID = self.mainFrame.getActiveFit()
            if fitID is None:
                return
            context = (("implantView",),)
            menu = ContextMenu.getMenu([], *context)
        if menu is not None:
            self.PopupMenu(menu)
Exemplo n.º 15
0
 def Do(self):
     pyfalog.debug('Doing removal of booster from position {} on fit {}'.format(self.position, self.fitID))
     fit = Fit.getInstance().getFit(self.fitID)
     booster = fit.boosters[self.position]
     self.savedBoosterInfo = BoosterInfo.fromBooster(booster)
     fit.boosters.remove(booster)
     return True
Exemplo n.º 16
0
    def getText(self, itmContext, selection):
        sDP = import_DamagePattern.getInstance()
        sFit = Fit.getInstance()
        fitID = self.mainFrame.getActiveFit()
        self.fit = sFit.getFit(fitID)

        self.patterns = sDP.getDamagePatternList()
        self.patterns.sort(key=lambda p: (p.name not in ["Uniform", "Selected Ammo"], p.name))

        self.patternIds = {}
        self.subMenus = OrderedDict()
        self.singles = []

        # iterate and separate damage patterns based on "[Parent] Child"
        for pattern in self.patterns:
            start, end = pattern.name.find('['), pattern.name.find(']')
            if start is not -1 and end is not -1:
                currBase = pattern.name[start + 1:end]
                # set helper attr
                setattr(pattern, "_name", pattern.name[end + 1:].strip())
                if currBase not in self.subMenus:
                    self.subMenus[currBase] = []
                self.subMenus[currBase].append(pattern)
            else:
                self.singles.append(pattern)

        # return list of names, with singles first followed by submenu names
        self.m = map(lambda p: p.name, self.singles) + self.subMenus.keys()
        return self.m
Exemplo n.º 17
0
    def fitChanged(self, event):
        sFit = Fit.getInstance()
        fit = sFit.getFit(event.fitID)

        self.Parent.Parent.Parent.DisablePage(self.Parent, not fit or fit.isStructure)

        # Clear list and get out if current fitId is None
        if event.fitID is None and self.lastFitId is not None:
            self.DeleteAllItems()
            self.lastFitId = None
            event.Skip()
            return

        self.original = fit.implants if fit is not None else None
        self.implants = stuff = fit.appliedImplants if fit is not None else None
        if stuff is not None:
            stuff.sort(key=lambda implant: implant.slot)

        if event.fitID != self.lastFitId:
            self.lastFitId = event.fitID

            item = self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)

            if item != -1:
                self.EnsureVisible(item)

            self.deselectItems()

        self.update(stuff)
        event.Skip()
Exemplo n.º 18
0
    def fitChanged(self, event):
        sFit = Fit.getInstance()
        fit = sFit.getFit(event.fitID)

        self.Parent.Parent.Parent.DisablePage(self.Parent, not fit)

        # Clear list and get out if current fitId is None
        if event.fitID is None and self.lastFitId is not None:
            self.DeleteAllItems()
            self.lastFitId = None
            event.Skip()
            return

        self.original = fit.fighters if fit is not None else None
        self.fighters = fit.fighters[:] if fit is not None else None

        if self.fighters is not None:
            self.fighters.sort(key=self.fighterKey)

        if event.fitID != self.lastFitId:
            self.lastFitId = event.fitID

            item = self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)

            if item != -1:
                self.EnsureVisible(item)

            self.deselectItems()

        self.update(self.fighters)
        event.Skip()
Exemplo n.º 19
0
    def fitChanged(self, event):
        sFit = Fit.getInstance()
        activeFitID = self.mainFrame.getActiveFit()
        fit = sFit.getFit(activeFitID)

        if fit:
            for x in self.labels:
                if fit.isStructure:
                    slot = getattr(FittingSlot, "FS_{}".format(x.upper()))
                else:
                    slot = getattr(FittingSlot, "F_{}".format(x.upper()))
                used = fit.getSlotsUsed(slot)
                total = fit.getNumSlots(slot)
                color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings.GetColour(
                    wx.SYS_COLOUR_WINDOWTEXT)

                lbl = getattr(self, "label%sUsed" % x.capitalize())
                lbl.SetLabel(str(int(used)))
                lbl.SetForegroundColour(color)

                lbl = getattr(self, "label%sTotal" % x.capitalize())
                lbl.SetLabel(str(int(total)))
                lbl.SetForegroundColour(color)

            self.Refresh()

        event.Skip()
Exemplo n.º 20
0
    def refreshCharacterList(self, event=None):
        choice = self.charChoice
        sChar = Character.getInstance()
        activeChar = self.getActiveCharacter()

        choice.Clear()
        charList = sorted(sChar.getCharacterList(), key=lambda c: (not c.ro, c.name))
        picked = False

        for char in charList:
            currId = choice.Append(char.name, char.ID)
            if char.ID == activeChar:
                choice.SetSelection(currId)
                self.charChanged(None)
                picked = True

        if not picked:
            charID = sChar.all5ID()
            self.selectChar(charID)
            fitID = self.mainFrame.getActiveFit()
            sFit = Fit.getInstance()
            sFit.changeChar(fitID, charID)

        choice.Append(u"\u2015 Open Character Editor \u2015", -1)
        self.charCache = self.charChoice.GetCurrentSelection()

        if event is not None:
            event.Skip()
Exemplo n.º 21
0
    def fitChanged(self, event):
        enable = event.fitID is not None
        self.Enable(wx.ID_SAVEAS, enable)
        self.Enable(wx.ID_COPY, enable)
        self.Enable(self.exportSkillsNeededId, enable)

        sChar = Character.getInstance()
        charID = self.mainFrame.charSelection.getActiveCharacter()
        char = sChar.getCharacter(charID)

        # enable/disable character saving stuff
        self.Enable(self.saveCharId, not char.ro and char.isDirty)
        self.Enable(self.saveCharAsId, char.isDirty)
        self.Enable(self.revertCharId, char.isDirty)

        self.Enable(self.toggleIgnoreRestrictionID, enable)

        if event.fitID:
            sFit = Fit.getInstance()
            fit = sFit.getFit(event.fitID)

            if fit.ignoreRestrictions:
                self.ignoreRestrictionItem.SetItemLabel("Enable Fitting Restrictions")
            else:
                self.ignoreRestrictionItem.SetItemLabel("Disable Fitting Restrictions")

        event.Skip()
Exemplo n.º 22
0
    def swapModule(self, x, y, modIdx):
        """Swap a module from fitting window with cargo"""
        sFit = Fit.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())
        dstRow, _ = self.HitTest((x, y))
        mstate = wx.GetMouseState()

        # Gather module information to get position
        module = fit.modules[modIdx]

        if module.item.isAbyssal:
            dlg = wx.MessageDialog(self,
               "Moving this Abyssal module to the cargo will convert it to the base module. Do you wish to proceed?",
               "Confirm", wx.YES_NO | wx.ICON_QUESTION)
            result = dlg.ShowModal() == wx.ID_YES

            if not result:
                return

        cargoPos = dstRow if dstRow > -1 else None

        self.mainFrame.command.Submit(cmd.GuiModuleToCargoCommand(
            self.mainFrame.getActiveFit(),
            module.modPosition,
            cargoPos,
            mstate.cmdDown
        ))
Exemplo n.º 23
0
    def fitChanged(self, event):
        sFit = Fit.getInstance()
        fit = sFit.getFit(event.fitID)

        # self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)

        # Clear list and get out if current fitId is None
        if event.fitID is None and self.lastFitId is not None:
            self.DeleteAllItems()
            self.lastFitId = None
            event.Skip()
            return

        self.original = fit.cargo if fit is not None else None
        self.cargo = stuff = fit.cargo if fit is not None else None
        if stuff is not None:
            stuff.sort(key=lambda c: (c.item.group.category.name, c.item.group.name, c.item.name))

        if event.fitID != self.lastFitId:
            self.lastFitId = event.fitID

            item = self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)

            if item != -1:
                self.EnsureVisible(item)

            self.deselectItems()

        self.populate(stuff)
        self.refresh(stuff)
        event.Skip()
Exemplo n.º 24
0
    def swapItems(self, x, y, srcIdx):
        """Swap two modules in fitting window"""
        mstate = wx.GetMouseState()
        sFit = Fit.getInstance()
        fit = sFit.getFit(self.activeFitID)

        if mstate.CmdDown():
            clone = True
        else:
            clone = False

        dstRow, _ = self.HitTest((x, y))

        if dstRow != -1 and dstRow not in self.blanks:

            mod1 = fit.modules[srcIdx]
            mod2 = self.mods[dstRow]

            if not isinstance(mod2, Module):
                return

            # can't swap modules to different racks
            if mod1.slot != mod2.slot:
                return

            if getattr(mod2, "modPosition") is not None:
                if clone and mod2.isEmpty:
                    sFit.cloneModule(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)
                else:
                    sFit.swapModules(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)

                wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
            else:
                pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
Exemplo n.º 25
0
 def _merge(self, src, dst):
     dstDrone = self.get(dst)
     if isinstance(dstDrone, es_Drone):
         sFit = Fit.getInstance()
         fitID = self.mainFrame.getActiveFit()
         if sFit.mergeDrones(fitID, self.get(src), dstDrone, True):
             wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Exemplo n.º 26
0
 def activate(self, fullContext, selection, i):
     sFit = Fit.getInstance()
     fitID = self.mainFrame.getActiveFit()
     trigger = sFit.project(fitID, selection[0])
     if trigger:
         wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
         self.mainFrame.additionsPane.select("Projected")
Exemplo n.º 27
0
    def exportFitting(self, event):
        sPort = Port.getInstance()
        fitID = self.mainFrame.getActiveFit()

        self.statusbar.SetStatusText("", 0)

        if fitID is None:
            self.statusbar.SetStatusText("Please select an active fitting in the main window", 1)
            return

        self.statusbar.SetStatusText("Sending request and awaiting response", 1)
        sCrest = Crest.getInstance()

        try:
            sFit = Fit.getInstance()
            data = sPort.exportCrest(sFit.getFit(fitID))
            res = sCrest.postFitting(self.getActiveCharacter(), data)

            self.statusbar.SetStatusText("%d: %s" % (res.status_code, res.reason), 0)
            try:
                text = json.loads(res.text)
                self.statusbar.SetStatusText(text['message'], 1)
            except ValueError:
                self.statusbar.SetStatusText("", 1)
        except requests.exceptions.ConnectionError:
            self.statusbar.SetStatusText("Connection error, please check your internet connection", 1)
Exemplo n.º 28
0
    def appendItem(self, event):
        if self.parent.IsActive(self):
            itemID = event.itemID
            fitID = self.activeFitID
            if fitID is not None:
                sFit = Fit.getInstance()
                if sFit.isAmmo(itemID):
                    modules = []
                    sel = self.GetFirstSelected()
                    while sel != -1 and sel not in self.blanks:
                        mod = self.mods[self.GetItemData(sel)]
                        if isinstance(mod, Module) and not mod.isEmpty:
                            modules.append(self.mods[self.GetItemData(sel)])
                        sel = self.GetNextSelected(sel)

                    if len(modules) > 0:
                        sFit.setAmmo(fitID, itemID, modules)
                        wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
                else:
                    populate = sFit.appendModule(fitID, itemID)
                    if populate is not None:
                        self.slotsChanged()
                        wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID, action="modadd", typeID=itemID))

        event.Skip()
Exemplo n.º 29
0
 def __init__(self, fitID, itemID):
     wx.Command.__init__(self, True, "Module Charge Add")
     self.mainFrame = gui.mainFrame.MainFrame.getInstance()
     self.sFit = Fit.getInstance()
     self.internal_history = wx.CommandProcessor()
     self.fitID = fitID
     self.itemID = itemID
Exemplo n.º 30
0
    def fitChanged(self, event):
        sFit = Fit.getInstance()
        fit = sFit.getFit(event.fitID)

        self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)

        # Clear list and get out if current fitId is None
        if event.fitID is None and self.lastFitId is not None:
            self.DeleteAllItems()
            self.lastFitId = None
            event.Skip()
            return

        self.origional = fit.boosters if fit is not None else None
        self.boosters = stuff = fit.boosters[:] if fit is not None else None

        if event.fitID != self.lastFitId:
            self.lastFitId = event.fitID

            item = self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)

            if item != -1:
                self.EnsureVisible(item)

            self.deselectItems()

        self.populate(stuff)
        self.refresh(stuff)
        event.Skip()
Exemplo n.º 31
0
 def copyFit(self, event=None):
     sFit = Fit.getInstance()
     fitID = sFit.copyFit(self.fitID)
     self.shipBrowser.fitIDMustEditName = fitID
     wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID))
     wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
Exemplo n.º 32
0
    def getText(self, stuff):
        if isinstance(stuff, BaseWrapper):
            stuff = stuff.item

        if isinstance(stuff, Drone):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fighter):
            return "%d/%d %s" % \
                   (stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
        elif isinstance(stuff, Cargo):
            return "%dx %s" % (stuff.amount, stuff.item.name)
        elif isinstance(stuff, Fit):
            if self.projectedView:
                # we need a little more information for the projected view
                fitID = self.mainFrame.getActiveFit()
                info = stuff.getProjectionInfo(fitID)

                if info:
                    return "%dx %s (%s)" % (stuff.getProjectionInfo(
                        fitID).amount, stuff.name, stuff.ship.item.name)

                pyfalog.warning(
                    "Projected View trying to display things that aren't there. stuff: {}, info: {}",
                    repr(stuff), info)
                return "<unknown>"
            else:
                return "%s (%s)" % (stuff.name, stuff.ship.item.name)
        elif isinstance(stuff, FitLite):
            return "{} ({})".format(stuff.name, stuff.shipName)
        elif isinstance(stuff, Rack):
            if FitSvc.getInstance().serviceFittingOptions["rackLabels"]:
                if stuff.slot == FittingSlot.MODE:
                    return '─ Tactical Mode ─'
                else:
                    return '─ {} {} Slot{}─'.format(
                        stuff.num,
                        FittingSlot(stuff.slot).name.capitalize(),
                        '' if stuff.num == 1 else 's')
            else:
                return ""
        elif isinstance(stuff, Module):
            if self.projectedView:
                # check for projected abyssal name
                name_check = stuff.item.name[0:-2]
                type = AddEnvironmentEffect.abyssal_mapping.get(
                    name_check, None)
                if type:
                    sMkt = Market.getInstance()
                    type = sMkt.getItem(type)
                    return "{} {}".format(type.name, stuff.item.name[-1:])

            if stuff.isEmpty:
                return "%s Slot" % FittingSlot(stuff.slot).name.capitalize()
            else:
                return stuff.item.name
        elif isinstance(stuff, Implant):
            return stuff.item.name
        elif isinstance(stuff, TargetProfile):
            return stuff.name
        else:
            item = getattr(stuff, "item", stuff)

            if FitSvc.getInstance(
            ).serviceFittingOptions["showMarketShortcuts"]:
                marketShortcut = getattr(item, "marketShortcut", None)

                if marketShortcut:
                    # use unicode subscript to display shortcut value
                    shortcut = chr(marketShortcut + 8320) + " "
                    del item.marketShortcut
                    return shortcut + item.name

            return item.name
Exemplo n.º 33
0
 def removeDrone(self, drone):
     fitID = self.mainFrame.getActiveFit()
     sFit = Fit.getInstance()
     sFit.removeDrone(fitID, self.original.index(drone))
     wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Exemplo n.º 34
0
 def activate(self, callingWindow, fullContext, i):
     fitID = self.mainFrame.getActiveFit()
     ship = Fit.getInstance().getFit(fitID).ship
     self.mainFrame.notebookBrowsers.SetSelection(1)
     wx.PostEvent(self.mainFrame.shipBrowser,
                  Stage3Selected(shipID=ship.item.ID, back=True))
Exemplo n.º 35
0
    def MakeSnapshot(self, maxColumns=1337):
        if self.FVsnapshot:
            self.FVsnapshot = None

        tbmp = wx.Bitmap(16, 16)
        tdc = wx.MemoryDC()
        tdc.SelectObject(tbmp)
        tdc.SetFont(self.font)

        columnsWidths = []
        for i in range(len(self.DEFAULT_COLS)):
            columnsWidths.append(0)

        sFit = Fit.getInstance()
        try:
            fit = sFit.getFit(self.activeFitID)
        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception as e:
            pyfalog.critical("Failed to get fit")
            pyfalog.critical(e)
            return

        if fit is None:
            return

        slotMap = {}

        for slot in [e.value for e in FittingSlot]:
            slotMap[slot] = fit.getSlotsFree(slot) < 0

        padding = 2
        isize = 16
        headerSize = max(isize, tdc.GetTextExtent("W")[0]) + padding * 2

        maxRowHeight = isize
        rows = 0
        for st in self.mods:
            for i, col in enumerate(self.activeColumns):
                if i > maxColumns:
                    break
                name = col.getText(st)

                if not isinstance(name, str):
                    name = ""

                nx, ny = tdc.GetTextExtent(name)
                imgId = col.getImageId(st)
                cw = 0
                if imgId != -1:
                    cw += isize + padding
                if name != "":
                    cw += nx + 4 * padding

                if imgId == -1 and name == "":
                    cw += isize + padding

                maxRowHeight = max(ny, maxRowHeight)
                columnsWidths[i] = max(columnsWidths[i], cw)

            rows += 1

        render = wx.RendererNative.Get()

        # Fix column widths (use biggest between header or items)

        for i, col in enumerate(self.activeColumns):
            if i > maxColumns:
                break

            name = col.columnText
            imgId = col.imageId

            if not isinstance(name, str):
                name = ""

            opts = wx.HeaderButtonParams()

            if name != "":
                opts.m_labelText = name

            if imgId != -1:
                opts.m_labelBitmap = wx.Bitmap(isize, isize)

            width = render.DrawHeaderButton(self, tdc, (0, 0, 16, 16), sortArrow=wx.HDR_SORT_ICON_NONE, params=opts)

            columnsWidths[i] = max(columnsWidths[i], width)

        tdc.SelectObject(wx.NullBitmap)

        maxWidth = padding * 2

        for i in range(len(self.DEFAULT_COLS)):
            if i > maxColumns:
                break
            maxWidth += columnsWidths[i]

        mdc = wx.MemoryDC()
        mbmp = wx.Bitmap(maxWidth, maxRowHeight * rows + padding * 4 + headerSize)

        mdc.SelectObject(mbmp)

        mdc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)))
        mdc.Clear()

        mdc.SetFont(self.font)
        mdc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))

        cx = padding
        for i, col in enumerate(self.activeColumns):
            if i > maxColumns:
                break

            name = col.columnText
            imgId = col.imageId

            if not isinstance(name, str):
                name = ""

            opts = wx.HeaderButtonParams()
            opts.m_labelAlignment = wx.ALIGN_LEFT
            if name != "":
                opts.m_labelText = name

            if imgId != -1:
                bmp = col.bitmap
                opts.m_labelBitmap = bmp

            render.DrawHeaderButton(self, mdc, (cx, padding, columnsWidths[i], headerSize), wx.CONTROL_CURRENT, sortArrow=wx.HDR_SORT_ICON_NONE, params=opts)

            cx += columnsWidths[i]

        brush = wx.Brush(wx.Colour(224, 51, 51))
        pen = wx.Pen(wx.Colour(224, 51, 51))

        mdc.SetPen(pen)
        mdc.SetBrush(brush)

        cy = padding * 2 + headerSize
        for st in self.mods:
            cx = padding

            if slotMap[st.slot]:
                mdc.DrawRectangle(cx, cy, maxWidth - cx, maxRowHeight)

            for i, col in enumerate(self.activeColumns):
                if i > maxColumns:
                    break

                name = col.getText(st)
                if not isinstance(name, str):
                    name = ""

                imgId = col.getImageId(st)
                tcx = cx

                if imgId != -1:
                    self.imageList.Draw(imgId, mdc, cx, cy, wx.IMAGELIST_DRAW_TRANSPARENT, False)
                    tcx += isize + padding

                if name != "":
                    nx, ny = mdc.GetTextExtent(name)
                    rect = wx.Rect()
                    rect.top = cy
                    rect.left = cx + 2 * padding
                    rect.width = nx
                    rect.height = maxRowHeight + padding
                    mdc.DrawLabel(name, rect, wx.ALIGN_CENTER_VERTICAL)
                    tcx += nx + padding

                cx += columnsWidths[i]

            cy += maxRowHeight

        mdc.SelectObject(wx.NullBitmap)

        self.FVsnapshot = mbmp
Exemplo n.º 36
0
Arquivo: efs.py Projeto: zliu/Pyfa
    def getWeaponBonusMultipliers(fit):
        def sumDamage(attr):
            totalDamage = 0
            for damageType in [
                    "emDamage", "thermalDamage", "kineticDamage",
                    "explosiveDamage"
            ]:
                if attr(damageType) is not None:
                    totalDamage += attr(damageType)
            return totalDamage

        def getCurrentMultipliers(tf):
            fitMultipliers = {}
            getDroneMulti = lambda d: sumDamage(d.getModifiedItemAttr
                                                ) * d.getModifiedItemAttr(
                                                    "damageMultiplier")
            fitMultipliers["drones"] = list(map(getDroneMulti, tf.drones))

            getFitTurrets = lambda f: filter(
                lambda mod: mod.hardpoint == Hardpoint.TURRET, f.modules)
            getTurretMulti = lambda mod: mod.getModifiedItemAttr(
                "damageMultiplier") / mod.cycleTime
            fitMultipliers["turrets"] = list(
                map(getTurretMulti, getFitTurrets(tf)))

            getFitLaunchers = lambda f: filter(
                lambda mod: mod.hardpoint == Hardpoint.MISSILE, f.modules)
            getLauncherMulti = lambda mod: sumDamage(mod.getModifiedChargeAttr
                                                     ) / mod.cycleTime
            fitMultipliers["launchers"] = list(
                map(getLauncherMulti, getFitLaunchers(tf)))
            return fitMultipliers

        multipliers = {"turret": 1, "launcher": 1, "droneBandwidth": 1}
        drones = EfsPort.getTestSet("drone")
        launchers = EfsPort.getTestSet("launcher")
        turrets = EfsPort.getTestSet("turret")
        for weaponTypeSet in [turrets, launchers, drones]:
            for mod in weaponTypeSet:
                mod.owner = fit
        turrets = list(
            filter(lambda mod: mod.getModifiedItemAttr("damageMultiplier"),
                   turrets))
        launchers = list(
            filter(lambda mod: sumDamage(mod.getModifiedChargeAttr),
                   launchers))

        # Since the effect modules are fairly opaque a mock test fit is used to test the impact of traits.
        # standin class used to prevent . notation causing issues when used as an arg
        class standin():
            pass

        tf = standin()
        tf.modules = HandledList(turrets + launchers)
        tf.character = fit.character
        tf.ship = fit.ship
        tf.drones = HandledList(drones)
        tf.fighters = HandledList([])
        tf.boosters = HandledList([])
        tf.extraAttributes = fit.extraAttributes
        tf.mode = fit.mode
        preTraitMultipliers = getCurrentMultipliers(tf)
        for effect in fit.ship.item.effects.values():
            if effect._Effect__effectModule is not None:
                effect.handler(tf, tf.ship, [])
        # Factor in mode effects for T3 Destroyers
        if fit.mode is not None:
            for effect in fit.mode.item.effects.values():
                if effect._Effect__effectModule is not None:
                    effect.handler(tf, fit.mode, [])
        if fit.ship.item.groupID == getGroup("Strategic Cruiser").ID:
            subSystems = list(
                filter(lambda mod: mod.slot == Slot.SUBSYSTEM and mod.item,
                       fit.modules))
            for sub in subSystems:
                for effect in sub.item.effects.values():
                    if effect._Effect__effectModule is not None:
                        effect.handler(tf, sub, [])
        postTraitMultipliers = getCurrentMultipliers(tf)
        getMaxRatio = lambda dictA, dictB, key: max(
            map(lambda a, b: b / a, dictA[key], dictB[key]))
        multipliers["turret"] = round(
            getMaxRatio(preTraitMultipliers, postTraitMultipliers, "turrets"),
            6)
        multipliers["launcher"] = round(
            getMaxRatio(preTraitMultipliers, postTraitMultipliers,
                        "launchers"), 6)
        multipliers["droneBandwidth"] = round(
            getMaxRatio(preTraitMultipliers, postTraitMultipliers, "drones"),
            6)
        Fit.getInstance().recalc(fit)
        return multipliers
Exemplo n.º 37
0
def importDna(string, fitName=None):
    sMkt = Market.getInstance()

    ids = list(map(int, re.findall(r'\d+', string)))
    for id_ in ids:
        try:
            try:
                try:
                    Ship(sMkt.getItem(sMkt.getItem(id_)))
                except ValueError:
                    Citadel(sMkt.getItem(sMkt.getItem(id_)))
            except ValueError:
                Citadel(sMkt.getItem(id_))
            string = string[string.index(str(id_)):]
            break
        except:
            pyfalog.warning("Exception caught in importDna")
            pass
    string = string[:string.index("::") + 2]
    info = string.split(":")

    f = Fit()
    try:
        try:
            f.ship = Ship(sMkt.getItem(int(info[0])))
        except ValueError:
            f.ship = Citadel(sMkt.getItem(int(info[0])))
        if fitName is None:
            f.name = "{0} - DNA Imported".format(f.ship.item.name)
        else:
            f.name = fitName
    except UnicodeEncodeError:

        def logtransform(s_):
            if len(s_) > 10:
                return s_[:10] + "..."
            return s_

        pyfalog.exception("Couldn't import ship data {0}",
                          [logtransform(s) for s in info])
        return None

    moduleList = []
    for itemInfo in info[1:]:
        if itemInfo:
            itemID, amount = itemInfo.split(";")
            item = sMkt.getItem(int(itemID), eager="group.category")

            if item.category.name == "Drone":
                d = Drone(item)
                d.amount = int(amount)
                f.drones.append(d)
            elif item.category.name == "Fighter":
                ft = Fighter(item)
                ft.amount = int(
                    amount
                ) if ft.amount <= ft.fighterSquadronMaxSize else ft.fighterSquadronMaxSize
                if ft.fits(f):
                    f.fighters.append(ft)
            elif item.category.name == "Charge":
                c = Cargo(item)
                c.amount = int(amount)
                f.cargo.append(c)
            else:
                for i in range(int(amount)):
                    try:
                        m = Module(item)
                    except:
                        pyfalog.warning("Exception caught in importDna")
                        continue
                    # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                    if item.category.name == "Subsystem":
                        if m.fits(f):
                            f.modules.append(m)
                    else:
                        m.owner = f
                        if m.isValidState(FittingModuleState.ACTIVE):
                            m.state = activeStateLimit(m.item)
                        moduleList.append(m)

    # Recalc to get slot numbers correct for T3 cruisers
    sFit = svcFit.getInstance()
    sFit.recalc(f)
    sFit.fill(f)

    for module in moduleList:
        if module.fits(f):
            module.owner = f
            if module.isValidState(FittingModuleState.ACTIVE):
                module.state = activeStateLimit(module.item)
            f.modules.append(module)

    return f
Exemplo n.º 38
0
Arquivo: eft.py Projeto: poundjd/Pyfa
def importEftCfg(shipname, lines, iportuser):
    """Handle import from EFT config store file"""

    # Check if we have such ship in database, bail if we don't
    sMkt = Market.getInstance()
    try:
        sMkt.getItem(shipname)
    except:
        return []  # empty list is expected

    fits = []  # List for fits
    fitIndices = []  # List for starting line numbers for each fit

    for line in lines:
        # Detect fit header
        if line[:1] == "[" and line[-1:] == "]":
            # Line index where current fit starts
            startPos = lines.index(line)
            fitIndices.append(startPos)

    for i, startPos in enumerate(fitIndices):
        # End position is last file line if we're trying to get it for last fit,
        # or start position of next fit minus 1
        endPos = len(lines) if i == len(fitIndices) - 1 else fitIndices[i + 1]

        # Finally, get lines for current fitting
        fitLines = lines[startPos:endPos]

        try:
            # Create fit object
            fitobj = Fit()
            # Strip square brackets and pull out a fit name
            fitobj.name = fitLines[0][1:-1]
            # Assign ship to fitting
            try:
                fitobj.ship = Ship(sMkt.getItem(shipname))
            except ValueError:
                fitobj.ship = Citadel(sMkt.getItem(shipname))

            moduleList = []
            for x in range(1, len(fitLines)):
                line = fitLines[x]
                if not line:
                    continue

                # Parse line into some data we will need
                misc = re.match(
                    "(Drones|Implant|Booster)_(Active|Inactive)=(.+)", line)
                cargo = re.match("Cargohold=(.+)", line)
                # 2017/03/27 NOTE: store description from EFT
                description = re.match("Description=(.+)", line)

                if misc:
                    entityType = misc.group(1)
                    entityState = misc.group(2)
                    entityData = misc.group(3)
                    if entityType == "Drones":
                        droneData = re.match("(.+),([0-9]+)", entityData)
                        # Get drone name and attempt to detect drone number
                        droneName = droneData.group(
                            1) if droneData else entityData
                        droneAmount = int(
                            droneData.group(2)) if droneData else 1
                        # Bail if we can't get item or it's not from drone category
                        try:
                            droneItem = sMkt.getItem(droneName,
                                                     eager="group.category")
                        except:
                            pyfalog.warning("Cannot get item.")
                            continue
                        if droneItem.category.name == "Drone":
                            # Add drone to the fitting
                            d = Drone(droneItem)
                            d.amount = droneAmount
                            if entityState == "Active":
                                d.amountActive = droneAmount
                            elif entityState == "Inactive":
                                d.amountActive = 0
                            fitobj.drones.append(d)
                        elif droneItem.category.name == "Fighter":  # EFT saves fighter as drones
                            ft = Fighter(droneItem)
                            ft.amount = int(
                                droneAmount
                            ) if ft.amount <= ft.fighterSquadronMaxSize else ft.fighterSquadronMaxSize
                            fitobj.fighters.append(ft)
                        else:
                            continue
                    elif entityType == "Implant":
                        # Bail if we can't get item or it's not from implant category
                        try:
                            implantItem = sMkt.getItem(entityData,
                                                       eager="group.category")
                        except:
                            pyfalog.warning("Cannot get item.")
                            continue
                        if implantItem.category.name != "Implant":
                            continue
                        # Add implant to the fitting
                        imp = Implant(implantItem)
                        if entityState == "Active":
                            imp.active = True
                        elif entityState == "Inactive":
                            imp.active = False
                        fitobj.implants.append(imp)
                    elif entityType == "Booster":
                        # Bail if we can't get item or it's not from implant category
                        try:
                            boosterItem = sMkt.getItem(entityData,
                                                       eager="group.category")
                        except:
                            pyfalog.warning("Cannot get item.")
                            continue
                        # All boosters have implant category
                        if boosterItem.category.name != "Implant":
                            continue
                        # Add booster to the fitting
                        b = Booster(boosterItem)
                        if entityState == "Active":
                            b.active = True
                        elif entityState == "Inactive":
                            b.active = False
                        fitobj.boosters.append(b)
                # If we don't have any prefixes, then it's a module
                elif cargo:
                    cargoData = re.match("(.+),([0-9]+)", cargo.group(1))
                    cargoName = cargoData.group(
                        1) if cargoData else cargo.group(1)
                    cargoAmount = int(cargoData.group(2)) if cargoData else 1
                    # Bail if we can't get item
                    try:
                        item = sMkt.getItem(cargoName)
                    except:
                        pyfalog.warning("Cannot get item.")
                        continue
                    # Add Cargo to the fitting
                    c = Cargo(item)
                    c.amount = cargoAmount
                    fitobj.cargo.append(c)
                # 2017/03/27 NOTE: store description from EFT
                elif description:
                    fitobj.notes = description.group(1).replace("|", "\n")
                else:
                    withCharge = re.match("(.+),(.+)", line)
                    modName = withCharge.group(1) if withCharge else line
                    chargeName = withCharge.group(2) if withCharge else None
                    # If we can't get module item, skip it
                    try:
                        modItem = sMkt.getItem(modName)
                    except:
                        pyfalog.warning("Cannot get item.")
                        continue

                    # Create module
                    m = Module(modItem)

                    # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                    if modItem.category.name == "Subsystem":
                        if m.fits(fitobj):
                            fitobj.modules.append(m)
                    else:
                        m.owner = fitobj
                        # Activate mod if it is activable
                        if m.isValidState(FittingModuleState.ACTIVE):
                            m.state = activeStateLimit(m.item)
                        # Add charge to mod if applicable, on any errors just don't add anything
                        if chargeName:
                            try:
                                chargeItem = sMkt.getItem(
                                    chargeName, eager="group.category")
                                if chargeItem.category.name == "Charge":
                                    m.charge = chargeItem
                            except:
                                pyfalog.warning("Cannot get item.")
                                pass
                        # Append module to fit
                        moduleList.append(m)

            # Recalc to get slot numbers correct for T3 cruisers
            sFit = svcFit.getInstance()
            sFit.recalc(fitobj)
            sFit.fill(fitobj)

            for module in moduleList:
                if module.fits(fitobj):
                    fitobj.modules.append(module)

            # Append fit to list of fits
            fits.append(fitobj)

            if iportuser:  # NOTE: Send current processing status
                processing_notify(
                    iportuser, IPortUser.PROCESS_IMPORT | IPortUser.ID_UPDATE,
                    "%s:\n%s" % (fitobj.ship.name, fitobj.name))

        # Skip fit silently if we get an exception
        except Exception as e:
            pyfalog.error("Caught exception on fit.")
            pyfalog.error(e)
            pass

    return fits
Exemplo n.º 39
0
Arquivo: eft.py Projeto: poundjd/Pyfa
def importEft(lines):
    lines = _importPrepare(lines)
    try:
        fit = _importCreateFit(lines)
    except EftImportError:
        return

    aFit = AbstractFit()
    aFit.mutations = _importGetMutationData(lines)

    stubPattern = '^\[.+?\]$'
    modulePattern = '^(?P<typeName>{0}+?)(,\s*(?P<chargeName>{0}+?))?(?P<offline>\s*{1})?(\s*\[(?P<mutation>\d+?)\])?$'.format(
        NAME_CHARS, OFFLINE_SUFFIX)
    droneCargoPattern = '^(?P<typeName>{}+?) x(?P<amount>\d+?)$'.format(
        NAME_CHARS)

    sections = []
    for section in _importSectionIter(lines):
        for line in section.lines:
            # Stub line
            if re.match(stubPattern, line):
                section.itemSpecs.append(None)
                continue
            # Items with quantity specifier
            m = re.match(droneCargoPattern, line)
            if m:
                try:
                    itemSpec = MultiItemSpec(m.group('typeName'))
                # Items which cannot be fetched are considered as stubs
                except EftImportError:
                    section.itemSpecs.append(None)
                else:
                    itemSpec.amount = int(m.group('amount'))
                    section.itemSpecs.append(itemSpec)
                continue
            # All other items
            m = re.match(modulePattern, line)
            if m:
                try:
                    itemSpec = RegularItemSpec(
                        m.group('typeName'), chargeName=m.group('chargeName'))
                # Items which cannot be fetched are considered as stubs
                except EftImportError:
                    section.itemSpecs.append(None)
                else:
                    if m.group('offline'):
                        itemSpec.offline = True
                    if m.group('mutation'):
                        itemSpec.mutationIdx = int(m.group('mutation'))
                    section.itemSpecs.append(itemSpec)
                continue
        _clearTail(section.itemSpecs)
        sections.append(section)

    hasDroneBay = any(s.isDroneBay for s in sections)
    hasFighterBay = any(s.isFighterBay for s in sections)
    for section in sections:
        if section.isModuleRack:
            aFit.addModules(section.itemSpecs)
        elif section.isImplantRack:
            for itemSpec in section.itemSpecs:
                aFit.addImplant(itemSpec)
        elif section.isDroneBay:
            for itemSpec in section.itemSpecs:
                aFit.addDrone(itemSpec)
        elif section.isFighterBay:
            for itemSpec in section.itemSpecs:
                aFit.addFighter(itemSpec)
        elif section.isCargoHold:
            for itemSpec in section.itemSpecs:
                aFit.addCargo(itemSpec)
        # Mix between different kinds of item specs (can happen when some
        # blank lines are removed)
        else:
            for itemSpec in section.itemSpecs:
                if itemSpec is None:
                    continue
                if itemSpec.isModule:
                    aFit.addModule(itemSpec)
                elif itemSpec.isImplant:
                    aFit.addImplant(itemSpec)
                elif itemSpec.isDrone and not hasDroneBay:
                    aFit.addDrone(itemSpec)
                elif itemSpec.isFighter and not hasFighterBay:
                    aFit.addFighter(itemSpec)
                elif itemSpec.isCargo:
                    aFit.addCargo(itemSpec)

    # Subsystems first because they modify slot amount
    for i, m in enumerate(aFit.subsystems):
        if m is None:
            dummy = Module.buildEmpty(aFit.getSlotByContainer(aFit.subsystems))
            dummy.owner = fit
            fit.modules.replaceRackPosition(i, dummy)
        elif m.fits(fit):
            m.owner = fit
            fit.modules.replaceRackPosition(i, m)
    sFit = svcFit.getInstance()
    sFit.recalc(fit)
    sFit.fill(fit)

    # Other stuff
    for modRack in (
            aFit.rigs,
            aFit.services,
            aFit.modulesHigh,
            aFit.modulesMed,
            aFit.modulesLow,
    ):
        for i, m in enumerate(modRack):
            if m is None:
                dummy = Module.buildEmpty(aFit.getSlotByContainer(modRack))
                dummy.owner = fit
                fit.modules.replaceRackPosition(i, dummy)
            elif m.fits(fit):
                m.owner = fit
                if not m.isValidState(m.state):
                    pyfalog.warning(
                        'service.port.eft.importEft: module {} cannot have state {}',
                        m, m.state)
                fit.modules.replaceRackPosition(i, m)
    for implant in aFit.implants:
        fit.implants.append(implant)
    for booster in aFit.boosters:
        fit.boosters.append(booster)
    for drone in aFit.drones.values():
        fit.drones.append(drone)
    for fighter in aFit.fighters:
        fit.fighters.append(fighter)
    for cargo in aFit.cargo.values():
        fit.cargo.append(cargo)

    return fit
Exemplo n.º 40
0
    def __init__(self, parent):
        wx.Frame.__init__(self,
                          parent,
                          id=wx.ID_ANY,
                          title=u"pyfa: Character Editor",
                          pos=wx.DefaultPosition,
                          size=wx.Size(640, 600),
                          style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)

        i = wx.IconFromBitmap(BitmapLoader.getBitmap("character_small", "gui"))
        self.SetIcon(i)

        self.mainFrame = parent
        # self.disableWin = wx.WindowDisabler(self)
        sFit = Fit.getInstance()

        self.SetBackgroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.entityEditor = CharacterEntityEditor(self)
        mainSizer.Add(self.entityEditor, 0, wx.ALL | wx.EXPAND, 2)
        # Default drop down to current fit's character
        self.entityEditor.setActiveEntity(sFit.character)

        self.viewsNBContainer = wx.Notebook(self, wx.ID_ANY,
                                            wx.DefaultPosition, wx.DefaultSize,
                                            0)

        self.sview = SkillTreeView(self.viewsNBContainer)
        self.iview = ImplantEditorView(self.viewsNBContainer)
        self.aview = APIView(self.viewsNBContainer)

        self.viewsNBContainer.AddPage(self.sview, "Skills")
        self.viewsNBContainer.AddPage(self.iview, "Implants")
        self.viewsNBContainer.AddPage(self.aview, "API")

        mainSizer.Add(self.viewsNBContainer, 1, wx.EXPAND | wx.ALL, 5)

        bSizerButtons = wx.BoxSizer(wx.HORIZONTAL)

        self.btnSaveChar = wx.Button(self, wx.ID_ANY, "Save")
        self.btnSaveAs = wx.Button(self, wx.ID_ANY, "Save As...")
        self.btnRevert = wx.Button(self, wx.ID_ANY, "Revert")
        self.btnOK = wx.Button(self, wx.ID_OK)

        bSizerButtons.Add(self.btnSaveChar, 0, wx.ALL, 5)
        bSizerButtons.Add(self.btnSaveAs, 0, wx.ALL, 5)
        bSizerButtons.Add(self.btnRevert, 0, wx.ALL, 5)
        bSizerButtons.AddStretchSpacer()
        bSizerButtons.Add(self.btnOK, 0, wx.ALL, 5)

        self.btnSaveChar.Bind(wx.EVT_BUTTON, self.saveChar)
        self.btnSaveAs.Bind(wx.EVT_BUTTON, self.saveCharAs)
        self.btnRevert.Bind(wx.EVT_BUTTON, self.revertChar)
        self.btnOK.Bind(wx.EVT_BUTTON, self.editingFinished)

        mainSizer.Add(bSizerButtons, 0, wx.EXPAND, 5)

        self.btnRestrict()

        self.SetSizer(mainSizer)
        self.Layout()

        self.Centre(wx.BOTH)

        self.Bind(wx.EVT_CLOSE, self.closeEvent)
        self.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
        self.entityEditor.Bind(wx.EVT_CHOICE, self.charChanged)

        self.charChanged(None)
Exemplo n.º 41
0
    def searchStage(self, event):

        self.lpane.ShowLoading(False)

        self.navpanel.ShowNewFitButton(False)
        self.navpanel.ShowSwitchEmptyGroupsButton(False)

        if not event.back:
            if self._activeStage != 4:
                if len(self.browseHist) > 0:
                    self.browseHist.append((self._activeStage, self.lastdata))
                else:
                    self.browseHist.append((1, 0))
            self._lastStage = self._activeStage
            self._activeStage = 4

        sMkt = Market.getInstance()
        sFit = Fit.getInstance()
        query = event.text

        self.lpane.Freeze()

        self.lpane.RemoveAllChildren()
        if query:
            ships = sMkt.searchShips(query)
            fitList = sFit.searchFits(query)

            for ship in ships:
                shipTrait = ship.traits.traitText if (
                    ship.traits
                    is not None) else ""  # empty string if no traits

                self.lpane.AddWidget(
                    ShipItem(self.lpane, ship.ID,
                             (ship.name, shipTrait,
                              len(sFit.getFitsWithShip(ship.ID))), ship.race,
                             ship.graphicID))

            for ID, name, shipID, shipName, booster, timestamp, notes in fitList:
                ship = sMkt.getItem(shipID)

                if not sMkt.getPublicityByItem(ship):
                    continue

                shipTrait = ship.traits.traitText if (
                    ship.traits
                    is not None) else ""  # empty string if no traits

                self.lpane.AddWidget(
                    FitItem(
                        self.lpane,
                        ID,
                        (shipName, shipTrait, name, booster, timestamp, notes),
                        shipID,
                        graphicID=ship.graphicID))
            if len(ships) == 0 and len(fitList) == 0:
                self.lpane.AddWidget(
                    PFStaticText(self.lpane, label="No matching results."))
            self.lpane.RefreshList(doFocus=False)
        self.lpane.Thaw()

        self.raceselect.RebuildRaces(self.RACE_ORDER)

        if self.showRacesFilterInStage2Only:
            self.raceselect.Show(False)
            self.Layout()
Exemplo n.º 42
0
 def Undo(self):
     success = self.internalHistory.undoAll()
     Fit.getInstance().recalc(self.fitID)
     wx.PostEvent(gui.mainFrame.MainFrame.getInstance(),
                  GE.FitChanged(fitID=self.fitID))
     return success
Exemplo n.º 43
0
    def stage2Callback(self, data):
        if self.GetActiveStage() != 2:
            return
        self.navpanel.ToggleRecentShips(False, False)

        categoryID = self._stage2Data
        ships = list(data[1])
        sFit = Fit.getInstance()

        ships.sort(key=self.raceNameKey)
        racesList = []
        subRacesFilter = {}
        t_fits = 0  # total number of fits in this category

        for ship in ships:
            if ship.race:
                if ship.race not in racesList:
                    racesList.append(ship.race)

        for race, state in self.racesFilter.items():
            if race in racesList:
                subRacesFilter[race] = self.racesFilter[race]

        override = True
        for race, state in subRacesFilter.items():
            if state:
                override = False
                break

        for ship in ships:
            fits = sFit.countFitsWithShip(ship.ID)
            t_fits += fits
            filter_ = subRacesFilter[ship.race] if ship.race else True
            if override:
                filter_ = True

            shipTrait = ship.traits.traitText if (
                ship.traits is not None) else ""  # empty string if no traits

            if self.filterShipsWithNoFits:
                if fits > 0:
                    if filter_:
                        self.lpane.AddWidget(
                            ShipItem(self.lpane, ship.ID,
                                     (ship.name, shipTrait, fits), ship.race,
                                     ship.graphicID))
            else:
                if filter_:
                    self.lpane.AddWidget(
                        ShipItem(self.lpane, ship.ID,
                                 (ship.name, shipTrait, fits), ship.race,
                                 ship.graphicID))

        self.raceselect.RebuildRaces(racesList)

        # refresh category cache
        if t_fits == 0:
            self.categoryFitCache[categoryID] = False
        else:
            self.categoryFitCache[categoryID] = True

        self.lpane.ShowLoading(False)

        self.lpane.RefreshList()

        if self.showRacesFilterInStage2Only:
            self.raceselect.Show(True)
            self.Layout()
Exemplo n.º 44
0
    def stage3(self, event):
        self.navpanel.ToggleRecentShips(False, False)
        self.lpane.ShowLoading(False)

        # If back is False, do not append to history. This could be us calling
        # the stage from previous history, creating / copying fit, etc.
        # We also have to use conditional for search stage since it's last data
        # is kept elsewhere
        if getattr(event, "back", False):
            if self._activeStage == 4 and self.navpanel.lastSearch != "":
                self.browseHist.append((4, self.navpanel.lastSearch))
            else:
                self.browseHist.append((self._activeStage, self.lastdata))

        shipID = event.shipID
        self.lastdata = shipID
        self._lastStage = self._activeStage
        self._activeStage = 3

        sFit = Fit.getInstance()
        sMkt = Market.getInstance()

        ship = sMkt.getItem(shipID)
        categoryID = ship.group.ID

        self.lpane.Freeze()
        self.lpane.RemoveAllChildren()
        fitList = sFit.getFitsWithShip(shipID)

        if len(fitList) == 0:
            stage, data = self.browseHist.pop()
            self.lpane.Thaw()
            self.navpanel.gotoStage(stage, data)
            return

        self.categoryFitCache[categoryID] = True

        self.navpanel.ShowNewFitButton(True)
        self.navpanel.ShowSwitchEmptyGroupsButton(False)

        if self.showRacesFilterInStage2Only:
            self.raceselect.Show(False)
            self.Layout()

        fitList.sort(key=self.nameKey)
        shipName = ship.name

        self._stage3ShipName = shipName
        self._stage3Data = shipID

        shipTrait = ship.traits.traitText if (
            ship.traits is not None) else ""  # empty string if no traits

        for ID, name, booster, timestamp, notes, graphicID in fitList:
            self.lpane.AddWidget(
                FitItem(self.lpane,
                        ID,
                        (shipName, shipTrait, name, booster, timestamp, notes),
                        shipID,
                        graphicID=graphicID))

        self.lpane.RefreshList()
        self.lpane.Thaw()
        self.raceselect.RebuildRaces(self.RACE_ORDER)
Exemplo n.º 45
0
 def toggleEffective(self, event):
     self.effective = event.effective
     sFit = Fit.getInstance()
     self.refreshPanel(sFit.getFit(self.mainFrame.getActiveFit()))
     event.Skip()
Exemplo n.º 46
0
    def fetchPrices(cls, prices):
        """Fetch all prices passed to this method"""

        # Dictionary for our price objects
        priceMap = {}
        # Check all provided price objects, and add invalid ones to dictionary
        for price in prices:
            if not price.isValid:
                priceMap[price.typeID] = price

        if len(priceMap) == 0:
            return

        # Set of items which are still to be requested from this service
        toRequest = set()

        # Compose list of items we're going to request
        for typeID in priceMap:
            # Get item object
            item = db.getItem(typeID)
            # We're not going to request items only with market group, as eve-central
            # doesn't provide any data for items not on the market
            if item is not None and item.marketGroupID:
                toRequest.add(typeID)

        # Do not waste our time if all items are not on the market
        if len(toRequest) == 0:
            return

        # This will store POST data for eve-central
        data = []

        sFit = Fit.getInstance()
        # Base request URL
        baseurl = "https://eve-central.com/api/marketstat"
        data.append(("usesystem",
                     cls.systemsList[sFit.serviceFittingOptions["priceSystem"]]
                     ))  # Use Jita for market

        for typeID in toRequest:  # Add all typeID arguments
            data.append(("typeid", typeID))

        # Attempt to send request and process it
        try:
            network = Network.getInstance()
            data = network.request(baseurl, network.PRICES, data)
            xml = minidom.parse(data)
            types = xml.getElementsByTagName("marketstat").item(
                0).getElementsByTagName("type")
            # Cycle through all types we've got from request
            for type_ in types:
                # Get data out of each typeID details tree
                typeID = int(type_.getAttribute("id"))
                sell = type_.getElementsByTagName("sell").item(0)
                # If price data wasn't there, set price to zero
                try:
                    percprice = float(
                        sell.getElementsByTagName("percentile").item(
                            0).firstChild.data)
                except (TypeError, ValueError):
                    pyfalog.warning("Failed to get price for: {0}", type_)
                    percprice = 0

                # Fill price data
                priceobj = priceMap[typeID]
                priceobj.price = percprice
                priceobj.time = time.time() + VALIDITY
                priceobj.failed = None

                # delete price from working dict
                del priceMap[typeID]

        # If getting or processing data returned any errors
        except TimeoutError:
            # Timeout error deserves special treatment
            pyfalog.warning("Price fetch timout")
            for typeID in priceMap.keys():
                priceobj = priceMap[typeID]
                priceobj.time = time.time() + TIMEOUT
                priceobj.failed = True

                del priceMap[typeID]
        except:
            # all other errors will pass and continue onward to the REREQUEST delay
            pyfalog.warning("Caught exception in fetchPrices")
            pass

        # if we get to this point, then we've got an error. Set to REREQUEST delay
        for typeID in priceMap.keys():
            priceobj = priceMap[typeID]
            priceobj.time = time.time() + REREQUEST
            priceobj.failed = True
Exemplo n.º 47
0
    def __getData(self, stuff):
        item = stuff.item
        if item is None:
            return "", None
        itemGroup = item.group.name
        itemCategory = item.category.name

        if itemGroup == "Ship Modifiers":
            return "", None
        elif itemGroup == "Booster":
            stuff.getModifiedItemAttr("boosterDuration")
            text = "{0} min".format(
                formatAmount(
                    stuff.getModifiedItemAttr("boosterDuration") / 1000 / 60,
                    3, 0, 3))
            return text, "Booster Duration"
        elif itemGroup in ("Super Weapon", "Structure Doomsday Weapon"):
            doomsday_duration = stuff.getModifiedItemAttr(
                "doomsdayDamageDuration", 1)
            doomsday_dottime = stuff.getModifiedItemAttr(
                "doomsdayDamageCycleTime", 1)
            func = stuff.getModifiedItemAttr

            volley = sum(
                map(lambda attr: (func("%sDamage" % attr) or 0),
                    ("em", "thermal", "kinetic", "explosive")))
            volley *= stuff.getModifiedItemAttr("damageMultiplier") or 1

            if volley <= 0:
                text = ""
                tooltip = ""
            elif max(doomsday_duration / doomsday_dottime, 1) > 1:
                text = "{0} dmg over {1} s".format(
                    formatAmount(
                        volley * (doomsday_duration / doomsday_dottime), 3, 0,
                        3), doomsday_duration / 1000)
                tooltip = "Raw damage done over time"
            else:
                text = "{0} dmg".format(
                    formatAmount(
                        volley * (doomsday_duration / doomsday_dottime), 3, 0,
                        3))
                tooltip = "Raw damage done"
            return text, tooltip

            pass
        elif itemGroup in ("Energy Weapon", "Hybrid Weapon",
                           "Projectile Weapon", "Combat Drone",
                           "Fighter Drone"):
            trackingSpeed = stuff.getModifiedItemAttr("trackingSpeed")
            if not trackingSpeed:
                return "", None
            text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3))
            tooltip = "Tracking speed"
            return text, tooltip
        elif itemGroup == "Precursor Weapon":
            info = []
            trackingSpeed = stuff.getModifiedItemAttr("trackingSpeed")
            if trackingSpeed:
                text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3))
                tooltip = "tracking speed"
                info.append((text, tooltip))
            maxBonusDamage = stuff.getModifiedItemAttr(
                "damageMultiplierBonusMax")
            bonusDamagePerCycle = stuff.getModifiedItemAttr(
                "damageMultiplierBonusPerCycle")
            cycleTime = stuff.getModifiedItemAttr("speed")
            if maxBonusDamage and bonusDamagePerCycle and cycleTime:
                cyclesToFullDamage = int(maxBonusDamage / bonusDamagePerCycle)
                timeToFullDamage = (cycleTime / 1000) * cyclesToFullDamage
                if cyclesToFullDamage:
                    text = "{0}s".format(
                        formatAmount(timeToFullDamage, 3, 0, 3))
                    tooltip = "spool-up time"
                    info.append((text, tooltip))
            if not info:
                return "", None
            text = ' | '.join(i[0] for i in info)
            tooltip = ' and '.join(i[1] for i in info).capitalize()
            return text, tooltip
        elif itemCategory == "Subsystem":
            slots = ("hi", "med", "low")
            info = []
            for slot in slots:
                n = int(stuff.getModifiedItemAttr("%sSlotModifier" % slot))
                if n > 0:
                    info.append("{0}{1}".format(n, slot[0].upper()))
            return "+ " + ", ".join(info), "Slot Modifiers"
        elif itemGroup == "Energy Neutralizer":
            neutAmount = stuff.getModifiedItemAttr("energyNeutralizerAmount")
            cycleTime = stuff.cycleTime
            if not neutAmount or not cycleTime:
                return "", None
            capPerSec = float(-neutAmount) * 1000 / cycleTime
            text = "{0}/s".format(formatAmount(capPerSec, 3, 0, 3))
            tooltip = "Energy neutralization per second"
            return text, tooltip
        elif itemGroup == "Energy Nosferatu":
            neutAmount = stuff.getModifiedItemAttr("powerTransferAmount")
            cycleTime = stuff.cycleTime
            if not neutAmount or not cycleTime:
                return "", None
            capPerSec = float(-neutAmount) * 1000 / cycleTime
            text = "{0}/s".format(formatAmount(capPerSec, 3, 0, 3))
            tooltip = "Energy neutralization per second"
            return text, tooltip
        elif itemGroup == "Salvager":
            chance = stuff.getModifiedItemAttr("accessDifficultyBonus")
            if not chance:
                return "", None
            text = "{0}%".format(formatAmount(chance, 3, 0, 3))
            tooltip = "Item retrieval chance"
            return text, tooltip
        elif itemGroup == "Data Miners":
            strength = stuff.getModifiedItemAttr("virusStrength")
            coherence = stuff.getModifiedItemAttr("virusCoherence")
            if not strength or not coherence:
                return "", None
            text = "{0} | {1}".format(formatAmount(strength, 3, 0, 3),
                                      formatAmount(coherence, 3, 0, 3))
            tooltip = "Virus strength and coherence"
            return text, tooltip
        elif itemGroup in ("Warp Scrambler", "Warp Core Stabilizer"):
            scramStr = stuff.getModifiedItemAttr("warpScrambleStrength")
            if not scramStr:
                return "", None
            text = "{0}".format(
                formatAmount(-scramStr, 3, 0, 3, forceSign=True))
            tooltip = "Warp core strength modification"
            return text, tooltip
        elif itemGroup in ("Stasis Web", "Stasis Webifying Drone"):
            speedFactor = stuff.getModifiedItemAttr("speedFactor")
            if not speedFactor:
                return "", None
            text = "{0}%".format(formatAmount(speedFactor, 3, 0, 3))
            tooltip = "Speed reduction"
            return text, tooltip
        elif itemGroup == "Target Painter":
            sigRadBonus = stuff.getModifiedItemAttr("signatureRadiusBonus")
            if not sigRadBonus:
                return "", None
            text = "{0}%".format(
                formatAmount(sigRadBonus, 3, 0, 3, forceSign=True))
            tooltip = "Signature radius increase"
            return text, tooltip
        elif itemGroup == "Sensor Dampener":
            lockRangeBonus = stuff.getModifiedItemAttr("maxTargetRangeBonus")
            scanResBonus = stuff.getModifiedItemAttr("scanResolutionBonus")
            if lockRangeBonus is None or scanResBonus is None:
                return "", None
            display = 0
            for bonus in (lockRangeBonus, scanResBonus):
                if abs(bonus) > abs(display):
                    display = bonus
            if not display:
                return "", None
            text = "{0}%".format(formatAmount(display, 3, 0, 3,
                                              forceSign=True))
            ttEntries = []
            if display == lockRangeBonus:
                ttEntries.append("lock range")
            if display == scanResBonus:
                ttEntries.append("scan resolution")
            tooltip = "{0} dampening".format(
                formatList(ttEntries)).capitalize()
            return text, tooltip
        elif itemGroup == "Weapon Disruptor":
            # Weapon disruption now covers both tracking and guidance (missile) disruptors
            # First get the attributes for tracking disruptors
            optimalRangeBonus = stuff.getModifiedItemAttr("maxRangeBonus")
            falloffRangeBonus = stuff.getModifiedItemAttr("falloffBonus")
            trackingSpeedBonus = stuff.getModifiedItemAttr(
                "trackingSpeedBonus")

            trackingDisruptorAttributes = {
                "optimal range": optimalRangeBonus,
                "falloff range": falloffRangeBonus,
                "tracking speed": trackingSpeedBonus
            }

            isTrackingDisruptor = any([
                x is not None and x != 0
                for x in list(trackingDisruptorAttributes.values())
            ])

            # Then get the attributes for guidance disruptors
            explosionVelocityBonus = stuff.getModifiedItemAttr(
                "aoeVelocityBonus")
            explosionRadiusBonus = stuff.getModifiedItemAttr(
                "aoeCloudSizeBonus")

            flightTimeBonus = stuff.getModifiedItemAttr("explosionDelayBonus")
            missileVelocityBonus = stuff.getModifiedItemAttr(
                "missileVelocityBonus")

            guidanceDisruptorAttributes = {
                "explosion velocity": explosionVelocityBonus,
                "explosion radius": explosionRadiusBonus,
                "flight time": flightTimeBonus,
                "missile velocity": missileVelocityBonus
            }

            isGuidanceDisruptor = any([
                x is not None and x != 0
                for x in list(guidanceDisruptorAttributes.values())
            ])

            if isTrackingDisruptor:
                attributes = trackingDisruptorAttributes
            elif isGuidanceDisruptor:
                attributes = guidanceDisruptorAttributes
            else:
                return "", None

            display = max(list(attributes.values()), key=lambda x: abs(x))

            text = "{0}%".format(formatAmount(display, 3, 0, 3,
                                              forceSign=True))

            ttEntries = []
            for attributeName, attributeValue in list(attributes.items()):
                if attributeValue == display:
                    ttEntries.append(attributeName)

            tooltip = "{0} disruption".format(
                formatList(ttEntries)).capitalize()
            return text, tooltip
        elif itemGroup in ("ECM", "Burst Jammer", "Burst Projectors"):
            grav = stuff.getModifiedItemAttr("scanGravimetricStrengthBonus")
            ladar = stuff.getModifiedItemAttr("scanLadarStrengthBonus")
            radar = stuff.getModifiedItemAttr("scanRadarStrengthBonus")
            magnet = stuff.getModifiedItemAttr(
                "scanMagnetometricStrengthBonus")
            displayMax = max(grav, ladar, radar, magnet)
            displayMin = min(grav, ladar, radar, magnet)
            if grav is None or ladar is None or radar is None or magnet is None or displayMax is None:
                return "", None

            if displayMax == displayMin or displayMin is None:
                text = "{0}".format(formatAmount(displayMax, 3, 0, 3), )
            else:
                text = "{0} | {1}".format(
                    formatAmount(displayMax, 3, 0, 3),
                    formatAmount(displayMin, 3, 0, 3),
                )
            tooltip = "ECM Jammer Strength:\n{0} Gravimetric | {1} Ladar | {2} Magnetometric | {3} Radar".format(
                formatAmount(grav, 3, 0, 3),
                formatAmount(ladar, 3, 0, 3),
                formatAmount(magnet, 3, 0, 3),
                formatAmount(radar, 3, 0, 3),
            )
            return text, tooltip
        elif itemGroup in ("Remote Sensor Booster", "Sensor Booster",
                           "Signal Amplifier"):
            scanResBonus = stuff.getModifiedItemAttr("scanResolutionBonus")
            lockRangeBonus = stuff.getModifiedItemAttr("maxTargetRangeBonus")
            gravBonus = stuff.getModifiedItemAttr(
                "scanGravimetricStrengthPercent")
            if scanResBonus is None or lockRangeBonus is None or gravBonus is None:
                return "", None

            text = "{0}% | {1}% | {2}%".format(
                formatAmount(scanResBonus, 3, 0, 3),
                formatAmount(lockRangeBonus, 3, 0, 3),
                formatAmount(gravBonus, 3, 0, 3),
            )
            tooltip = "Applied bonuses:\n{0}% scan resolution | {1}% lock range | {2}% sensor strength".format(
                formatAmount(scanResBonus, 3, 0, 3),
                formatAmount(lockRangeBonus, 3, 0, 3),
                formatAmount(gravBonus, 3, 0, 3),
            )
            return text, tooltip
        elif itemGroup in ("Projected ECCM", "ECCM", "Sensor Backup Array"):
            grav = stuff.getModifiedItemAttr("scanGravimetricStrengthPercent")
            ladar = stuff.getModifiedItemAttr("scanLadarStrengthPercent")
            radar = stuff.getModifiedItemAttr("scanRadarStrengthPercent")
            magnet = stuff.getModifiedItemAttr(
                "scanMagnetometricStrengthPercent")
            if grav is None or ladar is None or radar is None or magnet is None:
                return "", None
            display = max(grav, ladar, radar, magnet)
            if not display:
                return "", None
            text = "{0}%".format(formatAmount(display, 3, 0, 3,
                                              forceSign=True))
            ttEntries = []
            if display == grav:
                ttEntries.append("gravimetric")
            if display == ladar:
                ttEntries.append("ladar")
            if display == magnet:
                ttEntries.append("magnetometric")
            if display == radar:
                ttEntries.append("radar")
            plu = "" if len(ttEntries) == 1 else "s"
            tooltip = "{0} strength{1} bonus".format(formatList(ttEntries),
                                                     plu).capitalize()
            return text, tooltip
        elif itemGroup == "Cloaking Device":
            recalibration = stuff.getModifiedItemAttr("cloakingTargetingDelay")
            if recalibration is None:
                return "", None
            text = "{0}s".format(
                formatAmount(float(recalibration) / 1000, 3, 0, 3))
            tooltip = "Sensor recalibration time"
            return text, tooltip
        elif itemGroup == "Remote Armor Repairer":
            repAmount = stuff.getModifiedItemAttr("armorDamageAmount")
            cycleTime = stuff.getModifiedItemAttr("duration")
            if not repAmount or not cycleTime:
                return "", None
            repPerSec = float(repAmount) * 1000 / cycleTime
            text = "{0}/s".format(
                formatAmount(repPerSec, 3, 0, 3, forceSign=True))
            tooltip = "Armor repaired per second"
            return text, tooltip
        elif itemGroup == "Remote Shield Booster":
            repAmount = stuff.getModifiedItemAttr("shieldBonus")
            cycleTime = stuff.cycleTime
            if not repAmount or not cycleTime:
                return "", None
            repPerSec = float(repAmount) * 1000 / cycleTime
            text = "{0}/s".format(
                formatAmount(repPerSec, 3, 0, 3, forceSign=True))
            tooltip = "Shield transferred per second"
            return text, tooltip
        elif itemGroup == "Remote Capacitor Transmitter":
            repAmount = stuff.getModifiedItemAttr("powerTransferAmount")
            cycleTime = stuff.cycleTime
            if not repAmount or not cycleTime:
                return "", None
            repPerSec = float(repAmount) * 1000 / cycleTime
            text = "{0}/s".format(
                formatAmount(repPerSec, 3, 0, 3, forceSign=True))
            tooltip = "Energy transferred per second"
            return text, tooltip
        elif itemGroup == "Remote Hull Repairer":
            repAmount = stuff.getModifiedItemAttr("structureDamageAmount")
            cycleTime = stuff.cycleTime
            if not repAmount or not cycleTime:
                return "", None
            repPerSec = float(repAmount) * 1000 / cycleTime
            text = "{0}/s".format(
                formatAmount(repPerSec, 3, 0, 3, forceSign=True))
            tooltip = "Structure repaired per second"
            return text, tooltip
        elif itemGroup == "Gang Coordinator":
            command = stuff.getModifiedItemAttr(
                "commandBonus") or stuff.getModifiedItemAttr(
                    "commandBonusHidden")
            if not command:
                return "", None
            text = "{0}%".format(formatAmount(command, 3, 0, 3,
                                              forceSign=True))
            tooltip = "Gang bonus strength"
            return text, tooltip
        elif itemGroup == "Electronic Warfare Drone":
            sigRadBonus = stuff.getModifiedItemAttr("signatureRadiusBonus")
            lockRangeMult = stuff.getModifiedItemAttr(
                "maxTargetRangeMultiplier")
            scanResMult = stuff.getModifiedItemAttr("scanResolutionMultiplier")
            falloffRangeMult = stuff.getModifiedItemAttr("fallofMultiplier")
            optimalRangeMult = stuff.getModifiedItemAttr("maxRangeMultiplier")
            trackingSpeedMult = stuff.getModifiedItemAttr(
                "trackingSpeedMultiplier")
            grav = stuff.getModifiedItemAttr("scanGravimetricStrengthBonus")
            ladar = stuff.getModifiedItemAttr("scanLadarStrengthBonus")
            radar = stuff.getModifiedItemAttr("scanRadarStrengthBonus")
            magnet = stuff.getModifiedItemAttr(
                "scanMagnetometricStrengthBonus")
            if sigRadBonus:
                text = "{0}%".format(
                    formatAmount(sigRadBonus, 3, 0, 3, forceSign=True))
                tooltip = "Signature radius increase"
                return text, tooltip
            if lockRangeMult is not None and scanResMult is not None:
                lockRangeBonus = (lockRangeMult - 1) * 100
                scanResBonus = (scanResMult - 1) * 100
                display = 0
                for bonus in (lockRangeBonus, scanResBonus):
                    if abs(bonus) > abs(display):
                        display = bonus
                if not display:
                    return "", None
                text = "{0}%".format(
                    formatAmount(display, 3, 0, 3, forceSign=True))
                ttEntries = []
                if display == lockRangeBonus:
                    ttEntries.append("lock range")
                if display == scanResBonus:
                    ttEntries.append("scan resolution")
                tooltip = "{0} dampening".format(
                    formatList(ttEntries)).capitalize()
                return text, tooltip
            if falloffRangeMult is not None and optimalRangeMult is not None and trackingSpeedMult is not None:
                falloffRangeBonus = (falloffRangeMult - 1) * 100
                optimalRangeBonus = (optimalRangeMult - 1) * 100
                trackingSpeedBonus = (trackingSpeedMult - 1) * 100
                display = 0
                for bonus in (falloffRangeBonus, optimalRangeBonus,
                              trackingSpeedBonus):
                    if abs(bonus) > abs(display):
                        display = bonus
                if not display:
                    return "", None
                text = "{0}%".format(formatAmount(display, 3, 0, 3),
                                     forceSign=True)
                ttEntries = []
                if display == optimalRangeBonus:
                    ttEntries.append("optimal range")
                if display == falloffRangeBonus:
                    ttEntries.append("falloff range")
                if display == trackingSpeedBonus:
                    ttEntries.append("tracking speed")
                tooltip = "{0} disruption".format(
                    formatList(ttEntries)).capitalize()
                return text, tooltip
            if grav is not None and ladar is not None and radar is not None and magnet is not None:
                display = max(grav, ladar, radar, magnet)
                if not display:
                    return "", None
                text = "{0}".format(formatAmount(display, 3, 0, 3))
                ttEntries = []
                if display == grav:
                    ttEntries.append("gravimetric")
                if display == ladar:
                    ttEntries.append("ladar")
                if display == magnet:
                    ttEntries.append("magnetometric")
                if display == radar:
                    ttEntries.append("radar")
                plu = "" if len(ttEntries) == 1 else "s"
                tooltip = "{0} strength{1}".format(formatList(ttEntries),
                                                   plu).capitalize()
                return text, tooltip
            else:
                return "", None
        elif itemGroup == "Fighter Bomber":
            optimalSig = stuff.getModifiedItemAttr("optimalSigRadius")
            if not optimalSig:
                return "", None
            text = "{0}m".format(formatAmount(optimalSig, 3, 0, 3))
            tooltip = "Optimal signature radius"
            return text, tooltip
        elif itemGroup in ("Frequency Mining Laser", "Strip Miner",
                           "Mining Laser", "Gas Cloud Harvester",
                           "Mining Drone"):
            miningAmount = stuff.getModifiedItemAttr(
                "specialtyMiningAmount") or stuff.getModifiedItemAttr(
                    "miningAmount")
            cycleTime = getattr(stuff, 'cycleTime',
                                stuff.getModifiedItemAttr("duration"))
            if not miningAmount or not cycleTime:
                return "", None
            minePerSec = (float(miningAmount) * 1000 / cycleTime)
            text = "{0} m3/s".format(formatAmount(minePerSec, 3, 0, 3))
            tooltip = "Mining Yield per second ({0} per hour)".format(
                formatAmount(minePerSec * 3600, 3, 0, 3))
            return text, tooltip
        elif itemGroup == "Logistic Drone":
            armorAmount = stuff.getModifiedItemAttr("armorDamageAmount")
            shieldAmount = stuff.getModifiedItemAttr("shieldBonus")
            hullAmount = stuff.getModifiedItemAttr("structureDamageAmount")
            repAmount = armorAmount or shieldAmount or hullAmount
            cycleTime = stuff.getModifiedItemAttr("duration")
            if not repAmount or not cycleTime:
                return "", None
            repPerSecPerDrone = repPerSec = float(repAmount) * 1000 / cycleTime

            if isinstance(stuff, Drone):
                repPerSec *= stuff.amount

            text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3))
            ttEntries = []
            if hullAmount is not None and repAmount == hullAmount:
                ttEntries.append("structure")
            if armorAmount is not None and repAmount == armorAmount:
                ttEntries.append("armor")
            if shieldAmount is not None and repAmount == shieldAmount:
                ttEntries.append("shield")

            tooltip = "{0} HP repaired per second\n{1} HP/s per drone".format(
                formatList(ttEntries).capitalize(), repPerSecPerDrone)
            return text, tooltip
        elif itemGroup == "Energy Neutralizer Drone":
            neutAmount = stuff.getModifiedItemAttr("energyNeutralizerAmount")
            cycleTime = stuff.getModifiedItemAttr("energyNeutralizerDuration")
            if not neutAmount or not cycleTime:
                return "", None
            capPerSec = float(-neutAmount) * 1000 / cycleTime
            text = "{0}/s".format(formatAmount(capPerSec, 3, 0, 3))
            tooltip = "Energy neutralization per second"
            return text, tooltip
        elif itemGroup == "Micro Jump Drive":
            cycleTime = stuff.getModifiedItemAttr("duration") / 1000
            text = "{0}s".format(cycleTime)
            tooltip = "Spoolup time"
            return text, tooltip
        elif itemGroup in ("Siege Module", "Cynosural Field"):
            amt = stuff.getModifiedItemAttr("consumptionQuantity")
            if amt:
                typeID = stuff.getModifiedItemAttr("consumptionType")
                item = Market.getInstance().getItem(typeID)
                text = "{0} units".format(formatAmount(amt, 3, 0, 3))
                return text, item.name
            else:
                return "", None
        elif itemGroup in (
                "Ancillary Armor Repairer",
                "Ancillary Shield Booster",
                "Capacitor Booster",
                "Ancillary Remote Armor Repairer",
                "Ancillary Remote Shield Booster",
        ):
            if "Armor" in itemGroup or "Shield" in itemGroup:
                boosted_attribute = "HP"
                reload_time = item.getAttribute("reloadTime", 0) / 1000
            elif "Capacitor" in itemGroup:
                boosted_attribute = "Cap"
                reload_time = 10
            else:
                boosted_attribute = ""
                reload_time = 0

            cycles = max(stuff.numShots, 0)
            cycleTime = max(stuff.rawCycleTime, 0)

            # Get HP or boosted amount
            stuff_hp = max(stuff.hpBeforeReload, 0)
            armor_hp = stuff.getModifiedItemAttr("armorDamageAmount", 0)
            capacitor_hp = stuff.getModifiedChargeAttr("capacitorBonus", 0)
            shield_hp = stuff.getModifiedItemAttr("shieldBonus", 0)
            hp = max(stuff_hp, armor_hp * cycles, capacitor_hp * cycles,
                     shield_hp * cycles, 0)

            if not hp or not cycleTime or not cycles:
                return "", None

            fit = Fit.getInstance().getFit(self.fittingView.getActiveFit())
            ehpTotal = fit.ehp
            hpTotal = fit.hp
            useEhp = self.mainFrame.statsPane.nameViewMap[
                "resistancesViewFull"].showEffective
            tooltip = "{0} restored over duration using charges (plus reload)".format(
                boosted_attribute)

            if useEhp and boosted_attribute == "HP" and "Remote" not in itemGroup:
                if "Ancillary Armor Repairer" in itemGroup:
                    hpRatio = ehpTotal["armor"] / hpTotal["armor"]
                else:
                    hpRatio = ehpTotal["shield"] / hpTotal["shield"]
                tooltip = "E{0}".format(tooltip)
            else:
                hpRatio = 1

            if "Ancillary" in itemGroup and "Armor" in itemGroup:
                hpRatio *= stuff.getModifiedItemAttr(
                    "chargedArmorDamageMultiplier", 1)

            ehp = hp * hpRatio

            duration = cycles * cycleTime / 1000
            for number_of_cycles in {5, 10, 25}:
                tooltip = "{0}\n{1} charges lasts {2} seconds ({3} cycles)".format(
                    tooltip, formatAmount(number_of_cycles * cycles, 3, 0, 3),
                    formatAmount((duration + reload_time) * number_of_cycles,
                                 3, 0, 3),
                    formatAmount(number_of_cycles, 3, 0, 3))
            text = "{0} / {1}s (+{2}s)".format(
                formatAmount(ehp, 3, 0, 9), formatAmount(duration, 3, 0, 3),
                formatAmount(reload_time, 3, 0, 3))

            return text, tooltip
        elif itemGroup == "Armor Resistance Shift Hardener":
            itemArmorResistanceShiftHardenerEM = (
                1 - stuff.getModifiedItemAttr("armorEmDamageResonance")) * 100
            itemArmorResistanceShiftHardenerTherm = (
                1 -
                stuff.getModifiedItemAttr("armorThermalDamageResonance")) * 100
            itemArmorResistanceShiftHardenerKin = (
                1 -
                stuff.getModifiedItemAttr("armorKineticDamageResonance")) * 100
            itemArmorResistanceShiftHardenerExp = (
                1 - stuff.getModifiedItemAttr("armorExplosiveDamageResonance")
            ) * 100

            text = "{0}% | {1}% | {2}% | {3}%".format(
                formatAmount(itemArmorResistanceShiftHardenerEM, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerTherm, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerKin, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerExp, 3, 0, 3),
            )
            tooltip = "Resistances Shifted to Damage Profile:\n{0}% EM | {1}% Therm | {2}% Kin | {3}% Exp".format(
                formatAmount(itemArmorResistanceShiftHardenerEM, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerTherm, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerKin, 3, 0, 3),
                formatAmount(itemArmorResistanceShiftHardenerExp, 3, 0, 3),
            )
            return text, tooltip
        elif stuff.charge is not None:
            chargeGroup = stuff.charge.group.name
            if chargeGroup.endswith("Rocket") or chargeGroup.endswith(
                    "Missile") or chargeGroup.endswith("Torpedo"):
                cloudSize = stuff.getModifiedChargeAttr("aoeCloudSize")
                aoeVelocity = stuff.getModifiedChargeAttr("aoeVelocity")
                if not cloudSize or not aoeVelocity:
                    return "", None
                text = "{0}{1} | {2}{3}".format(
                    formatAmount(cloudSize, 3, 0, 3), "m",
                    formatAmount(aoeVelocity, 3, 0, 3), "m/s")
                tooltip = "Explosion radius and explosion velocity"
                return text, tooltip
            elif chargeGroup == "Bomb":
                cloudSize = stuff.getModifiedChargeAttr("aoeCloudSize")
                if not cloudSize:
                    return "", None
                text = "{0}{1}".format(formatAmount(cloudSize, 3, 0, 3), "m")
                tooltip = "Explosion radius"
                return text, tooltip
            elif chargeGroup in ("Scanner Probe", ):
                scanStr = stuff.getModifiedChargeAttr("baseSensorStrength")
                baseRange = stuff.getModifiedChargeAttr("baseScanRange")
                if not scanStr or not baseRange:
                    return "", None
                strTwoAu = scanStr / (2.0 / baseRange)
                text = "{0}".format(formatAmount(strTwoAu, 3, 0, 3))
                tooltip = "Scan strength with 2 AU scan range"
                return text, tooltip
            else:
                return "", None
        else:
            return "", None
Exemplo n.º 48
0
Arquivo: efs.py Projeto: zliu/Pyfa
    def exportEfs(fit, typeNotFitFlag):
        sFit = Fit.getInstance()
        includeShipTypeData = typeNotFitFlag > 0
        if includeShipTypeData:
            fitName = fit.name
        else:
            fitName = fit.ship.name + ": " + fit.name
        pyfalog.info("Creating Eve Fleet Simulator data for: " + fit.name)
        fitModAttr = fit.ship.getModifiedItemAttr
        propData = EfsPort.getPropData(fit, sFit)
        mwdPropSpeed = fit.maxSpeed
        if includeShipTypeData:
            mwdPropSpeed = EfsPort.getT2MwdSpeed(fit, sFit)
        projections = EfsPort.getOutgoingProjectionData(fit)
        modInfo = EfsPort.getModuleInfo(fit)
        moduleNames = modInfo["moduleNames"]
        modTypeIDs = modInfo["modTypeIDs"]
        weaponSystems = EfsPort.getWeaponSystemData(fit)

        turretSlots = fitModAttr("turretSlotsLeft") if fitModAttr(
            "turretSlotsLeft") is not None else 0
        launcherSlots = fitModAttr("launcherSlotsLeft") if fitModAttr(
            "launcherSlotsLeft") is not None else 0
        droneBandwidth = fitModAttr("droneBandwidth") if fitModAttr(
            "droneBandwidth") is not None else 0
        weaponBonusMultipliers = EfsPort.getWeaponBonusMultipliers(fit)
        effectiveTurretSlots = round(
            turretSlots * weaponBonusMultipliers["turret"], 2)
        effectiveLauncherSlots = round(
            launcherSlots * weaponBonusMultipliers["launcher"], 2)
        effectiveDroneBandwidth = round(
            droneBandwidth * weaponBonusMultipliers["droneBandwidth"], 2)
        # Assume a T2 siege module for dreads
        if fit.ship.item.group.name == "Dreadnought":
            effectiveTurretSlots *= 9.4
            effectiveLauncherSlots *= 15
        hullResonance = {
            "exp": fitModAttr("explosiveDamageResonance"),
            "kin": fitModAttr("kineticDamageResonance"),
            "therm": fitModAttr("thermalDamageResonance"),
            "em": fitModAttr("emDamageResonance")
        }
        armorResonance = {
            "exp": fitModAttr("armorExplosiveDamageResonance"),
            "kin": fitModAttr("armorKineticDamageResonance"),
            "therm": fitModAttr("armorThermalDamageResonance"),
            "em": fitModAttr("armorEmDamageResonance")
        }
        shieldResonance = {
            "exp": fitModAttr("shieldExplosiveDamageResonance"),
            "kin": fitModAttr("shieldKineticDamageResonance"),
            "therm": fitModAttr("shieldThermalDamageResonance"),
            "em": fitModAttr("shieldEmDamageResonance")
        }
        resonance = {
            "hull": hullResonance,
            "armor": armorResonance,
            "shield": shieldResonance
        }
        shipSize = EfsPort.getShipSize(fit.ship.item.groupID)
        try:
            dataDict = {
                "name": fitName,
                "ehp": fit.ehp,
                "droneDPS": fit.droneDPS,
                "droneVolley": fit.droneVolley,
                "hp": fit.hp,
                "maxTargets": fit.maxTargets,
                "maxSpeed": fit.maxSpeed,
                "weaponVolley": fit.weaponVolley,
                "totalVolley": fit.totalVolley,
                "maxTargetRange": fit.maxTargetRange,
                "scanStrength": fit.scanStrength,
                "weaponDPS": fit.weaponDPS,
                "alignTime": fit.alignTime,
                "signatureRadius": fitModAttr("signatureRadius"),
                "weapons": weaponSystems,
                "scanRes": fitModAttr("scanResolution"),
                "capUsed": fit.capUsed,
                "capRecharge": fit.capRecharge,
                "rigSlots": fitModAttr("rigSlots"),
                "lowSlots": fitModAttr("lowSlots"),
                "midSlots": fitModAttr("medSlots"),
                "highSlots": fitModAttr("hiSlots"),
                "turretSlots": fitModAttr("turretSlotsLeft"),
                "launcherSlots": fitModAttr("launcherSlotsLeft"),
                "powerOutput": fitModAttr("powerOutput"),
                "cpuOutput": fitModAttr("cpuOutput"),
                "rigSize": fitModAttr("rigSize"),
                "effectiveTurrets": effectiveTurretSlots,
                "effectiveLaunchers": effectiveLauncherSlots,
                "effectiveDroneBandwidth": effectiveDroneBandwidth,
                "resonance": resonance,
                "typeID": fit.shipID,
                "groupID": fit.ship.item.groupID,
                "shipSize": shipSize,
                "droneControlRange": fitModAttr("droneControlRange"),
                "mass": fitModAttr("mass"),
                "unpropedSpeed": propData["unpropedSpeed"],
                "unpropedSig": propData["unpropedSig"],
                "usingMWD": propData["usingMWD"],
                "mwdPropSpeed": mwdPropSpeed,
                "projections": projections,
                "modTypeIDs": modTypeIDs,
                "moduleNames": moduleNames,
                "pyfaVersion": pyfaVersion,
                "efsExportVersion": EfsPort.version
            }
        except TypeError:
            pyfalog.error("Error parsing fit:" + str(fit))
            pyfalog.error(TypeError)
            dataDict = {"name": fitName + "Fit could not be correctly parsed"}
        export = json.dumps(dataDict, skipkeys=True)
        return export
Exemplo n.º 49
0
 def OnFitRemoved(self, event):
     event.Skip()
     fitID = self.mainFrame.getActiveFit()
     fit = Fit.getInstance().getFit(fitID)
     self.refreshContents(fit)
Exemplo n.º 50
0
 def Do(self):
     fit = Fit.getInstance().getFit(self.fitID)
     srcMod = fit.modules[self.srcModPosition]
     if srcMod.isEmpty:
         return False
     srcModItemID = srcMod.itemID
     dstCargo = next(
         (c for c in fit.cargo if c.itemID == self.dstCargoItemID), None)
     success = False
     # Attempt to swap if we're moving our module onto a module in the cargo hold
     if not self.copy and dstCargo is not None and dstCargo.item.isModule:
         if srcModItemID == self.dstCargoItemID:
             return False
         srcModSlot = srcMod.slot
         newModInfo = ModuleInfo.fromModule(srcMod, unmutate=True)
         newModInfo.itemID = self.dstCargoItemID
         srcModChargeItemID = srcMod.chargeID
         srcModChargeAmount = srcMod.numCharges
         commands = []
         commands.append(
             CalcRemoveCargoCommand(fitID=self.fitID,
                                    cargoInfo=CargoInfo(
                                        itemID=self.dstCargoItemID,
                                        amount=1),
                                    commit=False))
         commands.append(
             CalcAddCargoCommand(
                 fitID=self.fitID,
                 # We cannot put mutated items to cargo, so use unmutated item ID
                 cargoInfo=CargoInfo(itemID=ModuleInfo.fromModule(
                     srcMod, unmutate=True).itemID,
                                     amount=1),
                 commit=False))
         cmdReplace = CalcReplaceLocalModuleCommand(
             fitID=self.fitID,
             position=self.srcModPosition,
             newModInfo=newModInfo,
             unloadInvalidCharges=True,
             commit=False)
         commands.append(cmdReplace)
         # Submit batch now because we need to have updated info on fit to keep going
         success = self.internalHistory.submitBatch(*commands)
         newMod = fit.modules[self.srcModPosition]
         # Process charge changes if module is moved to proper slot
         if newMod.slot == srcModSlot:
             # If we had to unload charge, add it to cargo
             if cmdReplace.unloadedCharge and srcModChargeItemID is not None:
                 cmdAddCargoCharge = CalcAddCargoCommand(
                     fitID=self.fitID,
                     cargoInfo=CargoInfo(itemID=srcModChargeItemID,
                                         amount=srcModChargeAmount),
                     commit=False)
                 success = self.internalHistory.submit(cmdAddCargoCharge)
             # If we did not unload charge and there still was a charge, see if amount differs and process it
             elif not cmdReplace.unloadedCharge and srcModChargeItemID is not None:
                 # How many extra charges do we need to take from cargo
                 extraChargeAmount = newMod.numCharges - srcModChargeAmount
                 if extraChargeAmount > 0:
                     cmdRemoveCargoExtraCharge = CalcRemoveCargoCommand(
                         fitID=self.fitID,
                         cargoInfo=CargoInfo(itemID=srcModChargeItemID,
                                             amount=extraChargeAmount),
                         commit=False)
                     # Do not check if operation was successful or not, we're okay if we have no such
                     # charges in cargo
                     self.internalHistory.submit(cmdRemoveCargoExtraCharge)
                 elif extraChargeAmount < 0:
                     cmdAddCargoExtraCharge = CalcAddCargoCommand(
                         fitID=self.fitID,
                         cargoInfo=CargoInfo(itemID=srcModChargeItemID,
                                             amount=abs(extraChargeAmount)),
                         commit=False)
                     success = self.internalHistory.submit(
                         cmdAddCargoExtraCharge)
             if success:
                 # Store info to properly send events later
                 self.removedModItemID = srcModItemID
                 self.addedModItemID = self.dstCargoItemID
         # If drag happened to module which cannot be fit into current slot - consider it as failure
         else:
             success = False
         # And in case of any failures, cancel everything to try to do move instead
         if not success:
             self.internalHistory.undoAll()
     # Just dump module and its charges into cargo when copying or moving to cargo
     if not success:
         commands = []
         commands.append(
             CalcAddCargoCommand(fitID=self.fitID,
                                 cargoInfo=CargoInfo(
                                     itemID=ModuleInfo.fromModule(
                                         srcMod, unmutate=True).itemID,
                                     amount=1),
                                 commit=False))
         if srcMod.chargeID is not None:
             commands.append(
                 CalcAddCargoCommand(fitID=self.fitID,
                                     cargoInfo=CargoInfo(
                                         itemID=srcMod.chargeID,
                                         amount=srcMod.numCharges),
                                     commit=False))
         if not self.copy:
             commands.append(
                 CalcRemoveLocalModulesCommand(
                     fitID=self.fitID,
                     positions=[self.srcModPosition],
                     commit=False))
         success = self.internalHistory.submitBatch(*commands)
     eos.db.commit()
     sFit = Fit.getInstance()
     sFit.recalc(self.fitID)
     self.savedRemovedDummies = sFit.fill(self.fitID)
     events = []
     if self.removedModItemID is not None:
         events.append(
             GE.FitChanged(fitID=self.fitID,
                           action='moddel',
                           typeID=self.removedModItemID))
     if self.addedModItemID is not None:
         events.append(
             GE.FitChanged(fitID=self.fitID,
                           action='modadd',
                           typeID=self.addedModItemID))
     if not events:
         events.append(GE.FitChanged(fitID=self.fitID))
     for event in events:
         wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), event)
     return success
Exemplo n.º 51
0
    def fetchPrices(cls, prices, fetchTimeout, validityOverride):
        """Fetch all prices passed to this method"""

        # Dictionary for our price objects
        priceMap = {}
        # Check all provided price objects, and add those we want to update to
        # dictionary
        for price in prices:
            if not price.isValid(validityOverride):
                priceMap[price.typeID] = price

        if not priceMap:
            return

        # Compose list of items we're going to request
        for typeID in tuple(priceMap):
            # Get item object
            item = db.getItem(typeID)
            # We're not going to request items only with market group, as our current market
            # sources do not provide any data for items not on the market
            if item is None:
                continue
            if not item.marketGroupID:
                priceMap[typeID].update(PriceStatus.notSupported)
                del priceMap[typeID]
                continue

        if not priceMap:
            return

        sFit = Fit.getInstance()

        if len(cls.sources.keys()) == 0:
            pyfalog.warn('No price source can be found')
            return

        # attempt to find user's selected price source, otherwise get first one
        sourceAll = list(cls.sources.keys())
        sourcePrimary = sFit.serviceFittingOptions[
            "priceSource"] if sFit.serviceFittingOptions[
                "priceSource"] in sourceAll else sourceAll[0]

        # Format: {source name: timeout weight}
        sources = {sourcePrimary: len(sourceAll)}
        for source in sourceAll:
            if source == sourcePrimary:
                continue
            sources[source] = min(sources.values()) - 1
        timeoutWeightMult = fetchTimeout / sum(sources.values())

        # Record timeouts as it will affect our final decision
        timedOutSources = {}

        for source, timeoutWeight in sources.items():
            pyfalog.info('Trying {}'.format(source))
            timedOutSources[source] = False
            sourceFetchTimeout = timeoutWeight * timeoutWeightMult
            try:
                sourceCls = cls.sources.get(source)
                sourceCls(
                    priceMap,
                    cls.systemsList[sFit.serviceFittingOptions["priceSystem"]],
                    sourceFetchTimeout)
            except TimeoutError:
                pyfalog.warning(
                    "Price fetch timeout for source {}".format(source))
                timedOutSources[source] = True
            except Exception as e:
                pyfalog.warn(
                    'Failed to fetch prices from price source {}: {}'.format(
                        source, e))
            # Sources remove price map items as they fetch info, if none remain then we're done
            if not priceMap:
                break

        # If we get to this point, then we've failed to get price with all our sources
        # If all sources failed due to timeouts, set one status
        if all(to is True for to in timedOutSources.values()):
            for typeID in priceMap.keys():
                priceMap[typeID].update(PriceStatus.fetchTimeout)
        # If some sources failed due to any other reason, then it's definitely not network
        # timeout and we just set another status
        else:
            for typeID in priceMap.keys():
                priceMap[typeID].update(PriceStatus.fetchFail)
Exemplo n.º 52
0
    def populatePanel(self, panel):
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW)

        self.engine_settings = EOSSettings.getInstance()

        self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title,
                                     wx.DefaultPosition, wx.DefaultSize, 0)
        self.stTitle.Wrap(-1)
        self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
        mainSizer.Add(self.stTitle, 0, wx.ALL, 5)

        self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.LI_HORIZONTAL)
        mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)

        self.cbGlobalForceReload = wx.CheckBox(
            panel, wx.ID_ANY,
            "Factor in reload time when calculating capacitor usage, damage, and tank.",
            wx.DefaultPosition, wx.DefaultSize, 0)

        mainSizer.Add(self.cbGlobalForceReload, 0, wx.ALL | wx.EXPAND, 5)

        self.cbStrictSkillLevels = wx.CheckBox(
            panel, wx.ID_ANY, "Enforce strict skill level requirements",
            wx.DefaultPosition, wx.DefaultSize, 0)
        self.cbStrictSkillLevels.SetCursor(helpCursor)
        self.cbStrictSkillLevels.SetToolTip(
            wx.ToolTip(
                'When enabled, skills will check their dependencies\' requirements when their levels change and reset '
                +
                'skills that no longer meet the requirement.\neg: Setting Drones from level V to IV will reset the Heavy '
                + 'Drone Operation skill, as that requires Drones V'))

        mainSizer.Add(self.cbStrictSkillLevels, 0, wx.ALL | wx.EXPAND, 5)

        self.cbUniversalAdaptiveArmorHardener = wx.CheckBox(
            panel, wx.ID_ANY,
            "When damage profile is Uniform, set Reactive Armor " +
            "Hardener to match (old behavior).", wx.DefaultPosition,
            wx.DefaultSize, 0)
        mainSizer.Add(self.cbUniversalAdaptiveArmorHardener, 0,
                      wx.ALL | wx.EXPAND, 5)

        spoolup_sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.spool_up_label = wx.StaticText(
            panel, wx.ID_ANY, "Global Default Spoolup Percentage:",
            wx.DefaultPosition, wx.DefaultSize, 0)
        self.spool_up_label.Wrap(-1)
        self.spool_up_label.SetCursor(helpCursor)
        self.spool_up_label.SetToolTip(
            wx.ToolTip(
                'The amount of spoolup to use by default on module which support it. Can be changed on a per-module basis'
            ))

        spoolup_sizer.Add(self.spool_up_label, 0,
                          wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        self.spoolup_value = IntCtrl(panel, min=0, max=100, limited=True)
        spoolup_sizer.Add(self.spoolup_value, 0, wx.ALL, 5)

        mainSizer.Add(spoolup_sizer, 0, wx.ALL | wx.EXPAND, 0)

        # Future code once new cap sim is implemented
        '''
        self.cbGlobalForceReactivationTimer = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 )
        mainSizer.Add( self.cbGlobalForceReactivationTimer, 0, wx.ALL|wx.EXPAND, 5 )

        text =  u"   Ignores reactivation timer when calculating capacitor usage,\n   damage, and tank."
        self.cbGlobalForceReactivationTimerText = wx.StaticText( panel, wx.ID_ANY, text, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.cbGlobalForceReactivationTimerText.Wrap( -1 )
        self.cbGlobalForceReactivationTimerText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) )
        mainSizer.Add( self.cbGlobalForceReactivationTimerText, 0, wx.ALL, 5 )
        '''

        # Future code for mining laser crystal
        '''
        self.cbGlobalMiningSpecialtyCrystal = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 )
        mainSizer.Add( self.cbGlobalMiningSpecialtyCrystal, 0, wx.ALL|wx.EXPAND, 5 )

        text = u"   If enabled, displays the Specialty Crystal mining amount.\n   This is the amount mined when using crystals and mining the matching asteroid."
        self.cbGlobalMiningSpecialtyCrystalText = wx.StaticText( panel, wx.ID_ANY, text, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.cbGlobalMiningSpecialtyCrystalText.Wrap( -1 )
        self.cbGlobalMiningSpecialtyCrystalText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) )
        mainSizer.Add( self.cbGlobalMiningSpecialtyCrystalText, 0, wx.ALL, 5 )
        '''

        self.sFit = Fit.getInstance()

        self.cbGlobalForceReload.SetValue(
            self.sFit.serviceFittingOptions["useGlobalForceReload"])
        self.cbGlobalForceReload.Bind(wx.EVT_CHECKBOX,
                                      self.OnCBGlobalForceReloadStateChange)

        self.cbStrictSkillLevels.SetValue(
            self.engine_settings.get("strictSkillLevels"))
        self.cbStrictSkillLevels.Bind(wx.EVT_CHECKBOX,
                                      self.OnCBStrictSkillLevelsChange)

        self.cbUniversalAdaptiveArmorHardener.SetValue(
            self.engine_settings.get("useStaticAdaptiveArmorHardener"))
        self.cbUniversalAdaptiveArmorHardener.Bind(
            wx.EVT_CHECKBOX, self.OnCBUniversalAdaptiveArmorHardenerChange)

        self.spoolup_value.SetValue(
            int(
                self.engine_settings.get("globalDefaultSpoolupPercentage") *
                100))
        self.spoolup_value.Bind(wx.lib.intctrl.EVT_INT, self.OnSpoolupChange)

        panel.SetSizer(mainSizer)
        panel.Layout()
Exemplo n.º 53
0
    def getSubMenu(self, context, selection, rootMenu, i, pitem):
        self.moduleLookup = {}
        sFit = Fit.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())

        def get_metalevel(x):
            if 'metaLevel' not in x.attributes:
                return 0
            return x.attributes['metaLevel'].value

        def get_metagroup(x):
            # We want deadspace before officer mods
            remap = {5: 6, 6: 5}
            return remap.get(x.metaGroup.ID, x.metaGroup.ID) if x.metaGroup is not None else 0

        def get_boosterrank(x):
            # If we're returning a lot of items, sort my name
            if len(self.variations) > 7:
                return x.name
            # Sort by booster chance to get some sort of pseudorank.
            elif 'boosterEffectChance1' in x.attributes:
                return x.attributes['boosterEffectChance1'].value
            # the "first" rank (Synth) doesn't have boosterEffectChance1. If we're not pulling back all boosters, return 0 for proper sorting
            else:
                return 0

        m = wx.Menu()

        # If on Windows we need to bind out events into the root menu, on other
        # platforms they need to go to our sub menu
        if 'wxMSW' in wx.PlatformInfo:
            bindmenu = rootMenu
        else:
            bindmenu = m

        # Sort items by metalevel, and group within that metalevel
        items = list(self.variations)
        # Sort all items by name first
        items.sort(key=lambda x: x.name)
        # Do not do any extra sorting for implants
        if 'implantItem' in context:
            pass
        # Boosters don't have meta or anything concrete that we can rank by. Go by chance to inflict side effect
        elif 'boosterItem' in context:
            items.sort(key=get_boosterrank)
        else:
            # sort by group and meta level
            items.sort(key=get_metalevel)
            items.sort(key=get_metagroup)

        group = None
        for item in items:
            # Apparently no metaGroup for the Tech I variant:
            if 'subSystem' in item.effects:
                thisgroup = item.marketGroup.marketGroupName
            elif item.metaGroup is None:
                thisgroup = 'Tech I'
            else:
                thisgroup = item.metaGroup.name

            if thisgroup != group and context not in ('implantItem', 'boosterItem'):
                group = thisgroup
                id = ContextMenu.nextID()
                m.Append(id, '─ %s ─' % group)
                m.Enable(id, False)

            id = ContextMenu.nextID()
            mitem = wx.MenuItem(rootMenu, id, item.name)
            bindmenu.Bind(wx.EVT_MENU, self.handleModule, mitem)

            self.moduleLookup[id] = item, context
            m.Append(mitem)
            mitem.Enable(fit.canFit(item))

        return m
Exemplo n.º 54
0
 def Do(self):
     cmd = CalcChangeProjectedModuleStateCommand(fitID=self.fitID, position=self.position, click=self.click)
     success = self.internalHistory.submit(cmd)
     Fit.getInstance().recalc(self.fitID)
     wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID))
     return success
Exemplo n.º 55
0
    def populatePanel(self, panel):
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()
        self.dirtySettings = False
        self.openFitsSettings = SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits",
                                                                           {"enabled": False, "pyfaOpenFits": []})

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
        self.stTitle.Wrap(-1)
        self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))

        helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW)
        mainSizer.Add(self.stTitle, 0, wx.ALL, 5)

        self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
        mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)

        self.cbGlobalChar = wx.CheckBox(panel, wx.ID_ANY, "Use global character", wx.DefaultPosition, wx.DefaultSize,
                                        0)
        mainSizer.Add(self.cbGlobalChar, 0, wx.ALL | wx.EXPAND, 5)

        self.cbDefaultCharImplants = wx.CheckBox(panel, wx.ID_ANY, "Use character implants by default for new fits",
                                                 wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbDefaultCharImplants, 0, wx.ALL | wx.EXPAND, 5)

        self.cbGlobalDmgPattern = wx.CheckBox(panel, wx.ID_ANY, "Use global damage pattern", wx.DefaultPosition,
                                              wx.DefaultSize, 0)
        mainSizer.Add(self.cbGlobalDmgPattern, 0, wx.ALL | wx.EXPAND, 5)

        self.cbCompactSkills = wx.CheckBox(panel, wx.ID_ANY, "Compact skills needed tooltip", wx.DefaultPosition,
                                           wx.DefaultSize, 0)
        mainSizer.Add(self.cbCompactSkills, 0, wx.ALL | wx.EXPAND, 5)

        self.cbFitColorSlots = wx.CheckBox(panel, wx.ID_ANY, "Color fitting view by slot", wx.DefaultPosition,
                                           wx.DefaultSize, 0)
        mainSizer.Add(self.cbFitColorSlots, 0, wx.ALL | wx.EXPAND, 5)

        self.cbReopenFits = wx.CheckBox(panel, wx.ID_ANY, "Reopen previous fits on startup", wx.DefaultPosition,
                                        wx.DefaultSize, 0)
        mainSizer.Add(self.cbReopenFits, 0, wx.ALL | wx.EXPAND, 5)

        self.cbRackSlots = wx.CheckBox(panel, wx.ID_ANY, "Separate Racks", wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbRackSlots, 0, wx.ALL | wx.EXPAND, 5)

        labelSizer = wx.BoxSizer(wx.VERTICAL)
        self.cbRackLabels = wx.CheckBox(panel, wx.ID_ANY, "Show Rack Labels", wx.DefaultPosition, wx.DefaultSize, 0)
        labelSizer.Add(self.cbRackLabels, 0, wx.ALL | wx.EXPAND, 5)
        mainSizer.Add(labelSizer, 0, wx.LEFT | wx.EXPAND, 30)

        self.cbShowTooltip = wx.CheckBox(panel, wx.ID_ANY, "Show fitting tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbShowTooltip, 0, wx.ALL | wx.EXPAND, 5)

        self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, "Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5)

        self.cbOpenFitInNew = wx.CheckBox(panel, wx.ID_ANY, "Open fittings in a new page by default",
                                          wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5)

        self.cbShowShipBrowserTooltip = wx.CheckBox(panel, wx.ID_ANY, "Show ship browser tooltip",
                                          wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add(self.cbShowShipBrowserTooltip, 0, wx.ALL | wx.EXPAND, 5)


        self.cbReloadAll = wx.CheckBox(panel, wx.ID_ANY, "Change charge in all modules of the same type",
                                       wx.DefaultPosition, wx.DefaultSize, 0)
        if "wxGTK" not in wx.PlatformInfo:
            self.cbReloadAll.SetCursor(helpCursor)
        self.cbReloadAll.SetToolTip(wx.ToolTip(
            'When disabled, reloads charges just in selected modules. Action can be reversed by holding Ctrl or Alt key while changing charge.'))
        mainSizer.Add(self.cbReloadAll, 0, wx.ALL | wx.EXPAND, 5)

        self.sFit = Fit.getInstance()

        self.cbGlobalChar.SetValue(self.sFit.serviceFittingOptions["useGlobalCharacter"])
        self.cbDefaultCharImplants.SetValue(self.sFit.serviceFittingOptions["useCharacterImplantsByDefault"])
        self.cbGlobalDmgPattern.SetValue(self.sFit.serviceFittingOptions["useGlobalDamagePattern"])
        self.cbFitColorSlots.SetValue(self.sFit.serviceFittingOptions["colorFitBySlot"] or False)
        self.cbRackSlots.SetValue(self.sFit.serviceFittingOptions["rackSlots"] or False)
        self.cbRackLabels.SetValue(self.sFit.serviceFittingOptions["rackLabels"] or False)
        self.cbCompactSkills.SetValue(self.sFit.serviceFittingOptions["compactSkills"] or False)
        self.cbReopenFits.SetValue(self.openFitsSettings["enabled"])
        self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False)
        self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"])
        self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"])
        self.cbShowShipBrowserTooltip.SetValue(self.sFit.serviceFittingOptions["showShipBrowserTooltip"])
        self.cbReloadAll.SetValue(self.sFit.serviceFittingOptions["ammoChangeAll"])

        self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange)
        self.cbDefaultCharImplants.Bind(wx.EVT_CHECKBOX, self.OnCBDefaultCharImplantsStateChange)
        self.cbGlobalDmgPattern.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange)
        self.cbFitColorSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalColorBySlot)
        self.cbRackSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackSlots)
        self.cbRackLabels.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackLabels)
        self.cbCompactSkills.Bind(wx.EVT_CHECKBOX, self.onCBCompactSkills)
        self.cbReopenFits.Bind(wx.EVT_CHECKBOX, self.onCBReopenFits)
        self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip)
        self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation)
        self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew)
        self.cbShowShipBrowserTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowShipBrowserTooltip)
        self.cbReloadAll.Bind(wx.EVT_CHECKBOX, self.onCBReloadAll)

        self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False)

        panel.SetSizer(mainSizer)
        panel.Layout()
Exemplo n.º 56
0
    def __init__(self, parent):
        super().__init__(parent,
                         id=wx.ID_ANY,
                         title="Character Editor",
                         resizeable=True,
                         pos=wx.DefaultPosition,
                         size=wx.Size(950, 650)
                         if "wxGTK" in wx.PlatformInfo else wx.Size(850, 600))

        i = wx.Icon(BitmapLoader.getBitmap("character_small", "gui"))
        self.SetIcon(i)

        self.mainFrame = parent
        # self.disableWin = wx.WindowDisabler(self)
        sFit = Fit.getInstance()

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.entityEditor = CharacterEntityEditor(self)
        mainSizer.Add(self.entityEditor, 0, wx.ALL | wx.EXPAND, 2)
        # Default drop down to current fit's character
        self.entityEditor.setActiveEntity(sFit.character)

        self.viewsNBContainer = wx.Notebook(self, wx.ID_ANY,
                                            wx.DefaultPosition, wx.DefaultSize,
                                            0)

        self.sview = SkillTreeView(self.viewsNBContainer)
        self.iview = ImplantEditorView(self.viewsNBContainer, self)
        self.aview = APIView(self.viewsNBContainer)

        self.viewsNBContainer.AddPage(self.sview, "Skills")
        self.viewsNBContainer.AddPage(self.iview, "Implants")
        self.viewsNBContainer.AddPage(self.aview, "EVE SSO")

        mainSizer.Add(self.viewsNBContainer, 1, wx.EXPAND | wx.ALL, 5)

        bSizerButtons = wx.BoxSizer(wx.HORIZONTAL)

        self.btnSaveChar = wx.Button(self, wx.ID_ANY, "Save")
        self.btnSaveAs = wx.Button(self, wx.ID_ANY, "Save As...")
        self.btnRevert = wx.Button(self, wx.ID_ANY, "Revert")
        self.btnOK = wx.Button(self, wx.ID_OK)

        bSizerButtons.Add(self.btnSaveChar, 0, wx.ALL, 5)
        bSizerButtons.Add(self.btnSaveAs, 0, wx.ALL, 5)
        bSizerButtons.Add(self.btnRevert, 0, wx.ALL, 5)
        bSizerButtons.AddStretchSpacer()
        bSizerButtons.Add(self.btnOK, 0, wx.ALL, 5)

        self.btnSaveChar.Bind(wx.EVT_BUTTON, self.saveChar)
        self.btnSaveAs.Bind(wx.EVT_BUTTON, self.saveCharAs)
        self.btnRevert.Bind(wx.EVT_BUTTON, self.revertChar)
        self.btnOK.Bind(wx.EVT_BUTTON, self.editingFinished)

        mainSizer.Add(bSizerButtons, 0, wx.EXPAND, 5)

        self.btnRestrict()

        self.SetSizer(mainSizer)
        self.Layout()

        self.SetMinSize(self.GetSize())
        self.Centre(wx.BOTH)

        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent)
        self.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
        self.entityEditor.Bind(wx.EVT_CHOICE, self.charChanged)

        self.charChanged(None)
Exemplo n.º 57
0
 def delaySearch(self, evt):
     sFit = Fit.getInstance()
     self.searchTimer.Stop()
     self.searchTimer.Start(sFit.serviceFittingOptions["marketSearchDelay"],
                            True)  # 150ms
Exemplo n.º 58
0
 def Do(self):
     cmd = CalcToggleFighterStateCommand(fitID=self.fitID, projected=False, position=self.position)
     success = self.internalHistory.submit(cmd)
     Fit.getInstance().recalc(self.fitID)
     wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID))
     return success
Exemplo n.º 59
0
    def click(self, event):
        """
        Handle click event on modules.

        This is only useful for the State column. If multiple items are selected,
        and we have clicked the State column, iterate through the selections and
        change State
        """

        clickedRow, _, col = self.HitTestSubItem(event.Position)

        # only do State column and ignore invalid rows
        if clickedRow != -1 and clickedRow not in self.blanks and col == self.getColIndex(State):
            selectedRows = []
            currentRow = self.GetFirstSelected()

            while currentRow != -1 and clickedRow not in self.blanks:
                selectedRows.append(currentRow)
                currentRow = self.GetNextSelected(currentRow)

            if clickedRow not in selectedRows:
                try:
                    selectedMods = [self.mods[clickedRow]]
                except IndexError:
                    return
            else:
                selectedMods = self.getSelectedMods()

            click = "ctrl" if event.GetModifiers() == wx.MOD_CONTROL or event.middleIsDown else "right" if event.GetButton() == 3 else "left"

            try:
                mainMod = self.mods[clickedRow]
            except IndexError:
                return
            if mainMod.isEmpty:
                return
            fitID = self.mainFrame.getActiveFit()
            fit = Fit.getInstance().getFit(fitID)
            if mainMod not in fit.modules:
                return
            mainPosition = fit.modules.index(mainMod)
            if event.GetModifiers() == wx.MOD_ALT:
                positions = getSimilarModPositions(fit.modules, mainMod)
            else:
                positions = []
                for position, mod in enumerate(fit.modules):
                    if mod in selectedMods:
                        positions.append(position)
            self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleStatesCommand(
                fitID=fitID,
                mainPosition=mainPosition,
                positions=positions,
                click=click))

            # update state tooltip
            tooltip = self.activeColumns[col].getToolTip(self.mods[clickedRow])
            if tooltip:
                self.SetToolTip(tooltip)

        else:
            event.Skip()
Exemplo n.º 60
0
    def _merge(self, src, dst):
        sFit = Fit.getInstance()
        fitID = self.mainFrame.getActiveFit()

        if sFit.mergeDrones(fitID, self.drones[src], self.drones[dst]):
            wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))