locationDogmaItem.py (8332B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dogma\items\locationDogmaItem.py 2 from __future__ import absolute_import 3 from .baseDogmaItem import BaseDogmaItem 4 from dogma.const import attributeMaxGroupOnline, effectOnline 5 from eveexceptions import UserError 6 from eveexceptions.const import UE_GROUPID, UE_TYPEID 7 from utillib import strx 8 import weakref 9 from dogma import dogmaLogging as log 10 import sys 11 import inventorycommon.const as invconst 12 from ccpProfile import TimedFunction 13 14 class LocationDogmaItem(BaseDogmaItem): 15 16 @TimedFunction('LocationDogmaItem::__init__') 17 def __init__(self, dogmaLocation, item, eveCfg, clientIDFunc): 18 BaseDogmaItem.__init__(self, dogmaLocation, item, eveCfg, clientIDFunc) 19 self.fittedItems = {} 20 self.subLocations = {} 21 22 def Unload(self): 23 BaseDogmaItem.Unload(self) 24 self.dogmaLocation.LogInfo('LocationDogmaItem unloading subLocations') 25 for itemKey in self.subLocations.values(): 26 self.dogmaLocation.UnloadItem(itemKey) 27 28 if self in self.subLocations: 29 self.subLocations.remove(self) 30 self.dogmaLocation.LogInfo('LocationDogmaItem unloading fittedItems') 31 for itemKey in self.fittedItems.keys(): 32 self.dogmaLocation.UnloadItem(itemKey) 33 34 if self.itemID in self.fittedItems: 35 del self.fittedItems[self.itemID] 36 if self.itemID in self.dogmaLocation.moduleListsByShipGroup: 37 del self.dogmaLocation.moduleListsByShipGroup[self.itemID] 38 if self.itemID in self.dogmaLocation.moduleListsByShipType: 39 del self.dogmaLocation.moduleListsByShipType[self.itemID] 40 41 def OnItemLoaded(self): 42 self.dogmaLocation.LoadItemsInLocation(self.itemID) 43 self.dogmaLocation.LoadSublocations(self.itemID) 44 BaseDogmaItem.OnItemLoaded(self) 45 46 def PostLoadAction(self): 47 super(LocationDogmaItem, self).PostLoadAction() 48 self.dogmaLocation.CheckPowerCpuRequirementForOnlineModules(self.itemID) 49 self._EnforceMaxGroupOnline() 50 51 def ValidFittingFlag(self, flagID): 52 if invconst.flagLoSlot0 <= flagID <= invconst.flagHiSlot7: 53 return True 54 return False 55 56 def SetSubLocation(self, itemKey): 57 flagID = itemKey[1] 58 if flagID in self.subLocations: 59 log.LogTraceback('SetSubLocation used for subloc with flag %s' % strx(self.subLocations[flagID])) 60 self.subLocations[flagID] = itemKey 61 62 def RemoveSubLocation(self, itemKey): 63 flagID = itemKey[1] 64 subLocation = self.subLocations.get(flagID, None) 65 if subLocation is not None: 66 if subLocation != itemKey: 67 log.LogTraceback('RemoveSubLocation used for subloc with occupied flag %s' % strx((itemKey, subLocation))) 68 del self.subLocations[flagID] 69 70 def RegisterFittedItem(self, dogmaItem, flagID): 71 if self.ValidFittingFlag(flagID) or dogmaItem.itemID == self.itemID or flagID == invconst.flagPilot: 72 self.fittedItems[dogmaItem.itemID] = weakref.proxy(dogmaItem) 73 self.dogmaLocation.moduleListsByShipGroup[self.itemID][dogmaItem.groupID].add(dogmaItem.itemID) 74 self.dogmaLocation.moduleListsByShipType[self.itemID][dogmaItem.typeID].add(dogmaItem.itemID) 75 76 def UnregisterFittedItem(self, dogmaItem): 77 groupID = dogmaItem.groupID 78 typeID = dogmaItem.typeID 79 itemID = dogmaItem.itemID 80 try: 81 self.dogmaLocation.moduleListsByShipGroup[self.itemID][groupID].remove(itemID) 82 except KeyError: 83 self.dogmaLocation.LogError("UnregisterFittedItem::Tried to remove item from mlsg but group wasn't there", strx(dogmaItem)) 84 sys.exc_clear() 85 except IndexError: 86 self.dogmaLocation.LogError("UnregisterFittedItem::Tried to remove item from mlsg but it wasn't there", strx(dogmaItem)) 87 sys.exc_clear() 88 89 try: 90 self.dogmaLocation.moduleListsByShipType[self.itemID][typeID].remove(itemID) 91 except KeyError: 92 self.dogmaLocation.LogError("UnregisterFittedItem::Tried to remove item from mlsg but type wasn't there", strx(dogmaItem)) 93 sys.exc_clear() 94 except IndexError: 95 self.dogmaLocation.LogError("UnregisterFittedItem::Tried to remove item from mlsg but it wasn't there", strx(dogmaItem)) 96 sys.exc_clear() 97 98 try: 99 del self.fittedItems[dogmaItem.itemID] 100 except KeyError: 101 self.dogmaLocation.LogError("UnregisterFittedItem::Tried to remove item from fittedItems but it wasn't there", strx(dogmaItem)) 102 103 def GetFittedItems(self): 104 return self.fittedItems 105 106 def GetPersistables(self): 107 ret = BaseDogmaItem.GetPersistables(self) 108 ret.update(self.fittedItems.keys()) 109 return ret 110 111 def _FlushEffects(self): 112 stackTraceCount = 0 113 for fittedItem in self.fittedItems.itervalues(): 114 try: 115 if fittedItem.itemID == self.itemID: 116 continue 117 stackTraceCount += fittedItem.FlushEffects() 118 except ReferenceError as e: 119 self.dogmaLocation.LogWarn('Failed to _FlushEffects for a fitted dogmaitem that is no longer around - we should have cleaned this up') 120 log.LogException(channel='svc.dogmaIM') 121 sys.exc_clear() 122 123 stackTraceCount += BaseDogmaItem._FlushEffects(self) 124 return stackTraceCount 125 126 def GetCharacterID(self): 127 return self.GetPilot() 128 129 def CheckCanOnlineItem(self, itemID): 130 dogmaItem = self.dogmaLocation.GetItem(itemID) 131 groupID = dogmaItem.groupID 132 maxGroupOnline = self._GetLowestMaxGroupOnlineDict().get(groupID, None) 133 if maxGroupOnline is not None: 134 onlineModuleIDs = self._GetOnlineItemIDsInGroup(groupID) 135 try: 136 onlineModuleIDs.remove(itemID) 137 except ValueError: 138 pass 139 140 if len(onlineModuleIDs) >= maxGroupOnline: 141 raise UserError('CannotOnlineReachedMaxGroupOnline', {'type': (UE_TYPEID, dogmaItem.typeID), 142 'group': (UE_GROUPID, groupID), 143 'maxGroupOnline': maxGroupOnline}) 144 145 def EnforceMaxGroupOnlineForGroup(self, groupID): 146 maxGroupOnline = self._GetLowestMaxGroupOnlineDict().get(groupID, None) 147 if maxGroupOnline is not None: 148 self._OfflineExcessModulesInGroup(groupID, maxGroupOnline) 149 150 def _EnforceMaxGroupOnline(self): 151 maxGroupOnlineByGroupID = self._GetLowestMaxGroupOnlineDict() 152 for groupID, maxGroupOnline in maxGroupOnlineByGroupID.iteritems(): 153 self._OfflineExcessModulesInGroup(groupID, maxGroupOnline) 154 155 def _GetLowestMaxGroupOnlineDict(self): 156 maxGroupOnlineByGroupID = {} 157 fittedItems = self.GetFittedItems() 158 for moduleID, moduleDogmaItem in fittedItems.iteritems(): 159 if not self.dogmaLocation.TypeHasAttribute(moduleDogmaItem.typeID, attributeMaxGroupOnline): 160 continue 161 maxGroupOnline = int(self.dogmaLocation.GetAttributeValue(moduleID, attributeMaxGroupOnline)) 162 try: 163 currentGroupMinimum = maxGroupOnlineByGroupID[moduleDogmaItem.groupID] 164 except KeyError: 165 maxGroupOnlineByGroupID[moduleDogmaItem.groupID] = maxGroupOnline 166 else: 167 maxGroupOnlineByGroupID[moduleDogmaItem.groupID] = min(maxGroupOnline, currentGroupMinimum) 168 169 return maxGroupOnlineByGroupID 170 171 def _OfflineExcessModulesInGroup(self, groupID, maxGroupOnline): 172 onlineModuleIDs = self._GetOnlineItemIDsInGroup(groupID) 173 if len(onlineModuleIDs) > maxGroupOnline: 174 excessModuleIDs = onlineModuleIDs[maxGroupOnline:] 175 for moduleID in excessModuleIDs: 176 self.dogmaLocation.OfflineModule(moduleID) 177 178 def _GetOnlineItemIDsInGroup(self, groupID): 179 onlineItemIDs = [] 180 for itemID, dogmaItem in self.fittedItems.iteritems(): 181 if dogmaItem.groupID != groupID: 182 continue 183 if dogmaItem.IsOnline() and (itemID, effectOnline) not in self.dogmaLocation.deactivatingEffects: 184 onlineItemIDs.append(itemID) 185 186 return onlineItemIDs