controllers.py (9961B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\sov\reagentBay\controllers.py 2 from collections import defaultdict 3 import eveformat 4 import mathext 5 from caching import Memoize 6 from const import DAY 7 from dogma.const import attributeSpecialColonyResourcesHoldCapacity 8 from eve.client.script.environment.invControllers import ShipCargo, ShipColonyResourcesHold 9 from eve.client.script.ui.eveColor import SUCCESS_GREEN_HEX 10 from localization import GetByLabel 11 from localization.formatters import FormatTimeIntervalWritten 12 from sovereignty.client.quasarCallWrapper import QuasarCallWrapper, DATA_NOT_AVAILABLE 13 from sovereignty.fuel.client.errors import SovFuelGetLevelsError, SovFuelAddRequestError 14 from sovereignty.fuel.client.data_types import Fuel 15 from stackless_response_router.exceptions import TimeoutException 16 import inventorycommon.const as invConst 17 import logging 18 logger = logging.getLogger(__name__) 19 REAGENT_TYPES = [invConst.typeColonyReagentIce, invConst.typeColonyReagentLava] 20 21 class ReagentBayWndController(object): 22 23 def __init__(self, sovHubID, solarSystemID, isStationMgr): 24 self.sovHubSvc = sm.GetService('sovHubSvc') 25 self.quasarCallWrapper = QuasarCallWrapper(self.sovHubSvc) 26 self._sovHubID = sovHubID 27 self._solarSystemID = solarSystemID 28 self._isStationMgr = isStationMgr 29 self.busyDepositingItems = False 30 self.depositBtnDelay = False 31 self.useResourceHold = False 32 33 @property 34 def sovHubID(self): 35 return self._sovHubID 36 37 @property 38 def solarSystemID(self): 39 return self._solarSystemID 40 41 @property 42 def isStationMgr(self): 43 return self._isStationMgr 44 45 def IsSameItemID(self, sovHubID): 46 return self.sovHubID == sovHubID 47 48 def PrimeFuelByTypeID(self): 49 if self.GetFuelByTypeID() == DATA_NOT_AVAILABLE: 50 self.GetFuelByTypeID.clear_memoized(self) 51 raise SovFuelGetLevelsError() 52 53 @Memoize(1) 54 def GetFuelByTypeID(self): 55 fuelByTypeID = self.quasarCallWrapper.GetReagentsByTypeID(self.sovHubID) 56 if fuelByTypeID == DATA_NOT_AVAILABLE: 57 return DATA_NOT_AVAILABLE 58 ret = {x:Fuel(x, 0, 0, None) for x in REAGENT_TYPES} 59 ret.update(fuelByTypeID) 60 return ret 61 62 @Memoize 63 def GetInstalledUpgrades(self): 64 return self.quasarCallWrapper.GetInstalledUpgradesForHub(self.sovHubID) 65 66 def GetNumOnlineAndInstalledUpgradesText(self): 67 installedUpgrades = self.GetInstalledUpgrades() 68 if installedUpgrades == DATA_NOT_AVAILABLE: 69 return DATA_NOT_AVAILABLE 70 numTotal = len(installedUpgrades) 71 numOnline = len([ x for x in installedUpgrades if x.is_power_online ]) 72 return GetByLabel('UI/Sovereignty/SovHub/ReagentBay/NumUpgradesOnline', numOnline=numOnline, numTotal=numTotal) 73 74 def CanSeeUpgrades(self): 75 return self._isStationMgr 76 77 def DoDepositItems(self, qtyByTypeID): 78 self._MergeItemsBeforeDeposit(qtyByTypeID) 79 cargoInvController = self.GetSelectedSourceHold() 80 cargoItemsByTypeID = self.GetSortedItemsByTypeID(qtyByTypeID.keys(), cargoInvController) 81 failedToMove = qtyByTypeID.copy() 82 for typeID, qty in qtyByTypeID.iteritems(): 83 if qty <= 0: 84 failedToMove.pop(typeID, None) 85 continue 86 qtyLeftToMove = qty 87 typeItemsInCargo = cargoItemsByTypeID.get(typeID, []) 88 if not typeItemsInCargo: 89 failedToMove[typeID] = qty 90 continue 91 for rec in typeItemsInCargo: 92 if qtyLeftToMove <= 0: 93 failedToMove.pop(typeID, None) 94 break 95 qtyToMove = min(rec.stacksize, qtyLeftToMove) 96 try: 97 self.sovHubSvc.AddFuel(rec.itemID, qtyToMove, self.sovHubID) 98 qtyLeftToMove -= qtyToMove 99 except SovFuelAddRequestError as e: 100 logger.exception('Failed to add fuel') 101 break 102 except TimeoutException as e: 103 logger.exception('Failed to add fuel due to timeout') 104 break 105 106 if qtyLeftToMove <= 0: 107 failedToMove.pop(typeID, None) 108 else: 109 failedToMove[typeID] = qtyLeftToMove 110 111 self.GetFuelByTypeID.clear_memoized(self) 112 return failedToMove 113 114 def _MergeItemsBeforeDeposit(self, qtyByTypeID): 115 cargoInvController = self.GetSelectedSourceHold() 116 cargoItemsByTypeID = self.GetSortedItemsByTypeID(qtyByTypeID.keys(), cargoInvController) 117 for typeID, qty in qtyByTypeID.iteritems(): 118 mergeData = [] 119 sourceContainerID = None 120 destID = None 121 typeItemsInCargo = cargoItemsByTypeID.get(typeID, []) 122 if not typeItemsInCargo: 123 continue 124 qtyLeftToFind = qty 125 for rec in typeItemsInCargo: 126 if qtyLeftToFind <= 0: 127 break 128 if sourceContainerID is None: 129 sourceContainerID = rec.locationID 130 destID = rec.itemID 131 else: 132 mergeData.append((rec.itemID, 133 destID, 134 rec.stacksize, 135 rec)) 136 qtyLeftToFind -= rec.stacksize 137 138 if sourceContainerID and len(mergeData): 139 cargoInvController.MultiMerge(mergeData, sourceContainerID) 140 141 def GetSortedItemsByTypeID(self, wantedTypeIDs, invController): 142 unsortedItemsByTypeID = defaultdict(list) 143 for rec in invController.GetItems(): 144 if rec.typeID in wantedTypeIDs: 145 unsortedItemsByTypeID[rec.typeID].append(rec) 146 147 sortedItemsByTypeID = {} 148 for typeID, itemList in unsortedItemsByTypeID.items(): 149 sortedItemsByTypeID[typeID] = sorted(itemList, key=lambda x: x.stacksize, reverse=True) 150 151 return sortedItemsByTypeID 152 153 def GetQtyByTypeID_InHold(self): 154 cargoInvController = self.GetSelectedSourceHold() 155 cargoQtyByTypeID = defaultdict(int) 156 for item in cargoInvController.GetItems(): 157 cargoQtyByTypeID[item.typeID] += item.stacksize 158 159 return cargoQtyByTypeID 160 161 def GetSelectedSourceHold(self): 162 if self.useResourceHold: 163 return ShipColonyResourcesHold() 164 return ShipCargo() 165 166 def GetQtyInCargoHintPath(self): 167 if self.useResourceHold: 168 return 'UI/Sovereignty/SovHub/ReagentBay/NumUnitsInReagentBay' 169 return 'UI/Inflight/SpaceComponents/UnderConstruction/NumUnitsInCargo' 170 171 def GetNoQtyInCargoHintPath(self): 172 if self.useResourceHold: 173 return 'UI/Sovereignty/SovHub/ReagentBay/NoSuchItemInInfrastructureHold' 174 return 'UI/Inflight/SpaceComponents/UnderConstruction/NoSuchItemInCargo' 175 176 def GetSourceOptions(self): 177 if not self.HasResourceBay(): 178 return [] 179 cargoInvController = ShipCargo() 180 resourceBayController = ShipColonyResourcesHold() 181 options = [] 182 for invController in [resourceBayController, cargoInvController]: 183 options.append((invController.GetName(), 184 invController.GetInvID(), 185 None, 186 invController.GetIconName())) 187 188 return options 189 190 def GetComboPrefsKey(self): 191 return ('char', 'ui', 'fittingInvCombo') 192 193 def HasResourceBay(self): 194 return bool(sm.GetService('godma').GetAttributeValueByID(session.shipid, attributeSpecialColonyResourcesHoldCapacity)) 195 196 197 HOURS_IN_4_WEEKS = 672 198 199 class InputItemController(object): 200 201 def __init__(self, typeID, qtyInCargo, burnedPerHour): 202 self.typeID = typeID 203 self.qtyInCargo = 0 204 self._unitsInSovHub = qtyInCargo 205 self._burnedPerHour = burnedPerHour 206 207 @property 208 def maxToAdd(self): 209 maxToAdd = max(0, self.qtyInCargo) 210 return maxToAdd 211 212 @property 213 def unitsInSovHub(self): 214 return self._unitsInSovHub 215 216 @unitsInSovHub.setter 217 def unitsInSovHub(self, units): 218 self._unitsInSovHub = units 219 220 @property 221 def burnedPerHour(self): 222 return self._burnedPerHour 223 224 @burnedPerHour.setter 225 def burnedPerHour(self, value): 226 self._burnedPerHour = value 227 228 @property 229 def amountBurnedIn4weeks(self): 230 return self._burnedPerHour * HOURS_IN_4_WEEKS 231 232 def GetWindowProgress(self, unitsInWnd): 233 return self._GetProgressFromValue(unitsInWnd) 234 235 def GetProgress(self, unitsInWnd): 236 inSovHubProgress = self._GetProgressFromValue(self.unitsInSovHub) 237 inWndProgress = self._GetProgressFromValue(unitsInWnd) 238 return (inSovHubProgress, inWndProgress) 239 240 def _GetProgressFromValue(self, value): 241 if self.amountBurnedIn4weeks: 242 progress = mathext.clamp(float(value) / self.amountBurnedIn4weeks, 0, 1) 243 else: 244 progress = 0 245 return progress 246 247 def GetTimesLeft(self, unitsInWnd): 248 timeLeftInHub = self._GetTimeForFuel(self.unitsInSovHub) 249 if not unitsInWnd: 250 return timeLeftInHub 251 timeAdded = self._GetTimeForFuel(unitsInWnd) 252 if not timeAdded: 253 return timeLeftInHub 254 timeAdded = '+' + timeAdded 255 return '%s %s' % (timeLeftInHub, eveformat.color(timeAdded, SUCCESS_GREEN_HEX)) 256 257 def _GetTimeForFuel(self, units): 258 if self.burnedPerHour: 259 hoursLeft = units / self.burnedPerHour 260 daysLeft = hoursLeft / 24 261 if daysLeft <= 0: 262 return GetByLabel('/Carbon/UI/Common/WrittenDateTimeQuantity/Day', units=0) 263 timeLeftInBlue = int(daysLeft * DAY) 264 text = FormatTimeIntervalWritten(timeLeftInBlue, showFrom='day', showTo='day') 265 return text 266 else: 267 return ''