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()
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
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)
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)
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
def droneKey(self, drone): sMkt = Market.getInstance() groupName = sMkt.getMarketGroupByItem(drone.item).name return (self.DRONE_ORDER.index(groupName), drone.item.name)
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
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)
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)
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
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
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)
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
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
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
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
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
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
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
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)
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, ()
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)
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)
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
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()
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
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()
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"])
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)
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))
def updateItems(self, updateDisplay=False): if updateDisplay: self.update(Market.getInstance().getItemsWithOverrides())
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
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
def groupIDCallback(): group = Market.getInstance().getGroup(value) return "%s (%d)" % (group.name, value) if group is not None else str(value)
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
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
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))
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)
def toCargo(self): item = Market.getInstance().getItem(self.itemID) cargo = Cargo(item) cargo.amount = self.amount return cargo
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
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))
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
def updateItems(self, updateDisplay=False): sMkt = Market.getInstance() self.things = sMkt.getItemsWithOverrides() self.items = self.things if updateDisplay: self.update(self.things)
def clearSearch(self, event=None): if event: self.searchBox.Clear() self.update(Market.getInstance().getItemsWithOverrides())
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
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()
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
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
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)
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)
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))
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
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()
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)
def getPriceNow(self, objitem): """Get price for provided typeID""" sMkt = Market.getInstance() item = sMkt.getItem(objitem) return item.price.price
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
def importESI(str_): sMkt = Market.getInstance() fitobj = Fit() refobj = json.loads(str_) items = refobj['items'] # "<" and ">" is replace to "<", ">" 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