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

minihangar.py (14778B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fittingScreen\fittingPanels\minihangar.py
      2 from collections import defaultdict
      3 import evetypes
      4 from carbon.client.script.environment.AudioUtil import PlaySound
      5 from carbon.common.script.util.format import FmtAmt
      6 from carbonui.primitives.container import Container
      7 from carbonui.primitives.fill import Fill
      8 from carbonui.primitives.frame import Frame
      9 from eve.client.script.environment import invControllers as invCtrl
     10 from eve.client.script.ui.control import eveIcon, eveLabel
     11 from eve.client.script.ui.control.utilMenu import UtilMenu
     12 from eve.client.script.ui.shared.fitting.fittingUtil import EatSignalChangingErrors
     13 from eve.client.script.ui.shared.fittingScreen.fittingUtil import GetColoredText
     14 from eve.common.lib import appConst as const
     15 from eve.common.script.sys import eveCfg
     16 from shipfitting.fittingWarnings import GetColorForLevel
     17 from signals.signalUtil import ChangeSignalConnect
     18 from inventorycommon.util import IsShipFittingFlag, IsShipFittable
     19 import uthread
     20 import carbonui.const as uiconst
     21 import localization
     22 from carbonui.uicore import uicore
     23 
     24 class CargoSlots(Container):
     25     default_state = uiconst.UI_NORMAL
     26 
     27     def ApplyAttributes(self, attributes):
     28         Container.ApplyAttributes(self, attributes)
     29         self.warningFrame = None
     30         self.controller = attributes.controller
     31         self.ChangeSignalConnection(connect=True)
     32         invController = self.GetInvController()
     33         getMenuFunc = attributes.getMenuFunc
     34         if getMenuFunc:
     35             self.itemUtilMenu = self.AddUtilMenu(getMenuFunc)
     36             self.itemUtilMenu.OnDropData = self.OnDropData
     37         else:
     38             self.itemUtilMenu = None
     39         self.sr.icon = eveIcon.Icon(parent=self, size=32, state=uiconst.UI_DISABLED, ignoreSize=True, icon=invController.GetIconName())
     40         self.sr.hilite = Fill(parent=self, name='hilite', align=uiconst.RELATIVE, state=uiconst.UI_HIDDEN, idx=-1, width=32, height=self.height)
     41         self.sr.icon.opacity = 0.8
     42         Container(name='push', parent=self, align=uiconst.TOLEFT, width=32)
     43         self.sr.statusCont = Container(name='statusCont', parent=self, align=uiconst.TOLEFT, width=50)
     44         self.sr.statustext1 = eveLabel.EveLabelMedium(text='status', parent=self.sr.statusCont, name='cargo_statustext', left=0, top=2, idx=0, state=uiconst.UI_DISABLED, align=uiconst.TOPRIGHT)
     45         self.sr.statustext2 = eveLabel.EveLabelMedium(text='status', parent=self.sr.statusCont, name='cargo_statustext', left=0, top=14, idx=0, state=uiconst.UI_DISABLED, align=uiconst.TOPRIGHT)
     46         m3TextCont = Container(name='m3Cont', parent=self, align=uiconst.TOLEFT, width=12)
     47         self.sr.m3Text = eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Fitting/FittingWindow/CubicMeters'), parent=m3TextCont, name='m3', left=4, top=14, idx=0)
     48         sm.GetService('inv').Register(self)
     49         self.invReady = 1
     50         self.Update()
     51 
     52     def ChangeSignalConnection(self, connect = True):
     53         signalAndCallback = [(self.controller.on_stats_changed, self.Update), (self.controller.on_new_itemID, self.Update), (self.controller.on_warning_display_changed, self.ChangeWarningDisplay)]
     54         ChangeSignalConnect(signalAndCallback, connect)
     55 
     56     def ConstructWarningFrame(self):
     57         if self.warningFrame and not self.warningFrame.destroyed:
     58             return
     59         self.warningFrame = Frame(bgParent=self, frameConst=uiconst.FRAME_BORDER1_CORNER9, padding=(-2, -2, -4, 0))
     60 
     61     def AddUtilMenu(self, expandMenuFunc):
     62         invController = self.GetInvController()
     63         if invController:
     64             iconName = invController.GetIconName()
     65         else:
     66             iconName = ''
     67         utilMenu = UtilMenu(menuAlign=uiconst.TOPLEFT, parent=self, align=uiconst.TOPLEFT, GetUtilMenu=expandMenuFunc, texturePath=iconName, idx=0, iconSize=32, pos=(0, 0, 32, 32))
     68         return utilMenu
     69 
     70     def IsItemHere(self, item):
     71         return True
     72 
     73     def AddItem(self, item):
     74         self.Update()
     75 
     76     def UpdateItem(self, item, *etc):
     77         self.Update()
     78 
     79     def RemoveItem(self, item):
     80         self.Update()
     81 
     82     def OnClick(self, *args):
     83         if self.controller.IsSimulated():
     84             if self.itemUtilMenu:
     85                 self.itemUtilMenu.OnClick()
     86         else:
     87             self.OnHoldClicked()
     88         PlaySound(uiconst.SOUND_BUTTON_CLICK)
     89 
     90     def OnHoldClicked(self):
     91         pass
     92 
     93     def OnMouseEnter(self, *args):
     94         self.DoMouseEntering()
     95         PlaySound(uiconst.SOUND_BUTTON_HOVER)
     96 
     97     def OnMouseEnterDrone(self, *args):
     98         if session.stationid:
     99             self.DoMouseEntering()
    100 
    101     def DoMouseEntering(self):
    102         self.Hilite(1)
    103         self.sr.statustext1.OnMouseEnter()
    104         self.sr.statustext2.OnMouseEnter()
    105         self.sr.m3Text.OnMouseEnter()
    106 
    107     def OnMouseExit(self, *args):
    108         self.Hilite(0)
    109         self.sr.statustext1.OnMouseExit()
    110         self.sr.statustext2.OnMouseExit()
    111         self.sr.m3Text.OnMouseExit()
    112         uthread.new(self.Update)
    113 
    114     def Hilite(self, state):
    115         self.sr.icon.opacity = [0.8, 1.0][state]
    116 
    117     def SetStatusText(self, text1, text2, color):
    118         self.sr.statustext1.text = text1
    119         self.sr.statustext2.text = localization.GetByLabel('UI/Fitting/FittingWindow/CargoUsage', color=color, text=text2)
    120         self.sr.statusCont.width = max(0, self.sr.statustext1.textwidth, self.sr.statustext2.textwidth)
    121 
    122     def OnDropData(self, dragObj, nodes):
    123         self.Hilite(0)
    124 
    125     def Update(self, *args):
    126         uthread.new(self._Update)
    127 
    128     def _Update(self):
    129         if not self.controller.CurrentShipIsLoaded():
    130             return
    131         if not self.controller.IsValidItemAndSimulationState():
    132             return
    133         try:
    134             cap = self.GetCapacity()
    135         except (RuntimeError, AttributeError) as e:
    136             sm.GetService('fittingSvc').LogWarn('Failed to get cap for ship: ', e)
    137             return
    138 
    139         if not cap or not self or self.destroyed:
    140             return
    141         try:
    142             capacityInfo = self.GetCapacityInfo()
    143         except KeyError:
    144             self.SetStatusText('-', '-', '')
    145             return
    146 
    147         cap2 = capacityInfo.value
    148         used = FmtAmt(cap.used, showFraction=1)
    149         cap2 = FmtAmt(cap2, showFraction=1)
    150         coloredText = GetColoredText(isBetter=capacityInfo.isBetterThanBefore, text=cap2)
    151         self.SetStatusText(used, coloredText, '')
    152         self.SetMenuState()
    153 
    154     def GetCapacity(self, flag = None):
    155         if self.controller.IsSimulated():
    156             return self.GetSimulatedCapacity()
    157         else:
    158             return self.GetInvController().GetCapacity()
    159 
    160     def GetSimulatedCapacity(self):
    161         pass
    162 
    163     def GetCapacityInfo(self):
    164         pass
    165 
    166     def GetInvController(self):
    167         pass
    168 
    169     def SetMenuState(self):
    170         if self.itemUtilMenu is None:
    171             return
    172         if self.controller.IsSimulated():
    173             self.itemUtilMenu.display = True
    174         else:
    175             self.itemUtilMenu.display = False
    176 
    177     def ChangeWarningDisplay(self, warningModuleSlotDict, *args):
    178         pass
    179 
    180     def Close(self):
    181         with EatSignalChangingErrors(errorMsg='Container'):
    182             self.ChangeSignalConnection(connect=False)
    183         Container.Close(self)
    184 
    185 
    186 class CargoDroneSlots(CargoSlots):
    187 
    188     def ChangeSignalConnection(self, connect = True):
    189         CargoSlots.ChangeSignalConnection(self, connect=connect)
    190         signalAndCallback = [(self.controller.on_drone_bay_open, self.OnClick)]
    191         ChangeSignalConnect(signalAndCallback, connect)
    192 
    193     def GetInvController(self):
    194         if self.controller.IsSimulated():
    195             itemID = None
    196         else:
    197             itemID = self.controller.GetItemID()
    198         return invCtrl.ShipDroneBay(itemID)
    199 
    200     def OnDropData(self, dragObj, nodes):
    201         if self.controller.IsSimulated():
    202             self.AddSimulatedDrones(nodes)
    203         else:
    204             shipID = eveCfg.GetActiveShip()
    205             invCtrl.ShipDroneBay(shipID).OnDropData(nodes)
    206         CargoSlots.OnDropData(self, dragObj, nodes)
    207 
    208     def OnHoldClicked(self, *args):
    209         uicore.cmd.OpenDroneBayOfActiveShip()
    210 
    211     def GetCapacityInfo(self, flag = None):
    212         return self.controller.GetDroneCapacity()
    213 
    214     def GetSimulatedCapacity(self):
    215         shipID = self.controller.GetItemID()
    216         return self.controller.dogmaLocation.GetCapacity(shipID, None, const.flagDroneBay)
    217 
    218     def AddSimulatedDrones(self, nodes):
    219         qtyByTypeIDs = GetQtyByTypeAndItemIDs(nodes)
    220         for typeID, itemID in qtyByTypeIDs.keys():
    221             if evetypes.GetCategoryID(typeID) != const.categoryDrone:
    222                 qtyByTypeIDs.pop(typeID, None)
    223 
    224         sm.GetService('ghostFittingSvc').TryFitDronesToDroneBay(qtyByTypeIDs)
    225 
    226 
    227 class CargoCargoSlots(CargoSlots):
    228 
    229     def GetInvController(self):
    230         if self.controller.IsSimulated():
    231             itemID = None
    232         else:
    233             itemID = self.controller.GetItemID()
    234         return invCtrl.ShipCargo(itemID)
    235 
    236     def OnDropData(self, dragObj, nodes):
    237         if self.controller.IsSimulated():
    238             return self.AddSimulatedCargo(nodes)
    239         self.Hilite(0)
    240         if len(nodes) == 1:
    241             item = nodes[0].item
    242             if item and IsShipFittingFlag(item.flagID):
    243                 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    244                 shipID = eveCfg.GetActiveShip()
    245                 if IsShipFittable(item.categoryID):
    246                     return dogmaLocation.UnloadModuleToContainer(shipID, item.itemID, (shipID,), flag=const.flagCargo)
    247                 if item.categoryID == const.categoryCharge:
    248                     return dogmaLocation.UnloadAmmoToContainer(shipID, item, (shipID, session.charid, const.flagCargo))
    249         invCtrl.ShipCargo(eveCfg.GetActiveShip()).OnDropData(nodes)
    250         CargoSlots.OnDropData(self, dragObj, nodes)
    251 
    252     def AddSimulatedCargo(self, nodes):
    253         qtyByTypeIDs = GetQtyByTypeIDs(nodes)
    254         sm.GetService('ghostFittingSvc').TryFitItemsToCargo(qtyByTypeIDs)
    255 
    256     def OnHoldClicked(self, *args):
    257         uicore.cmd.OpenCargoHoldOfActiveShip()
    258 
    259     def GetCapacityInfo(self, flag = None):
    260         return self.controller.GetCargoCapacity()
    261 
    262     def GetSimulatedCapacity(self):
    263         shipID = self.controller.GetItemID()
    264         return self.controller.dogmaLocation.GetCapacity(shipID, None, const.flagCargo)
    265 
    266     def ChangeWarningDisplay(self, warningModuleSlotDict, *args):
    267         invCtrl = self.GetInvController()
    268         warningLevel = warningModuleSlotDict.get(invCtrl.locationFlag, None)
    269         if warningLevel:
    270             color = GetColorForLevel(warningLevel)
    271             self.ConstructWarningFrame()
    272             self.warningFrame.display = True
    273             self.warningFrame.SetRGBA(*color)
    274         elif self.warningFrame:
    275             self.warningFrame.display = False
    276 
    277 
    278 class CargoFighterSlots(CargoSlots):
    279 
    280     def ChangeSignalConnection(self, connect = True):
    281         CargoSlots.ChangeSignalConnection(self, connect=connect)
    282         signalAndCallback = [(self.controller.on_drone_bay_open, self.OnClick)]
    283         ChangeSignalConnect(signalAndCallback, connect)
    284 
    285     def GetInvController(self):
    286         if self.controller.IsSimulated():
    287             itemID = None
    288         else:
    289             itemID = self.controller.GetItemID()
    290         return invCtrl.ShipFighterBay(itemID)
    291 
    292     def OnDropData(self, dragObj, nodes):
    293         if self.controller.IsSimulated():
    294             self.AddSimulatedFighters(nodes)
    295         else:
    296             self.GetInvController().OnDropData(nodes)
    297             CargoSlots.OnDropData(self, dragObj, nodes)
    298 
    299     def OnHoldClicked(self, *args):
    300         uicore.cmd.OpenFighterBayOfActiveShip()
    301 
    302     def GetCapacityInfo(self, flag = None):
    303         return self.controller.GetFighterCapacity()
    304 
    305     def GetSimulatedCapacity(self):
    306         shipID = self.controller.GetItemID()
    307         return self.controller.dogmaLocation.GetCapacity(shipID, None, const.flagFighterBay)
    308 
    309     def AddSimulatedFighters(self, nodes):
    310         qtyByTypeIDs = GetQtyByTypeIDs(nodes)
    311         for typeID in qtyByTypeIDs.keys():
    312             if evetypes.GetCategoryID(typeID) != const.categoryFighter:
    313                 qtyByTypeIDs.pop(typeID, None)
    314 
    315         if qtyByTypeIDs:
    316             sm.GetService('ghostFittingSvc').TryFitFightersToTubeOrBay(qtyByTypeIDs)
    317 
    318     def ChangeWarningDisplay(self, warningModuleSlotDict, *args):
    319         invCtrl = self.GetInvController()
    320         warningLevel = None
    321         for eachFlag in [invCtrl.locationFlag] + const.fighterTubeFlags:
    322             warningLevel = max(warningLevel, warningModuleSlotDict.get(eachFlag, None))
    323 
    324         if warningLevel:
    325             color = GetColorForLevel(warningLevel)
    326             self.ConstructWarningFrame()
    327             self.warningFrame.display = True
    328             self.warningFrame.SetRGBA(*color)
    329         elif self.warningFrame:
    330             self.warningFrame.display = False
    331 
    332 
    333 class CargoStructureAmmoBay(CargoSlots):
    334 
    335     def GetInvController(self):
    336         return invCtrl.StructureAmmoBay(self.controller.GetItemID())
    337 
    338     def OnDropData(self, dragObj, nodes):
    339         if self.controller.IsSimulated():
    340             return self.AddSimulatedCargo(nodes)
    341         self.GetInvController().OnDropData(nodes)
    342         CargoSlots.OnDropData(self, dragObj, nodes)
    343 
    344     def OnHoldClicked(self, *args):
    345         itemID = self.controller.GetItemID()
    346         invID = ('StructureAmmoBay', itemID)
    347         from eve.client.script.ui.shared.inventory.invWindow import Inventory
    348         Inventory.OpenOrShow(invID, usePrimary=False, toggle=True)
    349 
    350     def GetCapacityInfo(self, flag = None):
    351         return self.controller.GetCargoCapacity()
    352 
    353     def GetSimulatedCapacity(self):
    354         shipID = self.controller.GetItemID()
    355         return self.controller.dogmaLocation.GetCapacity(shipID, None, const.flagCargo)
    356 
    357     def AddSimulatedCargo(self, nodes):
    358         qtyByTypeIDs = GetQtyByTypeIDs(nodes)
    359         sm.GetService('ghostFittingSvc').TryFitItemsToCargo(qtyByTypeIDs)
    360 
    361 
    362 def GetQtyByTypeIDs(nodes):
    363     qtyByTypeIDs = defaultdict(int)
    364     for eachNode in nodes:
    365         typeID = getattr(eachNode, 'typeID', None)
    366         if typeID is None and getattr(eachNode, 'rec', None):
    367             typeID = eachNode.rec.typeID
    368         if typeID:
    369             qtyByTypeIDs[typeID] += 1
    370 
    371     return qtyByTypeIDs
    372 
    373 
    374 def GetQtyByTypeAndItemIDs(nodes):
    375     qtyByTypeIDs = defaultdict(int)
    376     for eachNode in nodes:
    377         typeID = getattr(eachNode, 'typeID', None)
    378         itemID = getattr(eachNode, 'itemID', None)
    379         if typeID is None and getattr(eachNode, 'rec', None):
    380             typeID = eachNode.rec.typeID
    381         if typeID:
    382             qtyByTypeIDs[typeID, itemID] += 1
    383 
    384     return qtyByTypeIDs