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

fittingSlotController.py (12103B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fittingScreen\fittingSlotController.py
      2 import carbonui.const as uiconst
      3 import dogma.data as dogma_data
      4 import eveicon
      5 import evetypes
      6 import uthread
      7 from carbonui.control.contextMenu.menuEntryData import MenuEntryData
      8 from carbonui.control.dragdrop.dragdata import TypeDragData
      9 from menu import MenuLabel
     10 from carbonui.uicore import uicore
     11 from eve.client.script.ui.shared.fitting.fittingSlotController import FittingSlotController
     12 from eve.client.script.ui.shared.fitting.fittingUtil import RigFittingCheck, IsCharge
     13 from eve.client.script.ui.shared.fittingScreen import OFFLINE, ONLINE, ACTIVE, OVERHEATED, fittingSignals
     14 from eve.client.script.ui.shared.fittingScreen.fittingUtil import GetOriginalItemID
     15 from eve.common.script.sys.eveCfg import IsDocked
     16 from localization import GetByLabel
     17 from menu import MenuLabel
     18 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     19 from shipfitting.errorConst import WRONG_SLOT
     20 from shipfitting.fittingStuff import IsRightSlotForType, IsFittable
     21 from utillib import KeyVal
     22 
     23 class ShipFittingSlotController(FittingSlotController):
     24 
     25     def __init__(self, flagID, parentController):
     26         FittingSlotController.__init__(self, flagID, parentController)
     27 
     28     def GetModule(self):
     29         if self.IsModulePreviewModule():
     30             return None
     31         return self.dogmaModuleItem
     32 
     33     def GetModuleOrPreview(self):
     34         return self.dogmaModuleItem
     35 
     36     def IsModulePreviewModule(self):
     37         if not self.dogmaModuleItem:
     38             return False
     39         if getattr(self.dogmaModuleItem, 'isPreviewItem', False):
     40             return True
     41         return False
     42 
     43     def Add(self, item, sourceLocation = None):
     44         if self.IsSimulated():
     45             return self.AddSimulatedItem(item)
     46         else:
     47             guid = getattr(item, '__guid__', None)
     48             if guid is None and item.itemID or guid in ('listentry.InvItem', 'xtriui.InvItem'):
     49                 return self.AddRealItem(item)
     50             sm.GetService('ghostFittingSvc').LoadCurrentShip()
     51             return self.AddSimulatedItem(item)
     52 
     53     def AddSimulatedItem(self, item):
     54         ghostFittingSvc = sm.GetService('ghostFittingSvc')
     55         if not IsRightSlotForType(self.dogmaLocation.dogmaStaticMgr, item.typeID, self.flagID):
     56             ghostFittingSvc.SendOnFeedbackTextChanged(KeyVal(errorKey=WRONG_SLOT, extraInfo=None), timeout=True)
     57             return
     58         shipID = self.GetParentID()
     59         wasUnfitted = self._TryUnfitModule(ghostFittingSvc, item)
     60         originalItemID = GetOriginalItemID(item.itemID)
     61         dogmaItem, errorInfo = ghostFittingSvc.FitModuleToShipAndChangeState(shipID, self.GetFlagID(), item.typeID, originalItemID=originalItemID)
     62         if dogmaItem:
     63             ghostFittingSvc.SendFittingSlotsChangedEvent()
     64         else:
     65             flagID = getattr(item, 'flagID', None)
     66             if wasUnfitted and flagID:
     67                 ghostFittingSvc.FitModuleToShipAndChangeState(shipID, flagID, item.typeID, originalItemID=originalItemID)
     68             ghostFittingSvc.SendOnFeedbackTextChanged(errorInfo, timeout=True)
     69 
     70     def _TryUnfitModule(self, ghostFittingSvc, item):
     71         itemID = getattr(item, 'itemID', None)
     72         wasFitted = getattr(item, 'isFitted', False)
     73         if wasFitted and itemID and not uicore.uilib.Key(uiconst.VK_SHIFT):
     74             return sm.GetService('ghostFittingSvc').UnfitModule(itemID)
     75 
     76     def AddRealItem(self, item):
     77         if not getattr(item, 'typeID', None):
     78             return
     79         if not RigFittingCheck(item, self.parentController.GetTypeID()):
     80             return
     81         validFitting = False
     82         shift = uicore.uilib.Key(uiconst.VK_SHIFT)
     83         for effect in dogma_data.get_type_effects(item.typeID):
     84             if not IsFittable(effect.effectID):
     85                 continue
     86             validFitting = True
     87             if effect.effectID == self.GetPowerType():
     88                 isFitted = item.locationID == self.GetParentID() and item.flagID != const.flagCargo
     89                 if isFitted and shift and self.GetModule():
     90                     if self.GetModule().typeID == item.typeID:
     91                         self.LinkWithWeapon(item)
     92                         return
     93                     else:
     94                         prompt_player_fsd_dialog('CustomNotify', {'notify': GetByLabel('UI/Fitting/GroupingIncompatible')})
     95                         return
     96                 self.FitModule(item)
     97                 return
     98             msgDict = {'item': evetypes.GetName(item.typeID),
     99              'slotpower': dogma_data.get_effect_display_name(self.GetPowerType()),
    100              'itempower': dogma_data.get_effect_display_name(effect.effectID)}
    101             prompt_player_fsd_dialog('ItemDoesntFitPower', msgDict)
    102 
    103         if not validFitting:
    104             raise UserError('ItemNotHardware', {'itemname': item.typeID})
    105 
    106     def OnDropData(self, dragObj, nodes):
    107         if self.GetModule() is not None and not self.SlotExists():
    108             return
    109         items, fakeItems = self.GetDroppedItems(nodes)
    110         allItems = items + fakeItems
    111         chargeTypeID = None
    112         chargeItems = []
    113         for item in allItems:
    114             if not getattr(item, 'typeID', None):
    115                 return
    116             if IsCharge(item.typeID):
    117                 if self.IsChargeable():
    118                     if chargeTypeID is None:
    119                         chargeTypeID = item.typeID
    120                     if chargeTypeID == item.typeID:
    121                         chargeItems.append(item)
    122             else:
    123                 uthread.new(self.Add, item)
    124 
    125         if len(chargeItems):
    126             if fakeItems and not self.IsSimulated():
    127                 sm.GetService('ghostFittingSvc').LoadCurrentShip()
    128             self.FitCharges(chargeItems)
    129 
    130     def GetDroppedItems(self, nodes):
    131         items = []
    132         fakeItems = []
    133         for node in nodes:
    134             guid = getattr(node, '__guid__', None)
    135             if guid in ('listentry.InvItem', 'xtriui.InvItem'):
    136                 invType = node.rec
    137                 if self.IsFittableType(invType.typeID):
    138                     items.append(invType)
    139             elif guid in ('listentry.GenericMarketItem', 'listentry.Item', 'listentry.FittingModuleEntry') or isinstance(node, TypeDragData):
    140                 if self.IsFittableType(node.typeID):
    141                     fakeItems.append(KeyVal(typeID=node.typeID, itemID=getattr(node, 'itemID', None), isFitted=getattr(node, 'isFitted', False), flagID=getattr(node, 'flagID', None)))
    142 
    143         return (items, fakeItems)
    144 
    145     def GetMenu(self, slot):
    146         m = []
    147         flagID = self.GetFlagID()
    148         if flagID in const.moduleSlotFlags + const.rigSlotFlags:
    149             m += [(MenuLabel('UI/Fitting/FittingWindow/SetFiltersForSlot'), sm.ScatterEvent, ('OnFittingFlagFilterSet', flagID))]
    150         typeID = self.GetModuleTypeID()
    151         if typeID and self.GetModuleID():
    152             m += [MenuEntryData(MenuLabel('UI/Fitting/FittingWindow/FindTypeInBrowser'), lambda : fittingSignals.on_find_type_in_browser(typeID), texturePath=eveicon.search)]
    153             sm.GetService('marketutils').AddMarketDetailsMenuOption(m, typeID)
    154             m += self.GetGroupMenu()
    155         elif self.GetFailedTypeID():
    156             m += [(MenuLabel('UI/Fitting/FittingWindow/ClearSlot'), self.ClearFailedSlot, (slot,))]
    157         return m
    158 
    159     def ClearFailedSlot(self, slot):
    160         self.SetFailedTypeID(None)
    161         self.UpdateStatusDisplay(slot)
    162 
    163     def _GetUnfitOption(self):
    164         return [MenuEntryData(MenuLabel('UI/Fitting/Unfit'), self.Unfit, texturePath=eveicon.close)]
    165 
    166     def GetGroupMenu(self, *args):
    167         masterID = self.IsInWeaponBank()
    168         if masterID:
    169             return [(MenuLabel('UI/Fitting/ClearGroup'), self.DestroyWeaponBank, ())]
    170         return []
    171 
    172     def OnClick(self, slot):
    173         if self.GetModule() is None:
    174             flagID = self.GetFlagID()
    175             if flagID in const.moduleSlotFlags + const.rigSlotFlags:
    176                 sm.ScatterEvent('OnFittingFlagFilterSet', flagID)
    177                 return
    178         if self.IsSimulated():
    179             return self.OnClickSimulated(slot)
    180         if not self._ShouldContinueAfterOfflineWarning():
    181             return
    182         self.ToggleOnlineModule()
    183 
    184     def _ShouldContinueAfterOfflineWarning(self):
    185         if not self.IsOnlineable():
    186             return False
    187         if IsDocked():
    188             return True
    189         if not self.IsOnline():
    190             return True
    191         if prompt_player_fsd_dialog('PutOffline', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES:
    192             return True
    193         return False
    194 
    195     def OnClickSimulated(self, slot):
    196         if self.GetModule() is None:
    197             return
    198         typeID = self.GetModuleTypeID()
    199         itemKey = self.GetModuleID()
    200         flagID = self.GetFlagID()
    201         ghostFittingSvc = sm.GetService('ghostFittingSvc')
    202         if flagID not in const.rigSlotFlags and not self.IsOnlineable():
    203             if self.IsOnline():
    204                 ghostFittingSvc.OfflineSlotList([flagID])
    205         else:
    206             ghostFittingSvc.SwitchBetweenModes(itemKey, typeID, flagID)
    207         self.UpdateStatusDisplay(slot)
    208 
    209     def UpdateStatusDisplay(self, slot):
    210         slot.SetIconNotAsPreview()
    211         if not self.IsSimulated():
    212             slot.HideModuleSlotFill()
    213             slot.ChangeWarningDisplay(False)
    214             return
    215         ghostFittingSvc = sm.GetService('ghostFittingSvc')
    216         itemKey = self.GetModuleID()
    217         typeID = self.GetModuleTypeID()
    218         flagID = self.GetFlagID()
    219         slot.ChangeWarningDisplay(bool(self.GetFailedTypeID()))
    220         if itemKey is None or typeID is None:
    221             slot.HideModuleSlotFill()
    222             return
    223         if self.IsModulePreviewModule():
    224             slot.SetIconAsPreview()
    225         typeEffectInfo = ghostFittingSvc.GetDefaultAndOverheatEffect(typeID)
    226         currentStatus = ghostFittingSvc.GetModuleStatus(itemKey, typeID, flagID)
    227         if currentStatus is None:
    228             return
    229         if typeEffectInfo.defaultEffect and typeEffectInfo.isActivatable:
    230             if currentStatus == OVERHEATED:
    231                 slot.SetTexturePathForOverheated()
    232             else:
    233                 slot.SetTexurePathForActivatable()
    234         else:
    235             slot.SetTexturePathForPassive()
    236         if currentStatus == OFFLINE:
    237             slot.SetStatusDisplayOffline()
    238         elif currentStatus == ONLINE:
    239             slot.SetStatusDisplayOnline()
    240         elif currentStatus == ACTIVE:
    241             slot.SetStatusDisplayActive()
    242         elif currentStatus == OVERHEATED:
    243             slot.SetStatusDisplayOverheated()
    244 
    245     def ShowChargeInfo(self, *args):
    246         if self.GetCharge():
    247             sm.GetService('info').ShowInfo(self.GetCharge().typeID, self.GetCharge().itemID)
    248 
    249     def UpdateGhostFittingIcons(self, slot, invItem):
    250         if not self.IsSimulated() or not invItem:
    251             slot.HideGhostFittingElement()
    252 
    253     def GetCpuAndPowergridUsage(self):
    254         if not self.GetModuleID() or self.parentController is None:
    255             return
    256         cpu = self.dogmaLocation.GetAttributeValue(self.GetModuleID(), const.attributeCpu)
    257         powergrid = self.dogmaLocation.GetAttributeValue(self.GetModuleID(), const.attributePower)
    258         calibration = self.dogmaLocation.GetAttributeValue(self.GetModuleID(), const.attributeUpgradeCost)
    259         self.parentController.OnPreviewCPU(cpu, powergrid, calibration)
    260 
    261     def HideCpuAndPowergridUsage(self):
    262         if self.parentController:
    263             self.parentController.OnPreviewCPU(0, 0, 0)
    264 
    265     def ToggleOnlineModule(self):
    266         if not self.IsSimulated():
    267             return FittingSlotController.ToggleOnlineModule(self)
    268         if self.IsOnline():
    269             newState = OFFLINE
    270         else:
    271             newState = ONLINE
    272         ghostFittingSvc = sm.GetService('ghostFittingSvc')
    273         ghostFittingSvc.PerformActionAndSetNewState(newState, self.GetModuleID(), self.GetModuleTypeID(), self.GetFlagID())
    274         ghostFittingSvc.SendFittingSlotsChangedEvent()