Exemple #1
0
    def refreshPanel(self, fit):
        if fit is not None:
            self.fit = fit
            # Compose a list of all the data we need & request it
            typeIDs = []
            typeIDs.append(fit.ship.item.ID)

            for mod in fit.modules:
                if not mod.isEmpty:
                    typeIDs.append(mod.itemID)

            for drone in fit.drones:
                typeIDs.append(drone.itemID)

            for fighter in fit.fighters:
                if fighter.amountActive > 0:
                    typeIDs.append(fighter.itemID)

            for cargo in fit.cargo:
                typeIDs.append(cargo.itemID)

            sMkt = Market.getInstance()
            sMkt.getPrices(typeIDs, self.processPrices)
            self.labelEMStatus.SetLabel("Updating prices...")
        else:
            self.labelEMStatus.SetLabel("")
            self.labelPriceShip.SetLabel("0.0 ISK")
            self.labelPriceFittings.SetLabel("0.0 ISK")
            self.labelPriceTotal.SetLabel("0.0 ISK")
            self._cachedFittings = self._cachedShip = self._cachedTotal = 0
            self.panel.Layout()
Exemple #2
0
    def display(self, srcContext, selection):
        if not self.settings.get('metaSwap'):
            return False

        if self.mainFrame.getActiveFit() is None or srcContext not in (
                "fittingModule",
                "droneItem",
                "fighterItem",
                "boosterItem",
                "implantItem",
                "cargoItem",
        ):
            return False

        # Check if list of variations is same for all of selection
        # If not - don't show the menu
        mkt = Market.getInstance()
        self.variations = None
        for i in selection:
            variations = mkt.getVariationsByItems([i.item])
            if self.variations is None:
                self.variations = variations
            else:
                if variations != self.variations:
                    return False

        self.selection = selection

        if len(self.variations) == 1:
            return False  # no variations from current module

        return True
Exemple #3
0
    def findCheaperReplacements(self, items, callback, fetchTimeout=10):
        sMkt = Market.getInstance()

        replacementsAll = {}  # All possible item replacements
        for item in items:
            if item in replacementsAll:
                continue
            itemRepls = sMkt.getReplacements(item)
            if itemRepls:
                replacementsAll[item] = itemRepls
        itemsToFetch = {i for i in chain(replacementsAll.keys(), *replacementsAll.values())}

        def makeCheapMapCb(requests):
            # Decide what we are going to replace
            replacementsCheaper = {}  # Items which should be replaced
            for replacee, replacers in replacementsAll.items():
                replacer = min(replacers, key=lambda i: i.price.price or math.inf)
                if (replacer.price.price or math.inf) < (replacee.price.price or math.inf):
                    replacementsCheaper[replacee] = replacer
            try:
                callback(replacementsCheaper)
            except Exception as e:
                pyfalog.critical("Execution of callback from findCheaperReplacements failed.")
                pyfalog.critical(e)

        # Prices older than 2 hours have to be refetched
        validityOverride = 2 * 60 * 60
        self.getPrices(itemsToFetch, makeCheapMapCb, fetchTimeout=fetchTimeout, validityOverride=validityOverride)
Exemple #4
0
    def spawnMenu(self, event):
        item = event.GetItem()
        self.skillTreeListCtrl.Select(item)
        thing = self.skillTreeListCtrl.GetFirstChild(item).IsOk()
        if thing:
            return

        id = self.skillTreeListCtrl.GetItemData(item)[1]
        eveItem = Market.getInstance().getItem(id)

        srcContext = "skillItem"
        itemContext = "Skill"
        context = (srcContext, itemContext)
        menu = ContextMenu.getMenu(eveItem, [eveItem], context)
        char = self.charEditor.entityEditor.getActiveEntity()
        if char.name not in ("All 0", "All 5"):
            menu.AppendSeparator()
            menu.Append(self.idUnlearned, "Unlearn")
            for level in range(6):
                menu.Append(self.idLevels[level], "Level %d" % level)
            # Doesn't make sense to have these menu items here, as they do not revert skill changes
            # done in an editor - because these changes are persisted anyway
            # menu.AppendSeparator()
            # menu.Append(self.revertID, "Revert")
            # menu.Append(self.saveID, "Save")
            menu.Bind(wx.EVT_MENU, self.changeLevel)

        self.PopupMenu(menu)
Exemple #5
0
    def display(self, srcContext, mainItem, selection):
        if not self.settings.get('metaSwap'):
            return False

        if self.mainFrame.getActiveFit() is None or srcContext not in (
            'fittingModule',
            'droneItem',
            'fighterItem',
            'boosterItem',
            'implantItem',
            'cargoItem',
            'projectedModule',
            'projectedDrone',
            'projectedFighter'
        ):
            return False

        if mainItem is None or getattr(mainItem, 'isEmpty', False):
            return False

        self.mainVariations = Market.getInstance().getVariationsByItems((mainItem.item,))
        # No variations from current module
        if len(self.mainVariations) < 2:
            return False

        self.mainItem = mainItem
        self.selection = selection
        return True
Exemple #6
0
    def droneKey(self, drone):
        sMkt = Market.getInstance()

        groupName = sMkt.getMarketGroupByItem(drone.item).name

        return (self.DRONE_ORDER.index(groupName),
                drone.item.name)
Exemple #7
0
    def getSubMenu(self, context, selection, rootMenu, i, pitem):
        msw = True if "wxMSW" in wx.PlatformInfo else False
        sMkt = Market.getInstance()
        effdata = sMkt.getSystemWideEffects()

        self.idmap = {}
        sub = wx.Menu()

        for swType in sorted(effdata):
            subItem = wx.MenuItem(sub, wx.ID_ANY, swType)
            grandSub = wx.Menu()
            subItem.SetSubMenu(grandSub)
            sub.AppendItem(subItem)

            for swData in sorted(effdata[swType], key=lambda tpl: tpl[2]):
                wxid = ContextMenu.nextID()
                swObj, swName, swClass = swData
                self.idmap[wxid] = (swObj, swName)
                grandSubItem = wx.MenuItem(grandSub, wxid, swClass)
                if msw:
                    rootMenu.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
                else:
                    grandSub.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
                grandSub.AppendItem(grandSubItem)
        return sub
Exemple #8
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)
Exemple #9
0
    def expandLookup(self, event):
        tree = self.availableImplantsTree
        sMkt = Market.getInstance()
        parent = event.Item
        child, _ = tree.GetFirstChild(parent)
        text = tree.GetItemText(child)

        if text == "dummy" or text == "itemdummy":
            tree.Delete(child)

        # if the dummy item is a market group, replace with actual market groups
        if text == "dummy":
            # Add 'real stoof!' instead
            currentMktGrp = sMkt.getMarketGroup(tree.GetPyData(parent), eager="children")
            for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
                iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(childMktGrp))
                childId = tree.AppendItem(parent, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
                if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
                    tree.AppendItem(childId, "dummy")
                else:
                    tree.AppendItem(childId, "itemdummy")

        # replace dummy with actual items
        if text == "itemdummy":
            currentMktGrp = sMkt.getMarketGroup(tree.GetPyData(parent))
            items = sMkt.getItemsByMarketGroup(currentMktGrp)
            for item in items:
                iconId = self.addMarketViewImage(item.icon.iconFile)
                tree.AppendItem(parent, item.name, iconId, data=wx.TreeItemData(item))

        tree.SortChildren(parent)
Exemple #10
0
    def getAbyssalWeather(self):
        sMkt = Market.getInstance()

        environments = {x.ID: x for x in sMkt.getGroup("Abyssal Environment").items}
        items = chain(sMkt.getGroup("MassiveEnvironments").items, sMkt.getGroup("Non-Interactable Object").items)

        grouped = {}
        flat = set()

        for beacon in items:
            if not beacon.isType('projected'):
                continue

            type = self.__class__.abyssal_mapping.get(beacon.name[0:-2], None)
            type = environments.get(type, None)
            if type is None:
                continue

            if type.name not in grouped:
                grouped[type.name] = set()

            display_name = "{} {}".format(type.name, beacon.name[-1:])
            grouped[type.name].add((beacon, display_name, display_name))

        # PVP weather
        flat.add((sMkt.getItem(49766), 'PvP Weather', 'PvP Weather'))

        return grouped, flat
Exemple #11
0
    def display(self, srcContext, mainItem):
        validContexts = ("marketItemMisc", "fittingModule",
                         "fittingCharge", "droneItem",
                         "implantItem", "boosterItem",
                         "projectedModule", "projectedDrone",
                         "projectedCharge", "cargoItem",
                         "implantItemChar", "fighterItem",
                         "projectedFighter")

        if srcContext not in validContexts or mainItem is None:
            return False

        if mainItem is None or getattr(mainItem, "isEmpty", False):
            return False

        sMkt = Market.getInstance()
        item = getattr(mainItem, "item", mainItem)
        isMutated = getattr(mainItem, "isMutated", False)
        mktGrp = sMkt.getMarketGroupByItem(item)
        if mktGrp is None and isMutated:
            mktGrp = sMkt.getMarketGroupByItem(mainItem.baseItem)

        # 1663 is Special Edition Festival Assets, we don't have root group for it
        if mktGrp is None or mktGrp.ID == 1663:
            return False

        doit = not mainItem.isEmpty if srcContext == "fittingModule" else True
        return doit
Exemple #12
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)
Exemple #13
0
 def Do(self):
     pyfalog.debug('Doing change of module charges according to map {} on fit {}'.format(self.chargeMap, self.fitID))
     sFit = Fit.getInstance()
     fit = sFit.getFit(self.fitID)
     container = fit.modules if not self.projected else fit.projectedModules
     changes = False
     self.savedChargeMap = {}
     sMkt = Market.getInstance()
     for position, chargeItemID in self.chargeMap.items():
         mod = container[position]
         if mod.isEmpty:
             continue
         if mod.chargeID is None and chargeItemID is None:
             continue
         if mod.chargeID == chargeItemID:
             continue
         chargeItem = sMkt.getItem(chargeItemID) if chargeItemID is not None else None
         if chargeItem is not None and not chargeItem.isCharge:
             continue
         if not self.ignoreRestriction and not mod.isValidCharge(chargeItem):
             pyfalog.warning('Invalid charge {} for {}'.format(chargeItem, mod))
             continue
         pyfalog.debug('Setting charge {} for {} on fit {}'.format(chargeItem, mod, self.fitID))
         self.savedChargeMap[position] = mod.chargeID
         changes = True
         mod.charge = chargeItem
     if not changes:
         return False
     sFit.recalc(fit)
     self.savedStateCheckChanges = sFit.checkStates(fit, None)
     return True
Exemple #14
0
    def display(self, srcContext, selection):
        if not self.settings.get('moduleAmmoPicker'):
            return False

        if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "projectedModule"):
            return False

        modules = selection if srcContext == "fittingModule" else (selection[0],)

        validCharges = None
        checkedTypes = set()

        for mod in modules:
            # loop through modules and gather list of valid charges
            if mod.item.ID in checkedTypes:
                continue
            checkedTypes.add(mod.item.ID)
            currCharges = mod.getValidCharges()
            if len(currCharges) > 0:
                if validCharges is not None and validCharges != currCharges:
                    return False

                validCharges = currCharges
                self.module = mod

        if validCharges is None:
            return False

        self.modules = modules
        self.charges = list([charge for charge in validCharges if Market.getInstance().getPublicityByItem(charge)])
        return len(self.charges) > 0
Exemple #15
0
    def display(self, srcContext, selection):
        if not self.settings.get('marketJump'):
            return False

        validContexts = ("marketItemMisc", "fittingModule",
                         "fittingCharge", "droneItem",
                         "implantItem", "boosterItem",
                         "projectedModule", "projectedDrone",
                         "projectedCharge", "cargoItem",
                         "implantItemChar", "fighterItem",
                         "projectedDrone")

        if srcContext not in validContexts or selection is None or len(selection) < 1:
            return False

        sMkt = Market.getInstance()
        item = getattr(selection[0], "item", selection[0])
        isMutated = getattr(selection[0], "isMutated", False)
        mktGrp = sMkt.getMarketGroupByItem(item)
        if mktGrp is None and isMutated:
            mktGrp = sMkt.getMarketGroupByItem(selection[0].baseItem)

        # 1663 is Special Edition Festival Assets, we don't have root group for it
        if mktGrp is None or mktGrp.ID == 1663:
            return False

        doit = not selection[0].isEmpty if srcContext == "fittingModule" else True
        return doit
Exemple #16
0
    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
Exemple #17
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
Exemple #18
0
 def groupHasFits(self, id):
     sMkt = Market.getInstance()
     grp = sMkt.getGroup(id, eager=("items", "group"))
     items = sMkt.getItemsByGroup(grp)
     for item in items:
         if self.countFitsWithShip(item.ID) > 0:
             return True
     return False
Exemple #19
0
 def Do(self):
     pyfalog.debug('Doing changing ship mode to {} for fit {}'.format(self.itemID, self.fitID))
     fit = Fit.getInstance().getFit(self.fitID)
     self.savedItemID = fit.mode.item.ID
     item = Market.getInstance().getItem(self.itemID)
     mode = Mode(item)
     fit.mode = mode
     return True
Exemple #20
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)
Exemple #21
0
    def getEffectBeacons(self, incursions=False):
        """
        Get dictionary with wormhole system-wide effects
        """
        sMkt = Market.getInstance()

        # todo: rework this
        # Container for system-wide effects
        grouped = {}

        # Expressions for matching when detecting effects we're looking for
        if incursions:
            validgroups = ("Incursion ship attributes effects",
                           "Invasion Effects")
        else:
            validgroups = ("Black Hole Effect Beacon",
                           "Cataclysmic Variable Effect Beacon",
                           "Magnetar Effect Beacon",
                           "Pulsar Effect Beacon",
                           "Red Giant Beacon",
                           "Wolf Rayet Effect Beacon")

        # Stuff we don't want to see in names
        garbages = ("Effects?", "Beacon", "ship attributes effects")

        # Get group with all the system-wide beacons
        grp = sMkt.getGroup("Effect Beacon")

        # Cycle through them
        for beacon in sMkt.getItemsByGroup(grp):
            # Check if it belongs to any valid group
            for group in validgroups:
                # Check beginning of the name only
                if re.match(group, beacon.name):
                    # Get full beacon name
                    beaconname = beacon.name
                    for garbage in garbages:
                        beaconname = re.sub(garbage, "", beaconname)
                    beaconname = re.sub(" {2,}", " ", beaconname).strip()
                    # Get short name
                    shortname = re.sub(group, "", beacon.name)
                    for garbage in garbages:
                        shortname = re.sub(garbage, "", shortname)
                    shortname = re.sub(" {2,}", " ", shortname).strip()
                    # Get group name
                    groupname = group
                    for garbage in garbages:
                        groupname = re.sub(garbage, "", groupname)
                    groupname = re.sub(" {2,}", " ", groupname).strip()
                    # Add stuff to dictionary
                    if groupname not in grouped:
                        grouped[groupname] = set()
                    grouped[groupname].add((beacon, beaconname, shortname))
                    # Break loop on 1st result
                    break

        return grouped, ()
Exemple #22
0
    def spawnMenu(self):
        sel = self.GetFirstSelected()
        if sel != -1:
            drone = self.drones[sel]

            sMkt = Market.getInstance()
            sourceContext = "droneItem"
            itemContext = sMkt.getCategoryByItem(drone.item).name
            menu = ContextMenu.getMenu((drone,), (sourceContext, itemContext))
            self.PopupMenu(menu)
Exemple #23
0
    def spawnMenu(self, event):
        sel = self.GetFirstSelected()
        if sel != -1:
            fighter = self.fighters[sel]

            sMkt = Market.getInstance()
            sourceContext = "fighterItem"
            itemContext = sMkt.getCategoryByItem(fighter.item).name
            menu = ContextMenu.getMenu((fighter,), (sourceContext, itemContext))
            self.PopupMenu(menu)
Exemple #24
0
 def fighterKey(self, fighter):
     groupName = Market.getInstance().getGroupByItem(fighter.item).name
     orderPos = self.FIGHTER_ORDER.index(groupName)
     # Sort support fighters by name, ignore their abilities
     if groupName == 'Support Fighter':
         abilityEffectIDs = ()
     # Group up fighters from various roles
     else:
         abilityEffectIDs = sorted(a.effectID for a in fighter.abilities)
     return orderPos, abilityEffectIDs, fighter.item.name
Exemple #25
0
    def addItem(self, event):
        item = Market.getInstance().getItem(event.itemID, eager='group.category')
        if item is None or not item.isFighter:
            event.Skip()
            return

        fitID = self.mainFrame.getActiveFit()
        if self.mainFrame.command.Submit(cmd.GuiAddLocalFighterCommand(fitID, event.itemID)):
            self.mainFrame.additionsPane.select('Fighters')

        event.Skip()
Exemple #26
0
def _fetchItem(typeName, eagerCat=False):
    sMkt = Market.getInstance()
    eager = 'group.category' if eagerCat else None
    try:
        item = sMkt.getItem(typeName, eager=eager)
    except:
        pyfalog.warning('service.port.eft: unable to fetch item "{}"'.format(typeName))
        return None
    if sMkt.getPublicityByItem(item):
        return item
    else:
        return None
Exemple #27
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()
Exemple #28
0
    def scheduleSearch(self, event=None):
        sMkt = Market.getInstance()

        search = self.searchBox.GetLineText(0)
        # Make sure we do not count wildcard as search symbol
        realsearch = search.replace("*", "")
        # Show nothing if query is too short
        if len(realsearch) < 3:
            self.clearSearch()
            return

        sMkt.searchItems(search, self.populateSearch, ["Implant"])
Exemple #29
0
    def spawnMenu(self,event):
        sel = self.GetFirstSelected()
        if sel != -1:
            sFit = Fit.getInstance()
            fit = sFit.getFit(self.mainFrame.getActiveFit())
            cargo = fit.cargo[sel]

            sMkt = Market.getInstance()
            sourceContext = "cargoItem"
            itemContext = sMkt.getCategoryByItem(cargo.item).name

            menu = ContextMenu.getMenu((cargo,), (sourceContext, itemContext))
            self.PopupMenu(menu)
Exemple #30
0
 def __handleCargo(self, varItem):
     fitID = self.mainFrame.getActiveFit()
     sMkt = Market.getInstance()
     itemIDs = []
     for cargo in self.selection:
         if cargo is self.mainItem:
             itemIDs.append(cargo.itemID)
             continue
         cargoVariations = sMkt.getVariationsByItems((cargo.item,))
         if cargoVariations == self.mainVariations:
             itemIDs.append(cargo.itemID)
     self.mainFrame.command.Submit(cmd.GuiChangeCargoMetasCommand(
         fitID=fitID, itemIDs=itemIDs, newItemID=varItem.ID))
Exemple #31
0
 def updateItems(self, updateDisplay=False):
     if updateDisplay:
         self.update(Market.getInstance().getItemsWithOverrides())
Exemple #32
0
def importXml(text, iportuser):
    from .port import Port
    # type: (str, IPortUser) -> list[eos.saveddata.fit.Fit]
    sMkt = Market.getInstance()
    doc = xml.dom.minidom.parseString(text)
    # NOTE:
    #   When L_MARK is included at this point,
    #   Decided to be localized data
    b_localized = L_MARK in text
    fittings = doc.getElementsByTagName("fittings").item(0)
    fittings = fittings.getElementsByTagName("fitting")
    fit_list = []
    failed = 0

    for fitting in fittings:
        try:
            fitobj = _resolve_ship(fitting, sMkt, b_localized)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            failed += 1
            continue

        # -- 170327 Ignored description --
        # read description from exported xml. (EVE client, EFT)
        description = fitting.getElementsByTagName("description").item(0).getAttribute("value")
        if description is None:
            description = ""
        elif len(description):
            # convert <br> to "\n" and remove html tags.
            if Port.is_tag_replace():
                description = replace_ltgt(
                    sequential_rep(description, r"<(br|BR)>", "\n", r"<[^<>]+>", "")
                )
        fitobj.notes = description

        hardwares = fitting.getElementsByTagName("hardware")
        moduleList = []
        for hardware in hardwares:
            try:
                item = _resolve_module(hardware, sMkt, b_localized)
                if not item or not item.published:
                    continue

                if item.category.name == "Drone":
                    d = Drone(item)
                    d.amount = int(hardware.getAttribute("qty"))
                    fitobj.drones.append(d)
                elif item.category.name == "Fighter":
                    ft = Fighter(item)
                    ft.amount = int(hardware.getAttribute("qty")) if ft.amount <= ft.fighterSquadronMaxSize else ft.fighterSquadronMaxSize
                    fitobj.fighters.append(ft)
                elif hardware.getAttribute("slot").lower() == "cargo":
                    # although the eve client only support charges in cargo, third-party programs
                    # may support items or "refits" in cargo. Support these by blindly adding all
                    # cargo, not just charges
                    c = Cargo(item)
                    c.amount = int(hardware.getAttribute("qty"))
                    fitobj.cargo.append(c)
                else:
                    try:
                        m = Module(item)
                    # When item can't be added to any slot (unknown item or just charge), ignore it
                    except ValueError:
                        pyfalog.warning("item can't be added to any slot (unknown item or just charge), ignore it")
                        continue
                    # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                    if item.category.name == "Subsystem":
                        if m.fits(fitobj):
                            m.owner = fitobj
                            fitobj.modules.append(m)
                    else:
                        if m.isValidState(FittingModuleState.ACTIVE):
                            m.state = activeStateLimit(m.item)

                        moduleList.append(m)

            except KeyboardInterrupt:
                pyfalog.warning("Keyboard Interrupt")
                continue

        # 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):
                module.owner = fitobj
                fitobj.modules.append(module)

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

    return fit_list
Exemple #33
0
    def __init__(self,
                 parent,
                 shipID=None,
                 shipFittingInfo=("Test", "TestTrait", 2),
                 itemData=None,
                 graphicID=None,
                 id=wx.ID_ANY,
                 pos=wx.DefaultPosition,
                 size=(0, 40),
                 style=0):
        SFItem.SFBrowserItem.__init__(self, parent, size=size)

        self.mainFrame = gui.mainFrame.MainFrame.getInstance()

        self._itemData = itemData

        self.shipRace = itemData

        self.shipID = shipID

        self.fontBig = wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.BOLD)
        self.fontNormal = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL)
        self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)

        self.shipBmp = None
        if graphicID:
            self.shipBmp = BitmapLoader.getBitmap(str(graphicID), "renders")
        if not self.shipBmp:
            self.shipBmp = BitmapLoader.getBitmap("ship_no_image_big", "gui")

        self.shipFittingInfo = shipFittingInfo
        self.shipName, self.shipTrait, self.shipFits = shipFittingInfo
        self.shipTrait = re.sub("<.*?>", " ", self.shipTrait)

        self.newBmp = BitmapLoader.getBitmap("fit_add_small", "gui")
        self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui")

        self.shipEffBk = BitmapLoader.getBitmap("fshipbk_big", "gui")

        img = self.shipEffBk.ConvertToImage()
        img = img.Mirror(False)
        self.shipEffBkMirrored = wx.Bitmap(img)

        self.raceBmp = BitmapLoader.getBitmap("race_%s_small" % self.shipRace,
                                              "gui")

        if not self.raceBmp:
            self.raceBmp = BitmapLoader.getBitmap("fit_delete_small", "gui")

        self.raceDropShadowBmp = drawUtils.CreateDropShadowBitmap(
            self.raceBmp, 0.2)

        sFit = Fit.getInstance()
        if self.shipTrait and sFit.serviceFittingOptions[
                "showShipBrowserTooltip"]:
            self.SetToolTip(wx.ToolTip(self.shipTrait))

        self.shipBrowser = self.Parent.Parent

        self.editWidth = 150
        self.padding = 4

        self.tcFitName = wx.TextCtrl(self, wx.ID_ANY, "%s fit" % self.shipName,
                                     wx.DefaultPosition, (120, -1),
                                     wx.TE_PROCESS_ENTER)
        self.tcFitName.Show(False)

        self.newBtn = self.toolbar.AddButton(self.newBmp, "New", self.newBtnCB)

        self.tcFitName.Bind(wx.EVT_TEXT_ENTER, self.createNewFit)
        self.tcFitName.Bind(wx.EVT_KILL_FOCUS, self.editLostFocus)
        self.tcFitName.Bind(wx.EVT_KEY_DOWN, self.editCheckEsc)

        self.animTimerId = wx.NewId()

        self.animTimer = wx.Timer(self, self.animTimerId)
        self.animStep = 0
        self.animPeriod = 10
        self.animDuration = 100

        self.Bind(wx.EVT_CONTEXT_MENU, self.OnShowPopup)

        self.marketInstance = Market.getInstance()
        self.baseItem = self.marketInstance.getItem(self.shipID)

        # =====================================================================
        # DISABLED - it will be added as an option in PREFERENCES

        self.animCount = 0
Exemple #34
0
 def groupIDCallback():
     group = Market.getInstance().getGroup(value)
     return "%s (%d)" % (group.name, value) if group is not None else str(value)
Exemple #35
0
    def importEftCfg(shipname, contents, callback=None):
        """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

        # If client didn't take care of encoding file contents into Unicode,
        # do it using fallback encoding ourselves
        if isinstance(contents, str):
            contents = unicode(contents, "cp1252")

        fits = []  # List for fits
        fitIndices = []  # List for starting line numbers for each fit
        lines = re.split('[\n\r]+', contents)  # Separate string into lines

        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
                f = Fit()
                # Strip square brackets and pull out a fit name
                f.name = fitLines[0][1:-1]
                # Assign ship to fitting
                try:
                    f.ship = Ship(sMkt.getItem(shipname))
                except ValueError:
                    f.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)

                    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
                                f.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
                                f.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
                            f.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
                            f.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
                        f.cargo.append(c)
                    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(f):
                                f.modules.append(m)
                        else:
                            m.owner = f
                            # Activate mod if it is activable
                            if m.isValidState(State.ACTIVE):
                                m.state = State.ACTIVE
                            # 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
                svcFit.getInstance().recalc(f)

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

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

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

        return fits
Exemple #36
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 (KeyboardInterrupt, SystemExit):
            raise
        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 (KeyboardInterrupt, SystemExit):
                        raise
                    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
    def getSubMenu(self, callingWindow, context, mainItem, selection, rootMenu,
                   i, pitem):
        self.moduleLookup = {}
        sFit = Fit.getInstance()
        sMkt = Market.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())

        def get_metalevel(x):
            return x.metaLevel or 0

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

        def get_boosterrank(x):
            # If we're returning a lot of items, sort my name
            if len(self.mainVariations) > 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

        # Do not show abyssal items
        items = list(i for i in self.mainVariations
                     if sMkt.getMetaGroupByItem(i) is None
                     or sMkt.getMetaGroupByItem(i).ID != 15)
        # Sort items by metalevel, and group within that metalevel
        # 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:
            metaGroup = sMkt.getMetaGroupByItem(item)
            if 'subSystem' in item.effects:
                thisgroup = item.marketGroup.marketGroupName
            elif metaGroup is None:
                thisgroup = 'Tech I'
            else:
                thisgroup = metaGroup.nameCn

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

            id = ContextMenuCombined.nextID()
            mitem = wx.MenuItem(rootMenu, id, item.nameCn)
            bindmenu.Bind(wx.EVT_MENU, self.handleSwitch, mitem)

            self.moduleLookup[id] = item, context
            m.Append(mitem)
            mitem.Enable(
                self.srcContext in ('projectedModule', 'projectedDrone',
                                    'projectedFighter') or fit.canFit(item))

        return m
Exemple #38
0
class CommandFits(ContextMenu):
    # Get list of items that define a command fit
    sMkt = Market.getInstance()
    grp = sMkt.getGroup(1770)  # Command burst group
    commandTypeIDs = {item.ID for item in grp.items}
    commandFits = []
    menu = None

    @classmethod
    def fitChanged(cls, evt):
        # This fires on a FitChanged event and updates the command fits whenever a command burst module is added or
        # removed from a fit. evt.typeID can be either a int or a set (in the case of multiple module deletions)
        if evt is None or (getattr(evt, 'action', None) in ("modadd", "moddel")
                           and getattr(evt, 'typeID', None)):
            if evt is not None:
                ids = getattr(evt, 'typeID')
                if not isinstance(ids, set):
                    ids = set([ids])

            if evt is None or not ids.isdisjoint(cls.commandTypeIDs):
                # we are adding or removing an item that defines a command fit. Need to refresh fit list
                cls.populateFits(evt)
        evt.Skip()

    @classmethod
    def populateFits(cls, evt):
        sFit = Fit.getInstance()
        cls.commandFits = sFit.getFitsWithModules(cls.commandTypeIDs)

    def __init__(self):
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()
        self.settings = ContextMenuSettings.getInstance()

    def display(self, srcContext, selection):
        if self.mainFrame.getActiveFit() is None or len(
                self.__class__.commandFits
        ) == 0 or srcContext != "commandView":
            return False

        return True

    def getText(self, itmContext, selection):
        return "Command Fits"

    def addFit(self, menu, fit, includeShip=False):
        label = fit.name if not includeShip else "({}) {}".format(
            fit.ship.item.name, fit.name)
        id = ContextMenu.nextID()
        self.fitMenuItemIds[id] = fit
        menuItem = wx.MenuItem(menu, id, label)
        menu.Bind(wx.EVT_MENU, self.handleSelection, menuItem)
        return menuItem

    def getSubMenu(self, context, selection, rootMenu, i, pitem):
        msw = True if "wxMSW" in wx.PlatformInfo else False
        self.context = context
        self.fitMenuItemIds = {}

        sub = wx.Menu()

        if len(self.__class__.commandFits) < 15:
            for fit in sorted(self.__class__.commandFits,
                              key=lambda x: x.name):
                menuItem = self.addFit(rootMenu if msw else sub, fit, True)
                sub.Append(menuItem)
        else:
            typeDict = {}

            for fit in self.__class__.commandFits:
                shipName = fit.ship.item.name
                if shipName not in typeDict:
                    typeDict[shipName] = []
                typeDict[shipName].append(fit)

            for ship in sorted(typeDict.keys()):
                shipItem = wx.MenuItem(sub, ContextMenu.nextID(), ship)
                grandSub = wx.Menu()
                shipItem.SetSubMenu(grandSub)

                for fit in sorted(typeDict[ship], key=lambda x: x.name):
                    fitItem = self.addFit(rootMenu if msw else grandSub, fit,
                                          False)
                    grandSub.Append(fitItem)

                sub.Append(shipItem)

        return sub

    def handleSelection(self, event):
        fit = self.fitMenuItemIds[event.Id]
        if fit is False or fit not in self.__class__.commandFits:
            event.Skip()
            return

        sFit = Fit.getInstance()
        fitID = self.mainFrame.getActiveFit()

        sFit.addCommandFit(fitID, fit)
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Exemple #39
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 in fitList:
            self.lpane.AddWidget(
                FitItem(self.lpane, ID,
                        (shipName, shipTrait, name, booster, timestamp, notes),
                        shipID))

        self.lpane.RefreshList()
        self.lpane.Thaw()
        self.raceselect.RebuildRaces(self.RACE_ORDER)
Exemple #40
0
 def toCargo(self):
     item = Market.getInstance().getItem(self.itemID)
     cargo = Cargo(item)
     cargo.amount = self.amount
     return cargo
Exemple #41
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 = "{} over {}s".format(
                    formatAmount(
                        volley * (doomsday_duration / doomsday_dottime), 3, 0,
                        6), formatAmount((doomsday_duration / 1000), 0, 0, 0))
                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))
            # TODO: fetch spoolup option
            defaultSpoolValue = 1
            spoolTime = stuff.getSpoolData(spoolOptions=SpoolOptions(
                SpoolType.SCALE, defaultSpoolValue, False))[1]
            if spoolTime:
                text = "{0}s".format(formatAmount(spoolTime, 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":
            rps = stuff.getRemoteReps(ignoreState=True)[1]
            if not rps:
                return "", None
            text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
            tooltip = "Armor repaired per second"
            return text, tooltip
        elif itemGroup == "Mutadaptive Remote Armor Repairer":
            # TODO: fetch spoolup option
            defaultSpoolValue = 1
            spoolOptDefault = SpoolOptions(SpoolType.SCALE, defaultSpoolValue,
                                           False)
            spoolOptPre = SpoolOptions(SpoolType.SCALE, 0, True)
            spoolOptFull = SpoolOptions(SpoolType.SCALE, 1, True)
            rrType, rps = stuff.getRemoteReps(spoolOptions=spoolOptDefault,
                                              ignoreState=True)
            rrTypePre, rpsPre = stuff.getRemoteReps(spoolOptions=spoolOptPre,
                                                    ignoreState=True)
            rrTypeFull, rpsFull = stuff.getRemoteReps(
                spoolOptions=spoolOptFull, ignoreState=True)
            if not rps:
                return "", None
            text = []
            tooltip = []
            text.append("{}/s".format(
                formatAmount(rps, 3, 0, 3, forceSign=True)))
            tooltip.append("Armor repaired per second")
            spoolTime = stuff.getSpoolData(spoolOptDefault)[1]
            if spoolTime:
                text.append("{}s".format(formatAmount(spoolTime, 3, 0, 3)))
                tooltip.append("spool up time")
            text = " | ".join(text)
            tooltip = " and ".join(tooltip)
            spoolTimePre = stuff.getSpoolData(spoolOptPre)[1]
            spoolTimeFull = stuff.getSpoolData(spoolOptFull)[1]
            if spoolTimePre != spoolTimeFull:
                tooltip = "{}\nSpool up: {}-{} over {}s".format(
                    tooltip, formatAmount(rpsPre, 3, 0, 3),
                    formatAmount(rpsFull, 3, 0, 3),
                    formatAmount(spoolTimeFull - spoolTimePre, 3, 0, 3))
            return text, tooltip
        elif itemGroup == "Remote Shield Booster":
            rps = stuff.getRemoteReps(ignoreState=True)[1]
            if not rps:
                return "", None
            text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
            tooltip = "Shield transferred per second"
            return text, tooltip
        elif itemGroup == "Remote Capacitor Transmitter":
            rps = stuff.getRemoteReps(ignoreState=True)[1]
            if not rps:
                return "", None
            text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
            tooltip = "Energy transferred per second"
            return text, tooltip
        elif itemGroup == "Remote Hull Repairer":
            rps = stuff.getRemoteReps(ignoreState=True)[1]
            if not rps:
                return "", None
            text = "{0}/s".format(formatAmount(rps, 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":
            repType, rps = stuff.getRemoteReps(ignoreState=True)
            if not repType:
                return "", None
            text = "{}/s".format(formatAmount(rps, 3, 0, 3))
            tooltip = "{} HP repaired per second\n{} HP/s per drone".format(
                repType, formatAmount(rps / stuff.amount, 3, 0, 3))
            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
Exemple #42
0
 def addModule(self, x, y, itemID):
     """Add a module from the market browser (from dragging it)"""
     fitID = self.mainFrame.getActiveFit()
     item = Market.getInstance().getItem(itemID)
     fit = Fit.getInstance().getFit(fitID)
     dstRow, _ = self.HitTest((x, y))
     if dstRow == -1 or dstRow in self.blanks:
         dstMod = None
     else:
         try:
             dstMod = self.mods[dstRow]
         except IndexError:
             dstMod = None
         if not isinstance(dstMod, Module):
             dstMod = None
         if dstMod not in fit.modules:
             dstMod = None
     dstPos = fit.modules.index(dstMod) if dstMod is not None else None
     mstate = wx.GetMouseState()
     # If we dropping on a module, try to replace, or add if replacement fails
     if item.isModule and dstMod is not None and not dstMod.isEmpty:
         positions = getSimilarModPositions(
             fit.modules,
             dstMod) if mstate.GetModifiers() == wx.MOD_ALT else [dstPos]
         command = cmd.GuiReplaceLocalModuleCommand(fitID=fitID,
                                                    itemID=itemID,
                                                    positions=positions)
         if not self.mainFrame.command.Submit(command):
             if mstate.GetModifiers() == wx.MOD_ALT:
                 self.mainFrame.command.Submit(
                     cmd.GuiFillWithNewLocalModulesCommand(fitID=fitID,
                                                           itemID=itemID))
             else:
                 self.mainFrame.command.Submit(
                     cmd.GuiAddLocalModuleCommand(fitID=fitID,
                                                  itemID=itemID))
     elif item.isModule:
         if mstate.GetModifiers() == wx.MOD_ALT:
             self.mainFrame.command.Submit(
                 cmd.GuiFillWithNewLocalModulesCommand(fitID=fitID,
                                                       itemID=itemID))
         elif dstPos is not None:
             self.mainFrame.command.Submit(
                 cmd.GuiReplaceLocalModuleCommand(fitID=fitID,
                                                  itemID=itemID,
                                                  positions=[dstPos]))
         else:
             self.mainFrame.command.Submit(
                 cmd.GuiAddLocalModuleCommand(fitID=fitID, itemID=itemID))
     elif item.isSubsystem:
         self.mainFrame.command.Submit(
             cmd.GuiAddLocalModuleCommand(fitID=fitID, itemID=itemID))
     elif item.isCharge:
         failoverToAll = False
         positionsAll = list(range(len(fit.modules)))
         if dstMod is None or dstMod.isEmpty:
             positions = positionsAll
         elif mstate.GetModifiers() == wx.MOD_ALT:
             positions = getSimilarModPositions(fit.modules, dstMod)
             failoverToAll = True
         else:
             positions = [fit.modules.index(dstMod)]
         if len(positions) > 0:
             command = cmd.GuiChangeLocalModuleChargesCommand(
                 fitID=fitID, positions=positions, chargeItemID=itemID)
             if not self.mainFrame.command.Submit(
                     command) and failoverToAll:
                 self.mainFrame.command.Submit(
                     cmd.GuiChangeLocalModuleChargesCommand(
                         fitID=fitID,
                         positions=positionsAll,
                         chargeItemID=itemID))
Exemple #43
0
def droneStackLimit(fit, itemIdentity):
    item = Market.getInstance().getItem(itemIdentity)
    hardLimit = max(5, fit.extraAttributes["maxActiveDrones"])
    releaseLimit = fit.getReleaseLimitForDrone(item)
    limit = min(hardLimit, releaseLimit if releaseLimit > 0 else math.inf)
    return limit
Exemple #44
0
 def updateItems(self, updateDisplay=False):
     sMkt = Market.getInstance()
     self.things = sMkt.getItemsWithOverrides()
     self.items = self.things
     if updateDisplay:
         self.update(self.things)
Exemple #45
0
 def clearSearch(self, event=None):
     if event:
         self.searchBox.Clear()
     self.update(Market.getInstance().getItemsWithOverrides())
Exemple #46
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 '─ Tactical Mode ─'
                else:
                    return '─ {} {} Slot{}─'.format(
                        stuff.num,
                        Slot.getName(stuff.slot).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" % 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 = chr(marketShortcut + 8320) + " "
                    del item.marketShortcut
                    return shortcut + item.name

            return item.name
Exemple #47
0
    def __init__(self, parent):
        wx.Panel.__init__(self,
                          parent,
                          id=wx.ID_ANY,
                          pos=wx.DefaultPosition,
                          size=wx.DefaultSize,
                          style=wx.TAB_TRAVERSAL)
        self.SetBackgroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))

        pmainSizer = wx.BoxSizer(wx.HORIZONTAL)

        availableSizer = wx.BoxSizer(wx.VERTICAL)

        self.searchBox = SearchBox(self)
        self.itemView = ItemView(self)

        self.itemView.Hide()

        availableSizer.Add(self.searchBox, 0, wx.EXPAND)
        availableSizer.Add(self.itemView, 1, wx.EXPAND)

        self.availableImplantsTree = wx.TreeCtrl(self,
                                                 wx.ID_ANY,
                                                 style=wx.TR_DEFAULT_STYLE
                                                 | wx.TR_HIDE_ROOT)
        root = self.availableRoot = self.availableImplantsTree.AddRoot(
            "Available")
        self.availableImplantsImageList = wx.ImageList(16, 16)
        self.availableImplantsTree.SetImageList(
            self.availableImplantsImageList)

        availableSizer.Add(self.availableImplantsTree, 1, wx.EXPAND)

        pmainSizer.Add(availableSizer, 1, wx.ALL | wx.EXPAND, 5)

        buttonSizer = wx.BoxSizer(wx.VERTICAL)
        buttonSizer.AddStretchSpacer()

        self.btnAdd = GenBitmapButton(self,
                                      wx.ID_ADD,
                                      BitmapLoader.getBitmap(
                                          "fit_add_small", "gui"),
                                      style=wx.BORDER_NONE)
        buttonSizer.Add(self.btnAdd, 0)

        self.btnRemove = GenBitmapButton(self,
                                         wx.ID_REMOVE,
                                         BitmapLoader.getBitmap(
                                             "fit_delete_small", "gui"),
                                         style=wx.BORDER_NONE)
        buttonSizer.Add(self.btnRemove, 0)

        buttonSizer.AddStretchSpacer()
        pmainSizer.Add(buttonSizer, 0, wx.EXPAND, 0)

        characterImplantSizer = wx.BoxSizer(wx.VERTICAL)
        self.pluggedImplantsTree = AvailableImplantsView(self)
        characterImplantSizer.Add(self.pluggedImplantsTree, 1,
                                  wx.ALL | wx.EXPAND, 5)
        pmainSizer.Add(characterImplantSizer, 1, wx.EXPAND, 5)

        self.SetSizer(pmainSizer)

        self.hoveredLeftTreeTypeID = None
        self.hoveredRightListRow = None

        # Populate the market tree
        sMkt = Market.getInstance()
        for mktGrp in sMkt.getImplantTree():
            iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(mktGrp))
            childId = self.availableImplantsTree.AppendItem(root,
                                                            mktGrp.name,
                                                            iconId,
                                                            data=mktGrp.ID)
            if sMkt.marketGroupHasTypesCheck(mktGrp) is False:
                self.availableImplantsTree.AppendItem(childId, "dummy")

        self.availableImplantsTree.SortChildren(self.availableRoot)

        # Bind the event to replace dummies by real data
        self.availableImplantsTree.Bind(wx.EVT_TREE_ITEM_EXPANDING,
                                        self.expandLookup)
        self.availableImplantsTree.Bind(wx.EVT_TREE_ITEM_ACTIVATED,
                                        self.itemSelected)
        self.availableImplantsTree.Bind(wx.EVT_MOTION,
                                        self.OnLeftTreeMouseMove)
        self.availableImplantsTree.Bind(wx.EVT_LEAVE_WINDOW,
                                        self.OnLeftTreeMouseLeave)

        self.itemView.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemSelected)

        self.pluggedImplantsTree.Bind(wx.EVT_MOTION, self.OnRightListMouseMove)

        # Bind add & remove buttons
        self.btnAdd.Bind(wx.EVT_BUTTON, self.itemSelected)
        self.btnRemove.Bind(wx.EVT_BUTTON, self.removeItem)

        # We update with an empty list first to set the initial size for Layout(), then update later with actual
        # implants for character. This helps with sizing issues.
        self.pluggedImplantsTree.update([])
        self.bindContext()
        self.Layout()

        self.update()
Exemple #48
0
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 (KeyboardInterrupt, SystemExit):
        raise
    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 (KeyboardInterrupt, SystemExit):
                            raise
                        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 (KeyboardInterrupt, SystemExit):
                            raise
                        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 (KeyboardInterrupt, SystemExit):
                            raise
                        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 (KeyboardInterrupt, SystemExit):
                        raise
                    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 (KeyboardInterrupt, SystemExit):
                        raise
                    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 (KeyboardInterrupt, SystemExit):
                                raise
                            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))

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

    return fits
Exemple #49
0
    def importXml(text, callback=None, encoding="utf-8"):
        sMkt = Market.getInstance()

        doc = xml.dom.minidom.parseString(text.encode(encoding))
        fittings = doc.getElementsByTagName("fittings").item(0)
        fittings = fittings.getElementsByTagName("fitting")
        fits = []

        for i, fitting in enumerate(fittings):
            f = Fit()
            f.name = fitting.getAttribute("name")
            # <localized hint="Maelstrom">Maelstrom</localized>
            shipType = fitting.getElementsByTagName("shipType").item(
                0).getAttribute("value")
            try:
                try:
                    f.ship = Ship(sMkt.getItem(shipType))
                except ValueError:
                    f.ship = Citadel(sMkt.getItem(shipType))
            except Exception as e:
                pyfalog.warning("Caught exception on importXml")
                pyfalog.error(e)
                continue
            hardwares = fitting.getElementsByTagName("hardware")
            moduleList = []
            for hardware in hardwares:
                try:
                    moduleName = hardware.getAttribute("type")
                    try:
                        item = sMkt.getItem(moduleName, eager="group.category")
                    except Exception as e:
                        pyfalog.warning("Caught exception on importXml")
                        pyfalog.error(e)
                        continue
                    if item:
                        if item.category.name == "Drone":
                            d = Drone(item)
                            d.amount = int(hardware.getAttribute("qty"))
                            f.drones.append(d)
                        elif item.category.name == "Fighter":
                            ft = Fighter(item)
                            ft.amount = int(
                                hardware.getAttribute("qty")
                            ) if ft.amount <= ft.fighterSquadronMaxSize else ft.fighterSquadronMaxSize
                            f.fighters.append(ft)
                        elif hardware.getAttribute("slot").lower() == "cargo":
                            # although the eve client only support charges in cargo, third-party programs
                            # may support items or "refits" in cargo. Support these by blindly adding all
                            # cargo, not just charges
                            c = Cargo(item)
                            c.amount = int(hardware.getAttribute("qty"))
                            f.cargo.append(c)
                        else:
                            try:
                                m = Module(item)
                            # When item can't be added to any slot (unknown item or just charge), ignore it
                            except ValueError:
                                pyfalog.warning(
                                    "item can't be added to any slot (unknown item or just charge), ignore it"
                                )
                                continue
                            # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                            if item.category.name == "Subsystem":
                                if m.fits(f):
                                    m.owner = f
                                    f.modules.append(m)
                            else:
                                if m.isValidState(State.ACTIVE):
                                    m.state = State.ACTIVE

                                moduleList.append(m)

                except KeyboardInterrupt:
                    pyfalog.warning("Keyboard Interrupt")
                    continue

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

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

            fits.append(f)
            if callback:
                wx.CallAfter(callback, None)

        return fits
Exemple #50
0
    def droneKey(self, drone):
        sMkt = Market.getInstance()

        groupName = sMkt.getMarketGroupByItem(drone.item).name

        return (self.DRONE_ORDER.index(groupName), drone.item.name)
Exemple #51
0
 def itemIDCallback():
     item = Market.getInstance().getItem(value)
     return "%s (%d)" % (item.name, value) if item is not None else str(value)
    def __init__(self,
                 victim,
                 fullContext=None,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 maximized=False):

        wx.Dialog.__init__(self,
                           gui.mainFrame.MainFrame.getInstance(),
                           wx.ID_ANY,
                           title="Item stats",
                           pos=pos,
                           size=size,
                           style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX
                           | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
                           | wx.SYSTEM_MENU)

        empty = getattr(victim, "isEmpty", False)

        if empty:
            self.Hide()
            self.Destroy()
            return

        srcContext = fullContext[0]
        try:
            itmContext = fullContext[1]
        except IndexError:
            itmContext = None
        item = getattr(victim, "item", None) if srcContext.lower() not in (
            "projectedcharge",
            "fittingcharge") else getattr(victim, "charge", None)
        if item is None:
            sMkt = Market.getInstance()
            item = sMkt.getItem(victim.ID)
            victim = None
        self.context = itmContext
        if item.iconID is not None:
            itemImg = BitmapLoader.getBitmap(item.iconID, "icons")
            if itemImg is not None:
                self.SetIcon(wx.Icon(itemImg))
        self.SetTitle(
            "%s: %s%s" %
            ("%s Stats" % itmContext if itmContext is not None else "Stats",
             item.name, " (%d)" % item.ID if config.debug else ""))

        self.SetMinSize((300, 200))
        if "wxGTK" in wx.PlatformInfo:  # GTK has huge tab widgets, give it a bit more room
            self.SetSize((640, 620))
        else:
            self.SetSize((550, 500))
        # self.SetMaxSize((500, -1))
        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.container = ItemStatsContainer(self, victim, item, itmContext)
        self.mainSizer.Add(self.container, 1, wx.EXPAND)

        if "wxGTK" in wx.PlatformInfo:
            self.closeBtn = wx.Button(self, wx.ID_ANY, "Close",
                                      wx.DefaultPosition, wx.DefaultSize, 0)
            self.mainSizer.Add(self.closeBtn, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
            self.closeBtn.Bind(wx.EVT_BUTTON, (lambda e: self.Close()))

        self.SetSizer(self.mainSizer)

        self.parentWnd = gui.mainFrame.MainFrame.getInstance()

        dlgsize = self.GetSize()
        psize = self.parentWnd.GetSize()
        ppos = self.parentWnd.GetPosition()

        ItemStatsDialog.counter += 1
        self.dlgOrder = ItemStatsDialog.counter

        counter = ItemStatsDialog.counter
        dlgStep = 30
        if counter * dlgStep > ppos.x + psize.width - dlgsize.x or counter * dlgStep > ppos.y + psize.height - dlgsize.y:
            ItemStatsDialog.counter = 1

        dlgx = ppos.x + counter * dlgStep
        dlgy = ppos.y + counter * dlgStep
        if pos == wx.DefaultPosition:
            self.SetPosition((dlgx, dlgy))
        else:
            self.SetPosition(pos)
        if maximized:
            self.Maximize(True)
        else:
            if size != wx.DefaultSize:
                self.SetSize(size)
        self.parentWnd.RegisterStatsWindow(self)

        self.Show()

        self.Bind(wx.EVT_CLOSE, self.closeEvent)
        self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
Exemple #53
0
def importKillmail(
        killmail,
        fitNameFunction=lambda killmail, fit: fit.ship.item.name
) -> Fit or None:
    """Parses a single killmail from the ESI API. The argument is an already parsed JSON"""
    sMkt = Market.getInstance()
    fit = Fit()
    victim = killmail["victim"]
    items = victim["items"]

    try:
        ship = victim["ship_type_id"]
        try:
            fit.ship = Ship(sMkt.getItem(ship))
        except ValueError:
            fit.ship = Citadel(sMkt.getItem(ship))
    except:
        pyfalog.warning("Caught exception in importZKillboard")
        return None

    fit.name = fitNameFunction(killmail, fit)

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

    moduleList = []
    moduleByFlag = {}
    chargeByFlag = {}
    for module in items:
        try:
            item = sMkt.getItem(module["item_type_id"], eager="group.category")
            if not item.published:
                continue
            flag = module["flag"]
            if flag == INV_FLAG_DRONEBAY:
                d = Drone(item)
                d.amount = module.get("quantity_destroyed", 0) + module.get(
                    "quantity_dropped", 0)
                fit.drones.append(d)
            elif flag == INV_FLAG_CARGOBAY:
                c = fit.cargo.findFirst(item)
                if c is None:
                    c = Cargo(item)
                    fit.cargo.append(c)
                c.amount += module.get("quantity_destroyed", 0) + module.get(
                    "quantity_dropped", 0)

            elif flag == INV_FLAG_FIGHTER:
                fighter = Fighter(item)
                fit.fighters.append(fighter)
            else:
                try:
                    m = Module(item)
                    moduleByFlag[flag] = m
                # When item can't be added to any slot (unknown item or just charge), ignore it
                except ValueError:
                    chargeByFlag[flag] = item
                    pyfalog.debug(
                        "Item can't be added to any slot (unknown item or just charge)"
                    )
                    continue
                # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                if item.category.name == "Subsystem":
                    if m.fits(fit):
                        fit.modules.append(m)
                else:
                    if m.isValidState(State.ACTIVE):
                        m.state = State.ACTIVE

                    moduleList.append(m)

        except:
            pyfalog.warning("Could not process module.")
            continue

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

    for flag in moduleByFlag.keys():
        module = moduleByFlag[flag]
        charge = chargeByFlag.get(flag, None)
        if (not charge is None
            ) and module.isValidCharge(charge) and module.charge is None:
            module.charge = charge

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

    km_time = datetime.strptime(killmail["killmail_time"],
                                "%Y-%m-%dT%H:%M:%SZ")
    fit.timestamp = time.mktime(km_time.timetuple())
    fit.modified = fit.created = km_time

    return saveImportedFit(fit)
Exemple #54
0
 def itemSort(self, item):
     sMkt = Market.getInstance()
     isFittable = item.group.name in sMkt.FIT_GROUPS or item.category.name in sMkt.FIT_CATEGORIES
     return (not isFittable, *sMkt.itemSort(item))
Exemple #55
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.amount, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
        elif isinstance(stuff, Cargo):
            if stuff.item.group.name in ("Cargo Container", "Secure Cargo Container", "Audit Log Secure Container", "Freight Container"):
                capacity = stuff.item.getAttribute('capacity')
                if capacity:
                    return "{:d}x {} ({} m\u00B3)".format(stuff.amount, stuff.item.name, formatAmount(capacity, 3, 0, 6))
            return "{:d}x {}".format(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
Exemple #56
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))

            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))
            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()
Exemple #57
0
    def __init__(self,
                 victim,
                 fullContext=None,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 maximized=False):
        super().__init__(parent=gui.mainFrame.MainFrame.getInstance(),
                         id=wx.ID_ANY,
                         title=_t("Item stats"),
                         pos=pos,
                         size=size,
                         resizeable=True)

        empty = getattr(victim, "isEmpty", False)

        if empty:
            self.Close()
            return

        srcContext = fullContext[0]
        try:
            itmContext = fullContext[1]
        except IndexError:
            itmContext = None
        item = getattr(victim, "item", None) if srcContext.lower() not in (
            "projectedcharge",
            "fittingcharge") else getattr(victim, "charge", None)
        if item is None:
            sMkt = Market.getInstance()
            item = sMkt.getItem(victim.ID)
            victim = None
        self.context = itmContext
        if item.iconID is not None:
            itemImg = BitmapLoader.getBitmap(item.iconID, "icons")
            if itemImg is not None:
                self.SetIcon(wx.Icon(itemImg))
        self.SetTitle(
            _t("{context}Stats: {name}{debug_info}").format(
                context="{} ".format(itmContext)
                if itmContext is not None else "",
                name=item.name,
                debug_info=" ({item_id})".format(
                    item_id=item.ID) if config.debug else ""))

        self.SetMinSize((300, 200))
        # GTK has huge tab widgets, give it a bit more room
        if "wxGTK" in wx.PlatformInfo:
            self.SetSize((640, 600))
        else:
            self.SetSize((550, 500))
        # self.SetMaxSize((500, -1))
        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.container = ItemStatsContainer(self, victim, item, itmContext)
        self.mainSizer.Add(self.container, 1, wx.EXPAND)

        self.SetSizer(self.mainSizer)

        self.parentWnd = gui.mainFrame.MainFrame.getInstance()

        dlgsize = self.GetSize()
        psize = self.parentWnd.GetSize()
        ppos = self.parentWnd.GetPosition()

        ItemStatsFrame.counter += 1
        self.dlgOrder = ItemStatsFrame.counter

        counter = ItemStatsFrame.counter
        dlgStep = 30
        if counter * dlgStep > ppos.x + psize.width - dlgsize.x or counter * dlgStep > ppos.y + psize.height - dlgsize.y:
            ItemStatsFrame.counter = 1

        dlgx = ppos.x + counter * dlgStep
        dlgy = ppos.y + counter * dlgStep
        if pos == wx.DefaultPosition:
            self.SetPosition((dlgx, dlgy))
        else:
            self.SetPosition(pos)
        if maximized:
            self.Maximize(True)
        else:
            if size != wx.DefaultSize:
                self.SetSize(size)
        self.parentWnd.RegisterStatsWindow(self)

        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent)
        self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
Exemple #58
0
    def getPriceNow(self, objitem):
        """Get price for provided typeID"""
        sMkt = Market.getInstance()
        item = sMkt.getItem(objitem)

        return item.price.price
Exemple #59
0
    def getTestSet(setType):
        def getT2ItemsWhere(additionalFilter,
                            mustBeOffensive=False,
                            category="Module"):
            # Used to obtain a smaller subset of items while still containing examples of each group.
            T2_META_LEVEL = 5
            metaLevelAttrID = getAttributeInfo("metaLevel").attributeID
            categoryID = getCategory(category).categoryID
            result = gamedata_session.query(Item).join(ItemEffect, Group, Attribute).\
                      filter(
                          additionalFilter,
                          Attribute.attributeID == metaLevelAttrID,
                          Attribute.value == T2_META_LEVEL,
                          Group.categoryID == categoryID,
                      ).all()
            if mustBeOffensive:
                result = filter(lambda t: t.offensive is True, result)
            return list(result)

        def getChargeType(item, setType):
            if setType == "turret":
                return str(item.attributes["chargeGroup1"].value) + "-" + str(
                    item.attributes["chargeSize"].value)
            return str(item.attributes["chargeGroup1"].value)

        if setType in EfsPort.wepTestSet.keys():
            return EfsPort.wepTestSet[setType]
        else:
            EfsPort.wepTestSet[setType] = []
        modSet = EfsPort.wepTestSet[setType]

        if setType == "drone":
            ilist = getT2ItemsWhere(True, True, "Drone")
            for item in ilist:
                drone = Drone(item)
                drone.amount = 1
                drone.amountActive = 1
                drone.itemModifiedAttributes.parent = drone
                modSet.append(drone)
            return modSet

        turretFittedEffectID = gamedata_session.query(Effect).filter(
            Effect.name == "turretFitted").first().effectID
        launcherFittedEffectID = gamedata_session.query(Effect).filter(
            Effect.name == "launcherFitted").first().effectID
        if setType == "launcher":
            effectFilter = ItemEffect.effectID == launcherFittedEffectID
            reqOff = False
        else:
            effectFilter = ItemEffect.effectID == turretFittedEffectID
            reqOff = True
        ilist = getT2ItemsWhere(effectFilter, reqOff)
        previousChargeTypes = []
        # Get modules from item list
        for item in ilist:
            chargeType = getChargeType(item, setType)
            # Only add turrets if we don"t already have one with the same size and ammo type.
            if setType == "launcher" or chargeType not in previousChargeTypes:
                previousChargeTypes.append(chargeType)
                mod = Module(item)
                modSet.append(mod)

        sMkt = Market.getInstance()
        # Due to typed missile damage bonuses we"ll need to add extra launchers to cover all four types.
        additionalLaunchers = []
        for mod in modSet:
            clist = list(
                gamedata_session.query(Item).options().filter(
                    Item.groupID == mod.getModifiedItemAttr(
                        "chargeGroup1")).all())
            mods = [mod]
            charges = [clist[0]]
            if setType == "launcher":
                # We don"t want variations of missiles we already have
                prevCharges = list(sMkt.getVariationsByItems(charges))
                testCharges = []
                for charge in clist:
                    if charge not in prevCharges:
                        testCharges.append(charge)
                        prevCharges += sMkt.getVariationsByItems([charge])
                for c in testCharges:
                    charges.append(c)
                    additionalLauncher = Module(mod.item)
                    mods.append(additionalLauncher)
            for i in range(len(mods)):
                mods[i].charge = charges[i]
                mods[i].reloadForce = True
                mods[i].state = 2
                if setType == "launcher" and i > 0:
                    additionalLaunchers.append(mods[i])
        modSet += additionalLaunchers
        return modSet
Exemple #60
0
def importESI(str_):

    sMkt = Market.getInstance()
    fitobj = Fit()
    refobj = json.loads(str_)
    items = refobj['items']
    # "<" and ">" is replace to "&lt;", "&gt;" by EVE client
    fitobj.name = refobj['name']
    # 2017/03/29: read description
    fitobj.notes = refobj['description']

    try:
        ship = refobj['ship_type_id']
        try:
            fitobj.ship = Ship(sMkt.getItem(ship))
        except ValueError:
            fitobj.ship = Citadel(sMkt.getItem(ship))
    except:
        pyfalog.warning("Caught exception in importESI")
        return None

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

    moduleList = []
    for module in items:
        try:
            item = sMkt.getItem(module['type_id'], eager="group.category")
            if not item.published:
                continue
            if module['flag'] == INV_FLAG_DRONEBAY:
                d = Drone(item)
                d.amount = module['quantity']
                fitobj.drones.append(d)
            elif module['flag'] == INV_FLAG_CARGOBAY:
                c = Cargo(item)
                c.amount = module['quantity']
                fitobj.cargo.append(c)
            elif module['flag'] == INV_FLAG_FIGHTER:
                fighter = Fighter(item)
                fitobj.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:
                    pyfalog.debug(
                        "Item can't be added to any slot (unknown item or just charge)"
                    )
                    continue
                # Add subsystems before modules to make sure T3 cruisers have subsystems installed
                if item.category.name == "Subsystem":
                    if m.fits(fitobj):
                        fitobj.modules.append(m)
                else:
                    if m.isValidState(State.ACTIVE):
                        m.state = State.ACTIVE

                    moduleList.append(m)

        except:
            pyfalog.warning("Could not process module.")
            continue

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

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

    return fitobj