itemTraderController.py (6578B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\itemTrader\itemTraderController.py 2 import math 3 from collections import defaultdict 4 import evetypes 5 import itertoolsext 6 from clientsettings.setting import CharSettingNumeric, CharSettingBool 7 from fsdBuiltData.common.itemTraderRecipesFSDLoader import ItemTraderRecipesFSDLoader 8 from localization import GetByMessageID, GetByLabel 9 from signals import Signal 10 11 class ItemTraderController(object): 12 13 def __init__(self, item_trader): 14 self.on_recipe_clicked = Signal('on_recipe_cliced') 15 self.recipes = {} 16 self.cargo_input_quantity = {} 17 recipeIDs = item_trader.GetRecipes() 18 self.LoadRecipes(recipeIDs) 19 self._selectedRecipe = None 20 self._searchString = '' 21 self._tempWndWidth = None 22 settingName = 'item_trader_browser_%s' % item_trader.typeID 23 self.selectedRecipeSetting = CharSettingNumeric(settingName, 0, min_value=0, max_value=1000000) 24 self.affordableSetting = CharSettingBool(settings_key='item_trader_affordable', default_value=False) 25 self.affordableSetting.set(False) 26 self.UpdateCargoQty() 27 28 @property 29 def selectedRecipe(self): 30 if not self._selectedRecipe: 31 lastSelectedID = self.selectedRecipeSetting.get() 32 lastSelectedRecipe = itertoolsext.first_or_default(self.recipes.values(), lambda x: x.recipeID == lastSelectedID and not self.IsFilteredOut(x)) 33 if lastSelectedRecipe: 34 self.selectedRecipe = lastSelectedRecipe 35 else: 36 defaultSelection = itertoolsext.first_or_default(self.recipes.values(), lambda x: not self.IsFilteredOut(x), self.recipes.values()[0]) 37 self.selectedRecipe = defaultSelection 38 return self._selectedRecipe 39 40 @selectedRecipe.setter 41 def selectedRecipe(self, value): 42 self._selectedRecipe = value 43 self.on_recipe_clicked(value) 44 self.selectedRecipeSetting.set(value.recipeID) 45 46 @property 47 def searchString(self): 48 return self._searchString 49 50 @searchString.setter 51 def searchString(self, value): 52 self._searchString = value.lower() if value else '' 53 54 @property 55 def tempWndWidth(self): 56 return self._tempWndWidth 57 58 @tempWndWidth.setter 59 def tempWndWidth(self, value): 60 self._tempWndWidth = value 61 62 def LoadRecipes(self, recipeIDs): 63 for recipeID in recipeIDs: 64 self.recipes[recipeID] = Recipe(recipeID) 65 66 def GetRecipes(self): 67 return self.recipes 68 69 def GetCargoQtyForTypeID(self, typeID): 70 return self.cargo_input_quantity.get(typeID, 0) 71 72 def GetQuantityFromCargo(self): 73 cargo_items = self._GetShipCargoItems() 74 cargo_input_quantity = defaultdict(int) 75 for item in cargo_items: 76 cargo_input_quantity[item.typeID] += item.quantity 77 78 return cargo_input_quantity 79 80 def _GetShipCargoItems(self): 81 ship_inventory = sm.GetService('invCache').GetInventoryFromId(session.shipid) 82 cargo_items = ship_inventory.List(const.flagCargo) 83 cargo_items += ship_inventory.List(const.flagGeneralMiningHold) 84 cargo_items += ship_inventory.List(const.flagSpecializedIceHold) 85 return cargo_items 86 87 def UpdateCargoQty(self): 88 self.cargo_input_quantity = self.GetQuantityFromCargo() 89 90 def GetInputMaxMultiplier(self): 91 currentRecipe = self.selectedRecipe 92 mults = [] 93 for type_id, qty in currentRecipe.inputItems.iteritems(): 94 cargo_quantity = self.cargo_input_quantity.get(type_id) 95 if not cargo_quantity or cargo_quantity < qty: 96 return 0 97 amount = int(math.floor(cargo_quantity / qty)) 98 mults.append(amount) 99 100 return min(mults) 101 102 def MatchesSearchQuery(self, recipe): 103 return recipe.MatchesSearchQuery(self.searchString) 104 105 def IsRecipeAffordable(self, recipe): 106 return recipe.IsAffordable(self.cargo_input_quantity) 107 108 def IsFilteredOut(self, recipe): 109 if self.affordableSetting.get(): 110 if not self.IsRecipeAffordable(recipe): 111 return True 112 if not self.MatchesSearchQuery(recipe): 113 return True 114 return False 115 116 117 class Recipe(object): 118 119 def __init__(self, recipeID): 120 data = ItemTraderRecipesFSDLoader.GetByID(recipeID) 121 self.recipeID = recipeID 122 self.data = data 123 124 @property 125 def inputIsk(self): 126 return self.data.inputIsk 127 128 @property 129 def inputItems(self): 130 return self.data.inputItems 131 132 @property 133 def outputItems(self): 134 return self.data.outputItems 135 136 @property 137 def groupID(self): 138 return self.data.groupID 139 140 @property 141 def displayName(self): 142 if self.data.displayNameID: 143 return GetByMessageID(self.data.displayNameID) 144 145 def GetRecipeNameAndSortValue(self): 146 if self.displayName: 147 return (self.displayName, self.displayName.lower()) 148 inputLabels = [] 149 for typeID, quantity in self.outputItems.iteritems(): 150 typeName = evetypes.GetName(typeID) 151 if quantity > 1: 152 text = GetByLabel('UI/Inventory/QuantityAndName', quantity=quantity, name=typeName) 153 else: 154 text = typeName 155 internalSortValue = (typeName.lower(), quantity) 156 inputLabels.append((internalSortValue, text)) 157 158 sortedListWithSortValues = sorted(inputLabels, key=lambda data: data[0]) 159 sortedInputLabels = [ item[1] for item in sortedListWithSortValues ] 160 sortValueForEntry = [ item[0] for item in sortedListWithSortValues ] 161 return (', '.join(sortedInputLabels), sortValueForEntry) 162 163 def MatchesSearchQuery(self, searchString): 164 if not searchString: 165 return True 166 if self.data.displayNameID: 167 recipeName = GetByMessageID(self.data.displayNameID) 168 if searchString in recipeName.lower(): 169 return True 170 for collection in (self.outputItems, self.inputItems): 171 for typeID, quantity in collection.iteritems(): 172 typeName = evetypes.GetName(typeID) 173 if searchString in typeName.lower(): 174 return True 175 176 return False 177 178 def IsAffordable(self, qtyInCargoByTypeID): 179 for typeID, quantity in self.inputItems.iteritems(): 180 if qtyInCargoByTypeID.get(typeID, 0) < quantity: 181 return False 182 183 return True