NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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 ''