diff --git a/eos/db/gamedata/queries.py b/eos/db/gamedata/queries.py index c49267050..5f6cca32e 100644 --- a/eos/db/gamedata/queries.py +++ b/eos/db/gamedata/queries.py @@ -23,6 +23,7 @@ from sqlalchemy.sql import and_, or_, select import eos.config from eos.db import gamedata_session from eos.db.gamedata.metaGroup import metatypes_table, items_table +from eos.db.gamedata.group import groups_table from eos.db.util import processEager, processWhere from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData @@ -249,7 +250,7 @@ def searchItems(nameLike, where=None, join=None, eager=None): @cachedQuery(2, "where", "itemids") -def getVariations(itemids, where=None, eager=None): +def getVariations(itemids, groupIDs=None, where=None, eager=None): for itemid in itemids: if not isinstance(itemid, int): raise TypeError("All passed item IDs must be integers") @@ -262,7 +263,18 @@ def getVariations(itemids, where=None, eager=None): joinon = items_table.c.typeID == metatypes_table.c.typeID vars = gamedata_session.query(Item).options(*processEager(eager)).join((metatypes_table, joinon)).filter( filter).all() - return vars + + if vars: + return vars + elif groupIDs: + itemfilter = or_(*(groups_table.c.groupID == groupID for groupID in groupIDs)) + filter = processWhere(itemfilter, where) + joinon = items_table.c.groupID == groups_table.c.groupID + vars = gamedata_session.query(Item).options(*processEager(eager)).join((groups_table, joinon)).filter( + filter).all() + + return vars + @cachedQuery(1, "attr") diff --git a/gui/builtinContextMenus/__init__.py b/gui/builtinContextMenus/__init__.py index c6a41c112..bb8631623 100644 --- a/gui/builtinContextMenus/__init__.py +++ b/gui/builtinContextMenus/__init__.py @@ -22,4 +22,6 @@ __all__ = [ "metaSwap", "implantSets", "fighterAbilities", + "cargoAmmo", + "droneStack" ] diff --git a/gui/builtinContextMenus/cargoAmmo.py b/gui/builtinContextMenus/cargoAmmo.py new file mode 100644 index 000000000..6b1233164 --- /dev/null +++ b/gui/builtinContextMenus/cargoAmmo.py @@ -0,0 +1,34 @@ +from gui.contextMenu import ContextMenu +import gui.mainFrame +import service +import gui.globalEvents as GE +import wx + + +class CargoAmmo(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + def display(self, srcContext, selection): + if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None: + return False + + for selected_item in selection: + if selected_item.category.ID in ( + 8, # Charge + ): + return True + + def getText(self, itmContext, selection): + return "Add {0} to Cargo (x1000)".format(itmContext) + + def activate(self, fullContext, selection, i): + sFit = service.Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + + typeID = int(selection[0].ID) + sFit.addCargo(fitID, typeID, 1000) + self.mainFrame.additionsPane.select("Cargo") + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + +CargoAmmo.register() diff --git a/gui/builtinContextMenus/droneStack.py b/gui/builtinContextMenus/droneStack.py new file mode 100644 index 000000000..687f94906 --- /dev/null +++ b/gui/builtinContextMenus/droneStack.py @@ -0,0 +1,36 @@ +from gui.contextMenu import ContextMenu +import gui.mainFrame +import service +import gui.globalEvents as GE +import wx + + +class CargoAmmo(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + def display(self, srcContext, selection): + if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None: + return False + + for selected_item in selection: + if selected_item.category.ID in ( + 18, # Drones + ): + return True + + return False + + def getText(self, itmContext, selection): + return "Add {0} to Drone Bay (x5)".format(itmContext) + + def activate(self, fullContext, selection, i): + sFit = service.Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + + typeID = int(selection[0].ID) + sFit.addDrone(fitID, typeID, 5) + self.mainFrame.additionsPane.select("Drones") + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + +CargoAmmo.register() diff --git a/gui/builtinContextMenus/metaSwap.py b/gui/builtinContextMenus/metaSwap.py index 389335f53..c9fe12be6 100644 --- a/gui/builtinContextMenus/metaSwap.py +++ b/gui/builtinContextMenus/metaSwap.py @@ -16,7 +16,13 @@ class MetaSwap(ContextMenu): def display(self, srcContext, selection): - if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule",): + if self.mainFrame.getActiveFit() is None or srcContext not in ( + "fittingModule", + "droneItem", + "fighterItem", + "boosterItem", + "implantItem", + ): return False # Check if list of variations is same for all of selection @@ -52,6 +58,17 @@ class MetaSwap(ContextMenu): def get_metagroup(x): return x.metaGroup.ID if x.metaGroup is not None else 0 + def get_boosterrank(x): + # If we're returning a lot of items, sort my name + if len(self.variations) > 7: + return x.name + # Sort by booster chance to get some sort of pseudorank. + elif 'boosterEffectChance1' in x.attributes: + return x.attributes['boosterEffectChance1'].value + # the "first" rank (Synth) doesn't have boosterEffectChance1. If we're not pulling back all boosters, return 0 for proper sorting + else: + return 0 + m = wx.Menu() # If on Windows we need to bind out events into the root menu, on other @@ -63,8 +80,17 @@ class MetaSwap(ContextMenu): # Sort items by metalevel, and group within that metalevel items = list(self.variations) - items.sort(key=get_metalevel) - items.sort(key=get_metagroup) + print context + if "implantItem" in context: + # sort implants based on name + items.sort(key=lambda x: x.name) + elif "boosterItem" in context: + # boosters don't have meta or anything concrete that we can rank by. Go by chance to inflict side effect + 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: @@ -74,7 +100,7 @@ class MetaSwap(ContextMenu): else: thisgroup = item.metaGroup.name - if thisgroup != group: + if thisgroup != group and context not in ("implantItem", "boosterItem"): group = thisgroup id = ContextMenu.nextID() m.Append(id, u'─ %s ─' % group) @@ -97,9 +123,58 @@ class MetaSwap(ContextMenu): fitID = self.mainFrame.getActiveFit() fit = sFit.getFit(fitID) - for mod in self.selection: - pos = fit.modules.index(mod) - sFit.changeModule(fitID, pos, item.ID) + for selected_item in self.selection: + if type(selected_item).__name__== 'Module': + pos = fit.modules.index(selected_item) + sFit.changeModule(fitID, pos, item.ID) + + elif type(selected_item).__name__== 'Drone': + drone_count = None + drone_index = None + + for idx, drone_stack in enumerate(fit.drones): + if drone_stack is selected_item: + drone_count = drone_stack.amount + sFit.removeDrone(fitID, idx, drone_count) + break + + if drone_count: + sFit.addDrone(fitID, item.ID, drone_count) + + elif type(selected_item).__name__== 'Fighter': + fighter_count = None + fighter_index = None + + for idx, fighter_stack in enumerate(fit.fighters): + # Right now fighters always will have max stack size. + # Including this for future improvement, so if adjustable + # fighter stacks get added we're ready for it. + if fighter_stack is selected_item: + if fighter_stack.amount > 0: + fighter_count = fighter_stack.amount + elif fighter_stack.amount == -1: + fighter_count = fighter_stack.amountActive + else: + fighter_count.amount = 0 + + sFit.removeFighter(fitID, idx) + break + + sFit.addFighter(fitID, item.ID) + + elif type(selected_item).__name__== 'Booster': + for idx, booster_stack in enumerate(fit.boosters): + if booster_stack is selected_item: + sFit.removeBooster(fitID, idx) + sFit.addBooster(fitID, item.ID) + break + + elif type(selected_item).__name__== 'Implant': + for idx, implant_stack in enumerate(fit.implants): + if implant_stack is selected_item: + sFit.removeImplant(fitID, idx) + sFit.addImplant(fitID, item.ID, False) + break wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) diff --git a/service/fit.py b/service/fit.py index 9dd1dff32..9eeb348fe 100644 --- a/service/fit.py +++ b/service/fit.py @@ -688,7 +688,7 @@ class Fit(object): self.recalc(fit) return True - def addDrone(self, fitID, itemID): + def addDrone(self, fitID, itemID, numDronesToAdd=1): if fitID is None: return False @@ -707,7 +707,7 @@ class Fit(object): fit.drones.append(drone) else: return False - drone.amount += 1 + drone.amount += numDronesToAdd eos.db.commit() self.recalc(fit) return True diff --git a/service/market.py b/service/market.py index 17518363c..925cbf9b4 100644 --- a/service/market.py +++ b/service/market.py @@ -590,7 +590,40 @@ class Market(object): parents = set() # Set-container for variables variations = set() + variations_limiter = set() for item in items: + if item.category.ID == 20: # Implants and Boosters + implant_remove_list = set() + implant_remove_list.add("Low-Grade ") + implant_remove_list.add("Low-grade ") + implant_remove_list.add("Mid-Grade ") + implant_remove_list.add("Mid-grade ") + implant_remove_list.add("High-Grade ") + implant_remove_list.add("High-grade ") + implant_remove_list.add("Limited ") + implant_remove_list.add(" - Advanced") + implant_remove_list.add(" - Basic") + implant_remove_list.add(" - Elite") + implant_remove_list.add(" - Improved") + implant_remove_list.add(" - Standard") + implant_remove_list.add("Copper ") + implant_remove_list.add("Gold ") + implant_remove_list.add("Silver ") + implant_remove_list.add("Advanced ") + implant_remove_list.add("Improved ") + implant_remove_list.add("Prototype ") + implant_remove_list.add("Standard ") + implant_remove_list.add("Strong ") + implant_remove_list.add("Synth ") + + for implant_prefix in ("-6","-7","-8","-9","-10"): + for i in range(50): + implant_remove_list.add(implant_prefix + str("%02d" % i)) + + for text_to_remove in implant_remove_list: + if text_to_remove in item.name: + variations_limiter.add(item.name.replace(text_to_remove,"")) + # Get parent item if alreadyparent is False: parent = self.getParentItemByItem(item) @@ -608,7 +641,16 @@ class Market(object): variations.update(parents) # Add all variations of parents to the set parentids = tuple(item.ID for item in parents) - variations.update(eos.db.getVariations(parentids)) + groupids = tuple(item.group.ID for item in parents) + variations_list = eos.db.getVariations(parentids, groupids) + + if variations_limiter: + for limit in variations_limiter: + trimmed_variations_list = [variation_item for variation_item in variations_list if limit in variation_item.name] + if trimmed_variations_list: + variations_list = trimmed_variations_list + + variations.update(variations_list) return variations def getGroupsByCategory(self, cat):