invControllers.py (72536B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\invControllers.py 2 import sys 3 import mathext 4 import utillib 5 from brennivin.itertoolsext import Bundle 6 from collections import defaultdict 7 from corporation.client.goals.goalsController import CorpGoalsController 8 from player_messaging.client.ui_message import message_player, prompt_player_fsd_dialog 9 from eve.common.lib import appConst as const 10 from eve.common.script.mgt.fighterConst import TUBE_STATE_READY 11 from eve.common.script.sys import eveCfg, idCheckers 12 from eve.common.script.sys.eveCfg import InSpace 13 from eve.common.script.util import inventoryFlagsCommon 14 from eve.common.script.util.inventoryFlagsCommon import inventoryFlagData 15 from inventorycommon.util import GetItemVolume, IsFittingFlag, IsFittingModule, IsStructureServiceFlag 16 from inventoryrestrictions import is_tradable, can_be_added_to_container 17 from inventoryrestrictions import ItemCannotBeTraded, ItemCannotBeAddedToContainer 18 from eve.client.script.ui.util import uix 19 import carbonui.const as uiconst 20 import log 21 import localization 22 import telemetry 23 import evetypes 24 import inventorycommon.typeHelpers 25 import inventorycommon.const as invConst 26 from inventoryrestrictions import can_be_unfitted, ItemCannotBeUnfitted 27 from eve.client.script.ui.plex.textures import PLEX_128_GRADIENT_YELLOW 28 from eve.client.script.ui.util import utilWindows 29 from localization import GetByLabel 30 from plex.common.const import InvoiceType 31 from resourcewars.client.audioevents import on_not_enough_cargo_space 32 from spacecomponents.common.componentConst import CARGO_BAY, UNDER_CONSTRUCTION 33 from spacecomponents.common.data import get_space_component_for_type 34 from spacecomponents.common.helper import HasCargoBayComponent, HasUnderConstructionComponent 35 from player_messaging import IGNORE_TO_TOP 36 from vgs.common.listeners import PlexDepositListener 37 from carbon.common.script.sys.row import Row 38 from carbonui.uicore import uicore 39 from eveexceptions import UserError 40 from eveservices.menu import GetMenuService 41 LOOT_GROUPS = (const.groupWreck, 42 const.groupCargoContainer, 43 const.groupFreightContainer, 44 const.groupSpawnContainer, 45 const.groupSpewContainer, 46 const.groupDeadspaceOverseersBelongings, 47 const.groupMissionContainer, 48 const.groupAutoLooter, 49 const.groupMobileHomes) 50 LOOT_GROUPS_NOCLOSE = (const.groupAutoLooter, const.groupMobileHomes) 51 ZERO_CAPACITY = Row(['capacity', 'used'], [0, 0.0]) 52 53 def GetNameForFlag(flagID): 54 return localization.GetByLabel(inventoryFlagData[flagID]['name']) 55 56 57 class BaseInvContainer(object): 58 __guid__ = 'invCtrl.BaseInvContainer' 59 name = '' 60 iconName = 'res:/UI/Texture/Icons/3_64_13.png' 61 locationFlag = None 62 hasCapacity = False 63 oneWay = False 64 viewOnly = False 65 scope = None 66 isLockable = True 67 isMovable = True 68 filtersEnabled = True 69 typeID = None 70 acceptsDrops = True 71 isCompact = False 72 73 def __init__(self, itemID = None, typeID = None): 74 self.itemID = itemID 75 self.typeID = typeID 76 self.invID = (self.__class__.__name__, itemID) 77 78 def GetInvID(self): 79 return self.invID 80 81 def GetInventoryLocationID(self): 82 inventoryLocationID, _ = self.invID 83 return inventoryLocationID 84 85 def GetName(self): 86 return self.name 87 88 def GetNameWithLocation(self): 89 return localization.GetByLabel('UI/Inventory/BayAndLocationName', bayName=self.GetName(), locationName=cfg.evelocations.Get(self.itemID).name) 90 91 def GetIconName(self): 92 return self.iconName 93 94 @telemetry.ZONE_METHOD 95 def GetItems(self): 96 try: 97 return filter(self.IsItemHere, self._GetItems()) 98 except RuntimeError as e: 99 if e[0] == 'CharacterNotAtStation': 100 return [] 101 raise 102 103 @telemetry.ZONE_METHOD 104 def _GetItems(self): 105 if self.locationFlag: 106 return self._GetInvCacheContainer().List(flag=self.locationFlag) 107 else: 108 return self._GetInvCacheContainer().List() 109 110 def GetItemsByType(self, typeID): 111 return [ item for item in self.GetItems() if item.typeID == typeID ] 112 113 def GetItem(self, itemID): 114 for item in self.GetItems(): 115 if item.itemID == itemID: 116 return item 117 118 def GetScope(self): 119 return self.scope 120 121 def GetMenu(self): 122 return GetMenuService().InvItemMenu(self.GetInventoryItem()) 123 124 def _GetInvCacheContainer(self): 125 invCache = sm.GetService('invCache') 126 return invCache.GetInventoryFromId(self.itemID) 127 128 def GetInventoryItem(self): 129 item = sm.GetService('invCache').GetCachedItem(self.itemID) 130 if not item: 131 item = self._GetInvCacheContainer().GetItem() 132 return item 133 134 def GetTypeID(self): 135 if self.typeID is None: 136 self.typeID = self.GetInventoryItem().typeID 137 return self.typeID 138 139 def IsItemHere(self, item): 140 raise NotImplementedError('IsItemHere must be implemented') 141 142 def IsMovable(self): 143 return self.isMovable 144 145 def IsItemHereVolume(self, item): 146 return self.IsItemHere(item) 147 148 def IsInRange(self): 149 return True 150 151 def CheckCanQuery(self): 152 return True 153 154 def CheckCanTake(self): 155 return True 156 157 def IsPrimed(self): 158 return sm.GetService('invCache').IsInventoryPrimedAndListed(self.itemID) 159 160 def HasEnoughSpaceForItems(self, items): 161 volume = 0.0 162 for item in items: 163 volume += GetItemVolume(item) 164 165 cap = self.GetCapacity() 166 remainingVolume = cap.capacity - cap.used 167 return volume <= remainingVolume 168 169 def DoesAcceptItem(self, item): 170 if self.locationFlag and inventoryFlagsCommon.ShouldAllowAdd(self.locationFlag, item.categoryID, item.groupID, item.typeID) is not None: 171 return False 172 return True 173 174 def OnItemsViewed(self): 175 pass 176 177 def AddFightersFromTube(self, fighters): 178 fighterSvc = sm.GetService('fighters') 179 for fighter in fighters: 180 if fighter.squadronState == TUBE_STATE_READY: 181 fighterSvc.UnloadTubeToFighterBay(fighter.tubeFlagID) 182 183 def __AddItem(self, item, sourceLocationID, quantity): 184 itemID = item.itemID 185 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 186 stateMgr = sm.StartService('godma').GetStateManager() 187 dividing = quantity != item.stacksize 188 if self.IsItemHere(item): 189 if not dividing: 190 return 191 else: 192 if not self.CheckAndConfirmOneWayMove(): 193 return 194 if not self.CheckCanAdd(item.typeID, quantity): 195 return 196 if self.locationFlag: 197 item = stateMgr.GetItem(itemID) 198 if item and self.locationFlag in inventoryFlagData and IsFittingFlag(item.flagID): 199 if item.categoryID == const.categoryCharge: 200 return dogmaLocation.UnloadAmmoToContainer(item.locationID, item, (self.itemID, self.GetOwnerID(), self.locationFlag), quantity) 201 if IsFittingModule(item.categoryID): 202 return stateMgr.UnloadModuleToContainer(item.locationID, item.itemID, self._GetContainerArgs(), self.locationFlag) 203 else: 204 return self._GetInvCacheContainer().Add(itemID, sourceLocationID, qty=quantity, flag=self.locationFlag) 205 else: 206 typeID = self.GetTypeID() 207 if typeID and evetypes.GetGroupID(typeID) == const.groupAuditLogSecureContainer: 208 thisContainer = sm.GetService('invCache').GetInventoryFromId(self.itemID) 209 thisContainerItem = thisContainer.GetItem() 210 rolesAreNeeded = thisContainerItem is None or not idCheckers.IsStation(thisContainerItem.locationID) and thisContainerItem.locationID != session.shipid 211 if rolesAreNeeded: 212 config = thisContainer.ALSCConfigGet() 213 lockFlag = const.flagLocked if bool(config & const.ALSCLockAddedItems) else const.flagUnlocked 214 if lockFlag == const.flagLocked and session.corprole & const.corpRoleEquipmentConfig == 0: 215 if prompt_player_fsd_dialog('ConfirmAddLockedItemToAuditContainer', {}, uiconst.OKCANCEL) != uiconst.ID_OK: 216 return 217 return self._GetInvCacheContainer().Add(itemID, sourceLocationID, qty=quantity, flag=self.locationFlag) 218 219 def _AddItem(self, item, forceQuantity = False, sourceLocation = None): 220 locationID = session.locationid 221 maxQty = None 222 for i in xrange(2): 223 try: 224 if locationID != session.locationid: 225 return 226 itemQuantity = item.stacksize 227 if itemQuantity == 1: 228 quantity = 1 229 elif uicore.uilib.Key(uiconst.VK_SHIFT) or forceQuantity: 230 quantity = self.PromptUserForQuantity(item, itemQuantity, sourceLocation, maxQty) 231 else: 232 quantity = itemQuantity 233 if not item.itemID or not quantity: 234 return 235 if locationID != session.locationid: 236 return 237 if sourceLocation is None: 238 sourceLocation = item.locationID 239 return self.__AddItem(item, sourceLocation, quantity) 240 except UserError as what: 241 msgKey = what.args[0] 242 if msgKey in ('NotEnoughCargoSpace', 'NotEnoughCargoSpaceOverload', 'NotEnoughDroneBaySpace', 'NotEnoughDroneBaySpaceOverload', 'NoSpaceForThat', 'NoSpaceForThatOverload', 'NotEnoughChargeSpace', 'NotEnoughSpecialBaySpace', 'NotEnoughSpecialBaySpaceOverload', 'NotEnoughSpace', 'NotEnoughFighterBaySpace'): 243 try: 244 cap = self.GetCapacity() 245 except UserError: 246 raise what 247 248 free = cap.capacity - cap.used 249 if free < 0: 250 raise 251 if item.typeID == const.typePlasticWrap: 252 volume = sm.GetService('invCache').GetInventoryFromId(item.itemID).GetCapacity().used 253 else: 254 volume = GetItemVolume(item, 1) 255 maxQty = self._CalculateMaxQuantity(free, item, volume) 256 if maxQty <= 0: 257 if volume < 0.01: 258 req = 0.01 259 else: 260 req = volume 261 prompt_player_fsd_dialog('NotEnoughCargoSpaceFor1Unit', {'type': item.typeID, 262 'free': free, 263 'required': req}) 264 on_not_enough_cargo_space(self.typeID, item) 265 return 266 if self._DBLessLimitationsCheck(msgKey, item): 267 return 268 forceQuantity = 1 269 elif msgKey == 'CannotAddToQtyLimit': 270 maxQty = what.dict.get('maxToAdd', None) 271 if maxQty <= 0: 272 raise 273 forceQuantity = 1 274 else: 275 raise 276 sys.exc_clear() 277 278 def _CalculateMaxQuantity(self, free, item, volume): 279 numberOfItemsWeHaveRoomFor = int(round(free / (volume or 1), 7)) 280 maxQty = min(item.stacksize, numberOfItemsWeHaveRoomFor) 281 return maxQty 282 283 def PromptUserForQuantity(self, item, itemQuantity, sourceLocation = None, maxQtyAllowed = None): 284 if self.locationFlag is not None and item.flagID != self.locationFlag or item.locationID != getattr(self._GetInvCacheContainer(), 'itemID', None): 285 maxQtyFromAvailableSpace = None 286 if self.hasCapacity: 287 cap = self.GetCapacity() 288 capacity = cap.capacity - cap.used 289 itemvolume = GetItemVolume(item, 1) or 1 290 maxQtyFromAvailableSpace = int(capacity / itemvolume + 1e-07) 291 maxQty = min(filter(None, [itemQuantity, maxQtyAllowed, maxQtyFromAvailableSpace])) 292 if maxQty == itemQuantity: 293 errmsg = localization.GetByLabel('UI/Common/NoMoreUnits') 294 else: 295 errmsg = localization.GetByLabel('UI/Common/NoRoomForMore') 296 ret = uix.QtyPopup(int(maxQty), 0, int(maxQty), errmsg) 297 else: 298 caption = '%s: %s' % (localization.GetByLabel('UI/Inventory/ItemActions/DivideItemStack'), evetypes.GetName(item.typeID)) 299 ret = uix.QtyPopup(itemQuantity, 1, 1, None, caption) 300 if item.locationID != session.stationid: 301 if not sm.GetService('invCache').IsInventoryPrimedAndListed(item.locationID): 302 log.LogError('Item disappeared before we could add it', item) 303 return 304 if ret is not None: 305 return ret['qty'] 306 307 def MultiMerge(self, data, mergeSourceID): 308 mergeItem = data[0][3] 309 if mergeItem.locationID != self.itemID or mergeItem.flagID != self.locationFlag: 310 if not self.CheckAndConfirmOneWayMove(): 311 return 312 if not self.CheckCanAdd(typeID=mergeItem.typeID, quantity=data[0][2]): 313 return 314 try: 315 self._GetInvCacheContainer().MultiMerge([ (d[0], d[1], d[2]) for d in data ], mergeSourceID) 316 return True 317 except UserError as what: 318 if len(data) == 1 and what.args[0] in ('NotEnoughCargoSpace', 'NotEnoughCargoSpaceOverload', 'NotEnoughDroneBaySpace', 'NotEnoughDroneBaySpaceOverload', 'NoSpaceForThat', 'NoSpaceForThatOverload', 'NotEnoughChargeSpace', 'NotEnoughSpecialBaySpace', 'NotEnoughFighterBaySpace'): 319 cap = self.GetCapacity() 320 free = cap.capacity - cap.used 321 if free < 0: 322 raise 323 item = data[0][3] 324 if item.typeID == const.typePlasticWrap: 325 volume = sm.GetService('invCache').GetInventoryFromId(item.itemID).GetCapacity().used 326 else: 327 volume = GetItemVolume(item, 1) 328 maxQty = self._CalculateMaxQuantity(free, item, volume) 329 if maxQty <= 0: 330 if volume < 0.01: 331 req = 0.01 332 else: 333 req = volume 334 prompt_player_fsd_dialog('NotEnoughCargoSpaceFor1Unit', {'type': item.typeID, 335 'free': free, 336 'required': req}) 337 return 338 if self._DBLessLimitationsCheck(what.args[0], item): 339 return 340 if maxQty == item.stacksize: 341 errmsg = localization.GetByLabel('UI/Common/NoMoreUnits') 342 else: 343 errmsg = localization.GetByLabel('UI/Common/NoRoomForMore') 344 ret = uix.QtyPopup(int(maxQty), 0, int(maxQty), errmsg) 345 if ret is None: 346 quantity = None 347 else: 348 quantity = ret['qty'] 349 if quantity: 350 self._GetInvCacheContainer().MultiMerge([(data[0][0], data[0][1], quantity)], mergeSourceID) 351 return True 352 else: 353 raise 354 sys.exc_clear() 355 356 def StackAll(self, securityCode = None): 357 if not self.CheckAndConfirmOneWayMove(): 358 return 359 if self.locationFlag: 360 retval = self._GetInvCacheContainer().StackAll(self.locationFlag) 361 return retval 362 try: 363 if securityCode is None: 364 retval = self._GetInvCacheContainer().StackAll() 365 else: 366 retval = self._GetInvCacheContainer().StackAll(securityCode=securityCode) 367 return retval 368 except UserError as what: 369 if what.args[0] == 'PermissionDenied': 370 if securityCode: 371 caption = localization.GetByLabel('UI/Menusvc/IncorrectPassword') 372 label = localization.GetByLabel('UI/Menusvc/PleaseTryEnteringPasswordAgain') 373 else: 374 caption = localization.GetByLabel('UI/Menusvc/PasswordRequired') 375 label = localization.GetByLabel('UI/Menusvc/PleaseEnterPassword') 376 passw = utilWindows.NamePopup(caption=caption, label=label, setvalue='', icon=-1, modal=1, btns=None, maxLength=50, passwordChar='*') 377 if passw == '': 378 raise UserError(IGNORE_TO_TOP) 379 else: 380 retval = self.StackAll(securityCode=passw['name']) 381 return retval 382 else: 383 raise 384 sys.exc_clear() 385 386 def _DBLessLimitationsCheck(self, errorName, item): 387 return False 388 389 def GetCapacity(self): 390 try: 391 return self._GetInvCacheContainer().GetCapacity(self.locationFlag) 392 except RuntimeError as e: 393 if e[0] in ('CharacterNotAtStation', 'FakeItemNotFound'): 394 return ZERO_CAPACITY 395 raise 396 397 def get_capacity_ratio(self): 398 capacity = self.GetCapacity() 399 return mathext.round_to_significant(capacity.used / capacity.capacity, 2) 400 401 def GetOwnerID(self): 402 return self.GetInventoryItem().ownerID 403 404 def _GetContainerArgs(self): 405 return (self.itemID,) 406 407 def _ValidateMove(self, items): 408 forbiddenTypeIDs = set() 409 for item in items: 410 typeID = getattr(item, 'typeID', None) 411 flagID = getattr(item, 'flagID', None) 412 if all([typeID, flagID]) and flagID in invConst.fittingFlags and not can_be_unfitted(typeID): 413 forbiddenTypeIDs.add(typeID) 414 415 if forbiddenTypeIDs: 416 raise ItemCannotBeUnfitted(type_ids=forbiddenTypeIDs) 417 418 def OnDropData(self, nodes): 419 if not self.acceptsDrops: 420 return 421 items = [] 422 fighters = [] 423 lockedNodes = [ node for node in nodes if getattr(node, 'locked', False) ] 424 if lockedNodes: 425 for node in lockedNodes: 426 nodes.remove(node) 427 428 prompt_player_fsd_dialog('SomeLockedItemsNotMoved') 429 for node in nodes: 430 if self.CheckAndHandlePlexVaultItem(node): 431 continue 432 if getattr(node, '__guid__', None) in ('xtriui.ShipUIModule', 'xtriui.InvItem', 'listentry.InvItem', 'xtriui.FittingSlot'): 433 items.append(node.item) 434 from eve.client.script.ui.shared.inventory.treeData import TreeDataInv 435 if isinstance(node, TreeDataInv) and node.invController.IsMovable(): 436 items.append(node.invController.GetInventoryItem()) 437 if getattr(node, '__guid__', None) == 'uicls.FightersHealthGauge': 438 fighters.append(node) 439 440 self._ValidateMove(items) 441 if fighters: 442 return self.AddFightersFromTube(fighters) 443 return self.AddItems(items) 444 445 def CheckAndHandlePlexVaultItem(self, node): 446 isPlexVaultItem = hasattr(node, 'WithdrawPlex') and callable(node.WithdrawPlex) 447 if not isPlexVaultItem: 448 return False 449 if not self.DoesAcceptItem(node.item): 450 return False 451 node.WithdrawPlex(self) 452 return True 453 454 def AddItems(self, items): 455 if not self.CheckCanAddMultiple(items): 456 return 457 else: 458 sourceLocation = items[0].locationID 459 if self.itemID != sourceLocation and not sm.GetService('crimewatchSvc').CheckCanTakeItems(sourceLocation): 460 sm.GetService('crimewatchSvc').SafetyActivated(const.shipSafetyLevelPartial) 461 container = sm.GetService('invCache').GetInventoryFromId(sourceLocation) 462 raise UserError('LootTheftDeniedSafetyPreventsSuspect', {'containerName': (const.UE_TYPEID, container.typeID)}) 463 if session.shipid and self.itemID == session.shipid: 464 if self.itemID != sourceLocation and not sm.GetService('consider').ConfirmTakeIllicitGoods(items): 465 return 466 if not sm.GetService('invCache').AcceptPossibleRemovalTax(items): 467 return 468 if len(items) == 1: 469 item = items[0] 470 if hasattr(item, 'flagID') and IsFittingFlag(item.flagID): 471 if item.locationID == eveCfg.GetActiveShip(): 472 if not self.CheckAndConfirmOneWayMove(): 473 return 474 itemKey = item.itemID 475 locationID = item.locationID 476 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 477 containerArgs = self._GetContainerArgs() 478 if IsFittingModule(item.categoryID): 479 return dogmaLocation.UnloadModuleToContainer(locationID, itemKey, containerArgs, self.locationFlag) 480 if item.categoryID == const.categoryCharge: 481 ownerID = session.charid if self.locationFlag == const.flagHangar else self.GetOwnerID() 482 return dogmaLocation.UnloadAmmoToContainer(locationID, item, (containerArgs[0], ownerID, self.locationFlag)) 483 if IsStructureServiceFlag(item.flagID): 484 sm.GetService('structureControl').CheckCanDisableServiceModule(item) 485 from eve.client.script.util.eveMisc import GetRemoveServiceConfirmationQuestion 486 questionPath, params = GetRemoveServiceConfirmationQuestion(item.typeID) 487 ret = prompt_player_fsd_dialog(questionPath, params=params, buttons=uiconst.YESNO) 488 if ret != uiconst.ID_YES: 489 return 490 ret = self._AddItem(item, sourceLocation=sourceLocation) 491 if ret: 492 sm.ScatterEvent('OnClientEvent_MoveFromCargoToHangar', sourceLocation, self.itemID, self.locationFlag) 493 return ret 494 if not self.CheckAndConfirmOneWayMove(): 495 return 496 items.sort(key=lambda item: evetypes.GetVolume(item.typeID) * item.stacksize) 497 itemIDs = [ node.itemID for node in items ] 498 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 499 masters = dogmaLocation.GetAllSlaveModulesByMasterModule(sourceLocation) 500 if masters: 501 inBank = 0 502 for itemID in itemIDs: 503 if dogmaLocation.IsInWeaponBank(sourceLocation, itemID): 504 inBank = 1 505 break 506 507 if inBank: 508 ret = prompt_player_fsd_dialog('CustomQuestion', {'header': localization.GetByLabel('UI/Common/Confirm'), 509 'question': localization.GetByLabel('UI/Inventory/WeaponLinkUnfitMany')}, uiconst.YESNO) 510 if ret != uiconst.ID_YES: 511 return 512 for item in items: 513 if item.categoryID == const.categoryCharge and IsFittingFlag(item.flagID): 514 log.LogInfo('A module with a db item charge dropped from ship fitting into some container. Cannot use multimove, must remove charge first.') 515 ret = [self._AddItem(item)] 516 items.remove(item) 517 for item in items: 518 ret.append(self._AddItem(item)) 519 520 return ret 521 522 invCacheCont = self._GetInvCacheContainer() 523 if self.locationFlag: 524 ret = invCacheCont.MultiAdd(itemIDs, sourceLocation, flag=self.locationFlag) 525 else: 526 ret = invCacheCont.MultiAdd(itemIDs, sourceLocation, flag=const.flagNone) 527 if ret: 528 sm.ScatterEvent('OnClientEvent_MoveFromCargoToHangar', sourceLocation, self.itemID, self.locationFlag) 529 return ret 530 531 def SetCompactMode(self, isCompact): 532 self.isCompact = isCompact 533 534 def CheckAndConfirmOneWayMove(self): 535 if self.oneWay: 536 return self.PromptOneWayMove() 537 return True 538 539 def CheckCanAdd(self, typeID, quantity): 540 return True 541 542 def CheckCanAddMultiple(self, items): 543 if len(items) > 1: 544 items = filter(self.DoesAcceptItem, items) 545 quantityByType = defaultdict(int) 546 for item in items: 547 quantityByType[item.typeID] += item.stacksize 548 549 for typeID, quantity in quantityByType.items(): 550 if quantity > 0: 551 if not self.CheckCanAdd(typeID, quantity): 552 return False 553 554 if not items: 555 return False 556 return True 557 558 def PromptOneWayMove(self): 559 return prompt_player_fsd_dialog('ConfirmOneWayItemMove', {}, uiconst.OKCANCEL) == uiconst.ID_OK 560 561 def GetSpecialActions(self): 562 return [] 563 564 565 class ShipCargo(BaseInvContainer): 566 __guid__ = 'invCtrl.ShipCargo' 567 hasCapacity = True 568 locationFlag = const.flagCargo 569 570 def __init__(self, itemID = None, typeID = None): 571 self.itemID = itemID or eveCfg.GetActiveShip() 572 self.invID = (self.__class__.__name__, self.itemID) 573 self.name = localization.GetByLabel('UI/Common/CargoHold') 574 575 def GetMenu(self): 576 if self.itemID == session.shipid and InSpace(): 577 return GetMenuService().GetMenuFromItemIDTypeID(self.itemID, self.GetTypeID()) 578 else: 579 return BaseInvContainer.GetMenu(self) 580 581 def GetIconName(self, highliteIfActive = False): 582 if highliteIfActive and self.itemID == eveCfg.GetActiveShip(): 583 return 'res:/UI/Texture/Icons/1337_64_11.png' 584 else: 585 return 'res:/ui/Texture/WindowIcons/ships.png' 586 587 def GetScope(self): 588 if self.itemID == eveCfg.GetActiveShip(): 589 return uiconst.SCOPE_INGAME 590 return uiconst.SCOPE_DOCKED 591 592 def GetName(self): 593 return cfg.evelocations.Get(self.itemID).name 594 595 def _GetInvCacheContainer(self): 596 return sm.GetService('invCache').GetInventoryFromId(self.itemID, locationID=session.stationid) 597 598 def IsItemHere(self, item): 599 return item.locationID == self.itemID and item.flagID == self.locationFlag 600 601 602 class BaseShipBay(BaseInvContainer): 603 __guid__ = 'invCtrl.BaseShipBay' 604 hasCapacity = True 605 isMovable = False 606 607 def __init__(self, itemID = None, typeID = None): 608 super(BaseShipBay, self).__init__(itemID, typeID) 609 self.itemID = itemID or eveCfg.GetActiveShip() 610 611 def IsItemHere(self, item): 612 return item.locationID == self.itemID and item.flagID == self.locationFlag 613 614 def GetName(self): 615 return GetNameForFlag(self.locationFlag) 616 617 def GetScope(self): 618 if self.itemID == eveCfg.GetActiveShip(): 619 return uiconst.SCOPE_INGAME 620 else: 621 return uiconst.SCOPE_DOCKED 622 623 624 class ShipDroneBay(BaseShipBay): 625 __guid__ = 'invCtrl.ShipDroneBay' 626 iconName = 'res:/UI/Texture/WindowIcons/dronebay.png' 627 locationFlag = const.flagDroneBay 628 hasCapacity = True 629 scope = uiconst.SCOPE_DOCKED 630 631 632 class ShipFighterBay(BaseShipBay): 633 __guid__ = 'invCtrl.ShipFighterBay' 634 iconName = 'res:/UI/Texture/WindowIcons/dronebay.png' 635 locationFlag = const.flagFighterBay 636 hasCapacity = True 637 scope = uiconst.SCOPE_DOCKED 638 639 640 class ShipFrigateEscapeBay(BaseShipBay): 641 __guid__ = 'invCtrl.ShipFrigateEscapeBay' 642 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 643 locationFlag = const.flagFrigateEscapeBay 644 scope = uiconst.SCOPE_DOCKED 645 646 647 class ShipFuelBay(BaseShipBay): 648 __guid__ = 'invCtrl.ShipFuelBay' 649 locationFlag = const.flagSpecializedFuelBay 650 iconName = 'res:/UI/Texture/WindowIcons/fuelbay.png' 651 652 653 class ShipGeneralMiningHold(BaseShipBay): 654 __guid__ = 'invCtrl.ShipGeneralMiningHold' 655 locationFlag = const.flagGeneralMiningHold 656 iconName = 'res:/UI/Texture/WindowIcons/orehold.png' 657 658 659 class ShipAsteroidHold(BaseShipBay): 660 __guid__ = 'invCtrl.ShipAsteroidHold' 661 locationFlag = const.flagSpecialAsteroidHold 662 iconName = 'res:/UI/Texture/WindowIcons/orehold.png' 663 664 665 class ShipIceHold(BaseShipBay): 666 __guid__ = 'invCtrl.ShipIceHold' 667 locationFlag = const.flagSpecializedIceHold 668 iconName = 'res:/UI/Texture/WindowIcons/icehold.png' 669 670 671 class ShipGasHold(BaseShipBay): 672 __guid__ = 'invCtrl.ShipGasHold' 673 locationFlag = const.flagSpecializedGasHold 674 iconName = 'res:/UI/Texture/WindowIcons/gashold.png' 675 676 677 class ShipMineralHold(BaseShipBay): 678 __guid__ = 'invCtrl.ShipMineralHold' 679 locationFlag = const.flagSpecializedMineralHold 680 iconName = 'res:/UI/Texture/WindowIcons/mineralhold.png' 681 682 683 class ShipSalvageHold(BaseShipBay): 684 __guid__ = 'invCtrl.ShipSalvageHold' 685 locationFlag = const.flagSpecializedSalvageHold 686 iconName = 'res:/UI/Texture/WindowIcons/salvagehold.png' 687 688 689 class ShipShipHold(BaseShipBay): 690 __guid__ = 'invCtrl.ShipShipHold' 691 locationFlag = const.flagSpecializedShipHold 692 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 693 694 695 class ShipSmallShipHold(BaseShipBay): 696 __guid__ = 'invCtrl.ShipSmallShipHold' 697 locationFlag = const.flagSpecializedSmallShipHold 698 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 699 700 701 class ShipMediumShipHold(BaseShipBay): 702 __guid__ = 'invCtrl.ShipMediumShipHold' 703 locationFlag = const.flagSpecializedMediumShipHold 704 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 705 706 707 class ShipLargeShipHold(BaseShipBay): 708 __guid__ = 'invCtrl.ShipLargeShipHold' 709 locationFlag = const.flagSpecializedLargeShipHold 710 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 711 712 713 class ShipIndustrialShipHold(BaseShipBay): 714 __guid__ = 'invCtrl.ShipIndustrialShipHold' 715 locationFlag = const.flagSpecializedIndustrialShipHold 716 iconName = 'res:/UI/Texture/WindowIcons/shiphangar.png' 717 718 719 class ShipAmmoHold(BaseShipBay): 720 __guid__ = 'invCtrl.ShipAmmoHold' 721 locationFlag = const.flagSpecializedAmmoHold 722 iconName = 'res:/UI/Texture/WindowIcons/itemHangar.png' 723 724 725 class ShipCommandCenterHold(BaseShipBay): 726 __guid__ = 'invCtrl.ShipCommandCenterHold' 727 locationFlag = const.flagSpecializedCommandCenterHold 728 iconName = 'res:/UI/Texture/WindowIcons/commandcenterhold.png' 729 730 731 class ShipPlanetaryCommoditiesHold(BaseShipBay): 732 __guid__ = 'invCtrl.ShipPlanetaryCommoditiesHold' 733 locationFlag = const.flagSpecializedPlanetaryCommoditiesHold 734 iconName = 'res:/UI/Texture/WindowIcons/planetarycommodities.png' 735 736 737 class ShipQuafeHold(BaseShipBay): 738 __guid__ = 'invCtrl.ShipQuafeHold' 739 locationFlag = const.flagQuafeBay 740 741 742 class ShipCorpseHold(BaseShipBay): 743 __guid__ = 'invCtrl.ShipCorpseHold' 744 locationFlag = const.flagCorpseBay 745 746 747 class ShipBoosterHold(BaseShipBay): 748 __guid__ = 'invCtrl.ShipBoosterHold' 749 locationFlag = const.flagBoosterBay 750 751 752 class ShipSubsystemHold(BaseShipBay): 753 __guid__ = 'invCtrl.ShipSubsystemHold' 754 locationFlag = const.flagSubsystemBay 755 756 757 class ShipMobileDepotHold(BaseShipBay): 758 __guid__ = 'invCtrl.ShipMobileDepotHold' 759 locationFlag = const.flagMobileDepotHold 760 761 762 class ShipColonyResourcesHold(BaseShipBay): 763 __guid__ = 'invCtrl.ShipColonyResourcesHold' 764 locationFlag = const.flagColonyResourcesHold 765 766 767 class ShipExpeditionHold(BaseShipBay): 768 __guid__ = 'invCtrl.ShipExpeditionHold' 769 locationFlag = const.flagExpeditionHold 770 771 772 class BaseCorpContainer(BaseInvContainer): 773 __guid__ = 'invCtrl.BaseCorpContainer' 774 scope = uiconst.SCOPE_DOCKED 775 oneWay = True 776 isMovable = False 777 778 def __init__(self, itemID = None, divisionID = 0): 779 self.itemID = itemID 780 self.divisionID = self.roles = self.locationFlag = None 781 self.SetDivisionID(divisionID) 782 if self.roles is not None: 783 self.SetAccess() 784 self.invID = (self.__class__.__name__, self.itemID, divisionID) 785 self.goals = CorpGoalsController.get_instance() 786 787 def GetIconName(self): 788 if self.locationFlag == const.flagCorpGoalDeliveries: 789 return 'res:/UI/Texture/WindowIcons/goalDeliveries.png' 790 return 'res:/UI/Texture/WindowIcons/corporation.png' 791 792 def GetName(self): 793 if self.locationFlag == const.flagCorpGoalDeliveries: 794 return localization.GetByLabel('UI/Inventory/GoalDeliveriesHangar') 795 if self.divisionID is None: 796 return localization.GetByLabel('UI/Inventory/CorporationHangars') 797 divisions = sm.GetService('corp').GetDivisionNames() 798 return divisions[self.divisionID + 1] 799 800 def SetDivisionID(self, divisionID): 801 self.divisionID = divisionID 802 self.locationFlag = const.corpFlagByDivision.get(divisionID) 803 if self.locationFlag: 804 self.roles = (const.corpHangarQueryRolesByFlag[self.locationFlag], const.corpHangarTakeRolesByFlag[self.locationFlag]) 805 806 def _GetInvCacheContainer(self): 807 try: 808 officeID = sm.GetService('officeManager').GetCorpOfficeAtLocation().officeID 809 if officeID == self.itemID: 810 return sm.GetService('invCache').GetInventoryFromId(self.itemID) 811 except AttributeError: 812 pass 813 814 raise RuntimeError('Invalid inventory window.') 815 816 def IsItemHere(self, item): 817 ballpark = sm.GetService('michelle').GetBallpark() 818 return item.locationID == self.itemID and (item.ownerID == session.corpid or ballpark and item.ownerID == ballpark.slimItems[self.itemID].ownerID) and (self.locationFlag is None or item.flagID == self.locationFlag) and self.CheckCanQuery() 819 820 def CheckCanQuery(self): 821 if self.roles is None: 822 return True 823 role = self.roles[0] 824 if session.corprole & role == role: 825 return True 826 return False 827 828 def CheckCanTake(self): 829 if self.roles is None: 830 return True 831 role = self.roles[1] 832 if session.corprole & role == role: 833 return True 834 return False 835 836 def SetAccess(self): 837 role = self.roles[1] 838 if session.corprole & role == role: 839 self.viewOnly = False 840 else: 841 self.viewOnly = True 842 843 @telemetry.ZONE_METHOD 844 def GetItems(self): 845 if self.CheckCanQuery(): 846 return BaseInvContainer.GetItems(self) 847 else: 848 return [] 849 850 def CheckCanAdd(self, typeID, quantity): 851 return self._IsItemExpected(typeID, quantity) 852 853 def _IsItemExpected(self, typeID, quantity): 854 if self.locationFlag != const.flagCorpGoalDeliveries: 855 return True 856 try: 857 expectedItems = self.goals.get_items_pending_delivery(self.itemID) 858 except: 859 message_player(GetByLabel('UI/Corporations/Goals/FailedToConnect')) 860 raise 861 862 if typeID not in expectedItems: 863 raise UserError('CannotMoveTypeToGoalDeliveries', {'containerName': self.GetName(), 864 'corpName': cfg.eveowners.Get(session.corpid).name, 865 'item': typeID}) 866 expectedQuantity = expectedItems[typeID] 867 if quantity > expectedQuantity: 868 raise UserError('CannotMoveQuantityToGoalDeliveries', {'containerName': self.GetName(), 869 'corpName': cfg.eveowners.Get(session.corpid).name, 870 'item': typeID, 871 'quantity': quantity, 872 'expectedQuantity': expectedQuantity}) 873 return True 874 875 def CheckAndHandlePlexVaultItem(self, node): 876 isPlexVaultItem = hasattr(node, 'WithdrawPlex') and callable(node.WithdrawPlex) 877 if not isPlexVaultItem: 878 return False 879 if not self.DoesAcceptItem(node.item): 880 return False 881 if not self.CheckCanAdd(node.typeID, quantity=1): 882 return False 883 if not self.CheckAndConfirmOneWayMove(): 884 return False 885 node.WithdrawPlex(self) 886 return True 887 888 889 class StationCorpHangar(BaseCorpContainer): 890 __guid__ = 'invCtrl.StationCorpHangar' 891 hasCapacity = False 892 893 def __init__(self, itemID = None, divisionID = 0): 894 if itemID is None: 895 itemID = sm.GetService('officeManager').GetCorpOfficeAtLocation().officeID 896 BaseCorpContainer.__init__(self, itemID, divisionID) 897 898 def GetItems(self): 899 office = sm.GetService('officeManager').GetCorpOfficeAtLocation() 900 if office is None or office.officeID != self.itemID: 901 return [] 902 else: 903 return BaseCorpContainer.GetItems(self) 904 905 def GetCapacity(self): 906 if sm.GetService('officeManager').GetCorpOfficeAtLocation() is None: 907 return ZERO_CAPACITY 908 else: 909 return BaseCorpContainer.GetCapacity(self) 910 911 def GetMenu(self): 912 return [] 913 914 def IsInRange(self): 915 office = sm.GetService('officeManager').GetCorpOfficeAtLocation() 916 return office and office.officeID == self.itemID 917 918 919 class POSCorpHangar(BaseCorpContainer): 920 __guid__ = 'invCtrl.POSCorpHangar' 921 scope = uiconst.SCOPE_INFLIGHT 922 hasCapacity = True 923 924 def GetCapacity(self): 925 return self._GetInvCacheContainer().GetCapacity() 926 927 def OnItemsViewed(self): 928 settings.user.ui.Set('InvPOSCorpHangar_%s' % self.itemID, self.divisionID) 929 930 def IsInRange(self): 931 bp = sm.GetService('michelle').GetBallpark() 932 if bp is None: 933 return True 934 ball = bp.GetBall(self.itemID) 935 if not ball: 936 return False 937 item = sm.GetService('michelle').GetItem(self.itemID) 938 if item is None: 939 return False 940 operationalDistance = sm.GetService('godma').GetTypeAttribute(item.typeID, const.attributeMaxOperationalDistance) 941 if operationalDistance is None: 942 operationalDistance = const.maxCargoContainerTransferDistance 943 if ball.surfaceDist > operationalDistance: 944 if bp.IsShipInRangeOfStructureControlTower(session.shipid, self.itemID): 945 return True 946 return False 947 return True 948 949 def IsItemHereVolume(self, item): 950 return item.locationID == self.itemID and (item.ownerID == session.corpid or session.solarsystemid and item.ownerID == sm.GetService('michelle').GetBallpark().slimItems[self.itemID].ownerID) and self.CheckCanQuery() 951 952 def _GetInvCacheContainer(self): 953 return sm.GetService('invCache').GetInventoryFromId(self.itemID) 954 955 956 class StationCorpMember(BaseInvContainer): 957 __guid__ = 'invCtrl.StationCorpMember' 958 scope = uiconst.SCOPE_STATION 959 oneWay = True 960 viewOnly = True 961 locationFlag = const.flagHangar 962 iconName = 'res:/ui/Texture/WindowIcons/member.png' 963 964 def __init__(self, itemID = None, ownerID = None): 965 self.itemID = itemID 966 self.ownerID = ownerID 967 self.invID = (self.__class__.__name__, itemID, ownerID) 968 969 def GetName(self): 970 return localization.GetByLabel('UI/Station/Hangar/HangarNameWithOwner', charID=self.ownerID) 971 972 def _GetInvCacheContainer(self): 973 return sm.GetService('invCache').GetInventory(const.containerHangar, self.itemID) 974 975 def _GetContainerArgs(self): 976 return (const.containerHangar, self.itemID) 977 978 def IsItemHere(self, item): 979 return item.flagID == const.flagHangar and item.locationID == session.stationid and item.ownerID == self.ownerID 980 981 982 class StationCorpDeliveries(BaseInvContainer): 983 __guid__ = 'invCtrl.StationCorpDeliveries' 984 scope = uiconst.SCOPE_DOCKED 985 oneWay = True 986 locationFlag = const.flagCorpDeliveries 987 iconName = 'res:/UI/Texture/WindowIcons/corpdeliveries.png' 988 isMovable = False 989 acceptsDrops = False 990 991 def __init__(self, *args, **kwargs): 992 BaseInvContainer.__init__(self, *args, **kwargs) 993 self.name = localization.GetByLabel('UI/Inventory/CorpDeliveries') 994 995 def _GetInvCacheContainer(self): 996 return sm.GetService('invCache').GetInventory(const.containerCorpMarket, session.corpid) 997 998 def _GetContainerArgs(self): 999 return (const.containerCorpMarket, session.corpid) 1000 1001 def GetOwnerID(self): 1002 return session.corpid 1003 1004 def IsItemHere(self, item): 1005 return item.flagID == const.flagCorpDeliveries and item.locationID in (session.stationid, session.structureid) and item.ownerID == session.corpid 1006 1007 def DoesAcceptItem(self, item): 1008 return False 1009 1010 1011 class CapsuleerDeliveries(BaseInvContainer): 1012 __guid__ = 'invCtrl.CorporationItemDeliveries' 1013 scope = uiconst.SCOPE_DOCKED 1014 oneWay = True 1015 locationFlag = const.flagCapsuleerDeliveries 1016 iconName = 'res:/UI/Texture/WindowIcons/goalDeliveries.png' 1017 isMovable = False 1018 acceptsDrops = False 1019 1020 def __init__(self, *args, **kwargs): 1021 BaseInvContainer.__init__(self, *args, **kwargs) 1022 self.name = localization.GetByLabel('UI/Corporations/DeliverItem/CapsuleerDeliveries') 1023 1024 def _GetInvCacheContainer(self): 1025 return sm.GetService('invCache').GetInventory(const.containerCapsuleerDeliveries, session.corpid) 1026 1027 def _GetContainerArgs(self): 1028 return (const.containerCapsuleerDeliveries, session.corpid) 1029 1030 def GetOwnerID(self): 1031 return session.corpid 1032 1033 def IsItemHere(self, item): 1034 return item.flagID == const.flagCapsuleerDeliveries and item.locationID in (session.stationid, session.structureid) and item.ownerID == session.corpid 1035 1036 def OnDropData(self, nodes): 1037 message_player(localization.GetByLabel('UI/Corporations/DeliverItem/NotStorage')) 1038 1039 def DoesAcceptItem(self, item): 1040 return False 1041 1042 1043 class AssetSafetyDeliveries(BaseInvContainer): 1044 __guid__ = 'invCtrl.AssetSafetyDeliveries' 1045 scope = uiconst.SCOPE_DOCKED 1046 acceptsDrops = False 1047 locationFlag = const.flagAssetSafety 1048 iconName = 'res:/UI/Texture/WindowIcons/personalDeliveries.png' 1049 isMovable = False 1050 1051 def __init__(self, *args, **kwargs): 1052 BaseInvContainer.__init__(self, *args, **kwargs) 1053 1054 def _GetInvCacheContainer(self): 1055 return sm.GetService('invCache').GetInventory(const.containerHangar) 1056 1057 def _GetContainerArgs(self): 1058 return (const.containerHangar,) 1059 1060 def IsItemHere(self, item): 1061 return item.flagID == const.flagAssetSafety and item.locationID in (session.stationid, session.structureid) and (item.ownerID == session.charid or item.ownerID == session.corpid and session.corprole & const.corpRoleDirector) 1062 1063 def GetMenu(self): 1064 return [] 1065 1066 1067 class StationItems(BaseInvContainer): 1068 __guid__ = 'invCtrl.StationItems' 1069 locationFlag = const.flagHangar 1070 scope = uiconst.SCOPE_DOCKED 1071 iconName = 'res:/ui/Texture/WindowIcons/itemHangar.png' 1072 isMovable = False 1073 1074 def __init__(self, *args, **kwargs): 1075 BaseInvContainer.__init__(self, *args, **kwargs) 1076 self.name = localization.GetByLabel('UI/Inventory/ItemHangar') 1077 1078 @telemetry.ZONE_METHOD 1079 def IsItemHere(self, item): 1080 return item.locationID == session.stationid and item.ownerID == session.charid and item.flagID == const.flagHangar and item.categoryID != const.categoryShip 1081 1082 def _GetInvCacheContainer(self): 1083 return sm.GetService('invCache').GetInventory(const.containerHangar) 1084 1085 def _GetContainerArgs(self): 1086 return (const.containerHangar,) 1087 1088 def IsPrimed(self): 1089 return self.IsInRange() 1090 1091 def IsInRange(self): 1092 return session.stationid and self.itemID == session.stationid 1093 1094 1095 class RedeemItems(BaseInvContainer): 1096 __guid__ = 'invCtrl.RedeemItems' 1097 locationFlag = const.flagHangar 1098 scope = uiconst.SCOPE_DOCKED 1099 isMovable = False 1100 viewOnly = True 1101 1102 def __init__(self, *args, **kwargs): 1103 BaseInvContainer.__init__(self, *args, **kwargs) 1104 1105 def __AddItem(self, item, sourceLocationID, quantity): 1106 sourceFlagID = item.flagID 1107 dropLocationID = self._GetInvCacheContainer().GetItem().itemID 1108 isDropInSameLocation = dropLocationID == sourceLocationID and sourceFlagID == self.locationFlag 1109 isDividing = quantity != item.stacksize 1110 if isDropInSameLocation and not isDividing: 1111 return 1112 super(RedeemItems, self).__AddItem(item, sourceLocationID, quantity) 1113 1114 def _GetItems(self): 1115 self.redeemSvc = sm.GetService('redeem') 1116 self.tokens = self.redeemSvc.GetRedeemTokens() 1117 self.items = [] 1118 for token in self.tokens: 1119 tokenID = int(token.tokenID) if token.tokenID else None 1120 typeID = int(token.typeID) 1121 massTokenID = int(token.massTokenID) if token.massTokenID else None 1122 categoryID = evetypes.GetCategoryID(typeID) 1123 isAutoInject = self.redeemSvc.redeemData.is_auto_injected(token) 1124 blueprintInfo = None 1125 if categoryID == invConst.categoryBlueprint: 1126 blueprintInfo = Bundle(isCopy=True, runs=token.blueprintRuns or 1, materialEfficiency=token.blueprintMaterialLevel, timeEfficiency=token.blueprintProductivityLevel) 1127 qty = token.quantity * evetypes.GetPortionSize(typeID) 1128 item = Bundle(itemID=tokenID, typeID=typeID, ownerID=session.charid, locationID=session.stationid or session.structureid or session.solarsystemid, flagID=int(self.locationFlag), quantity=qty, categoryID=categoryID, groupID=evetypes.GetGroupID(typeID), customInfo=None, stacksize=qty, singleton=None, tokenID=tokenID, massTokenID=massTokenID, stationID=token.stationID, expireDateTime=token.expireDateTime, description=self.redeemSvc.GetTokenDescription(token) or self.redeemSvc.GetTokenLabel(token), dateTime=token.dateTime, blueprintInfo=blueprintInfo, isAutoInject=isAutoInject) 1129 self.items.append(item) 1130 1131 return self.items 1132 1133 def IsItemHere(self, item): 1134 if not item: 1135 return False 1136 if session.charid: 1137 return item.ownerID == session.charid 1138 return True 1139 1140 def GetInventoryItem(self): 1141 return None 1142 1143 1144 class StationShips(BaseInvContainer): 1145 __guid__ = 'invCtrl.StationShips' 1146 iconName = 'res:/ui/Texture/WindowIcons/shiphangar.png' 1147 scope = uiconst.SCOPE_DOCKED 1148 locationFlag = const.flagHangar 1149 isMovable = False 1150 1151 def __init__(self, *args, **kwargs): 1152 BaseInvContainer.__init__(self, *args, **kwargs) 1153 self.name = localization.GetByLabel('UI/Inventory/ShipHangar') 1154 1155 @telemetry.ZONE_METHOD 1156 def IsItemHere(self, item): 1157 return item.locationID == session.stationid and item.ownerID == session.charid and item.flagID == const.flagHangar and item.categoryID == const.categoryShip 1158 1159 def GetActiveShip(self): 1160 activeShipID = eveCfg.GetActiveShip() 1161 for item in self._GetItems(): 1162 if item.itemID == activeShipID: 1163 return item 1164 1165 def _GetInvCacheContainer(self): 1166 return sm.GetService('invCache').GetInventory(const.containerHangar) 1167 1168 def _GetContainerArgs(self): 1169 return (const.containerHangar,) 1170 1171 def IsPrimed(self): 1172 return self.IsInRange() 1173 1174 def IsInRange(self): 1175 return session.stationid and self.itemID == session.stationid 1176 1177 1178 class CustomsOffice(BaseInvContainer): 1179 __guid__ = 'invCtrl.CustomsOffice' 1180 isMovable = False 1181 1182 1183 LOOT_ALL_BUTTON_NAME = 'invLootAllBtn' 1184 1185 class BaseCelestialContainer(BaseInvContainer): 1186 __guid__ = 'invCtrl.BaseCelestialContainer' 1187 hasCapacity = True 1188 isMovable = False 1189 1190 def __init__(self, *args, **kwargs): 1191 BaseInvContainer.__init__(self, *args, **kwargs) 1192 self._isLootable = None 1193 1194 def IsItemHere(self, item): 1195 if self.locationFlag is not None: 1196 return item.locationID == self.itemID and item.flagID == self.locationFlag 1197 else: 1198 return item.locationID == self.itemID 1199 1200 def IsInRange(self): 1201 bp = sm.GetService('michelle').GetBallpark() 1202 if bp is None or not InSpace(): 1203 return True 1204 ball = bp.GetBall(self.itemID) 1205 if not ball: 1206 return False 1207 item = sm.GetService('michelle').GetItem(self.itemID) 1208 if item is None: 1209 return False 1210 if ball.surfaceDist > self.GetOperationalDistance(item.typeID): 1211 if bp.IsShipInRangeOfStructureControlTower(session.shipid, self.itemID): 1212 return True 1213 return False 1214 return True 1215 1216 def GetOperationalDistance(self, typeID): 1217 distance = sm.GetService('godma').GetTypeAttribute(typeID, const.attributeMaxOperationalDistance) 1218 if distance is None: 1219 distance = const.maxCargoContainerTransferDistance 1220 return distance 1221 1222 def GetIconName(self): 1223 try: 1224 typeID = self.GetTypeID() 1225 except UserError: 1226 return self.iconName 1227 1228 if typeID: 1229 icon = inventorycommon.typeHelpers.GetIcon(typeID) 1230 if icon and icon.iconFile: 1231 return icon.iconFile 1232 return self.iconName 1233 1234 def GetTypeID(self): 1235 if self.typeID is not None: 1236 return self.typeID 1237 bp = sm.GetService('michelle').GetBallpark() 1238 if bp and self.itemID in bp.slimItems: 1239 slimItem = bp.slimItems[self.itemID] 1240 self.typeID = slimItem.typeID 1241 else: 1242 self.typeID = BaseInvContainer.GetTypeID(self) 1243 return self.typeID 1244 1245 def GetName(self): 1246 if self.name: 1247 return self.name 1248 bp = sm.GetService('michelle').GetBallpark() 1249 if bp: 1250 slimItem = bp.slimItems.get(self.itemID, None) 1251 if slimItem: 1252 return uix.GetSlimItemName(slimItem) 1253 return '' 1254 1255 def _DBLessLimitationsCheck(self, errorName, item): 1256 if errorName in ('NotEnoughCargoSpace', 'NotEnoughCargoSpaceOverload'): 1257 prompt_player_fsd_dialog('ItemMoveGoesThroughFullCargoHold', {'itemType': item.typeID}) 1258 return True 1259 return False 1260 1261 def GetMenu(self): 1262 return GetMenuService().GetMenuFromItemIDTypeID(self.itemID, self.GetTypeID()) 1263 1264 def GetSpecialActions(self): 1265 if self.IsLootable(): 1266 return [(localization.GetByLabel('UI/Inventory/LootAll'), 1267 self.LootAll, 1268 LOOT_ALL_BUTTON_NAME, 1269 True)] 1270 return [] 1271 1272 def LootAll(self, *args): 1273 items = self.GetItems() 1274 shipCargo = ShipCargo() 1275 if len(items) > 0: 1276 if sm.GetService('crimewatchSvc').CheckCanTakeItems(self.itemID): 1277 if sm.GetService('consider').ConfirmTakeIllicitGoods(items): 1278 shipCargo.AddItems(items) 1279 sm.GetService('audio').SendUIEvent('ui_notify_mission_rewards_play') 1280 else: 1281 sm.GetService('crimewatchSvc').SafetyActivated(const.shipSafetyLevelPartial) 1282 raise UserError('LootTheftDeniedSafetyPreventsSuspect', {'containerName': (const.UE_TYPEID, self.GetTypeID())}) 1283 if shipCargo.HasEnoughSpaceForItems(items): 1284 sm.ScatterEvent('OnWreckLootAll', self.GetInvID(), items) 1285 1286 def IsLootable(self): 1287 if self._isLootable is None: 1288 bp = sm.GetService('michelle').GetBallpark() 1289 item = bp.GetInvItem(self.itemID) if bp else None 1290 if item and item.groupID in LOOT_GROUPS: 1291 self._isLootable = True 1292 else: 1293 self._isLootable = False 1294 return self._isLootable 1295 1296 1297 class POSRefinery(BaseCelestialContainer): 1298 __guid__ = 'invCtrl.POSRefinery' 1299 locationFlag = const.flagCargo 1300 iconName = 'res:/UI/Texture/Icons/24_64_1.png' 1301 1302 1303 class POSCompression(BaseCelestialContainer): 1304 __guid__ = 'invCtrl.POSCompression' 1305 locationFlag = const.flagCargo 1306 iconName = 'res:/UI/Texture/Icons/24_64_1.png' 1307 1308 1309 class POSStructureCharges(BaseCelestialContainer): 1310 __guid__ = 'invCtrl.POSStructureCharges' 1311 locationFlag = const.flagHiSlot0 1312 1313 def GetIconName(self): 1314 typeID = self.GetTypeID() 1315 groupID = evetypes.GetGroupID(typeID) 1316 if groupID == const.groupMobileHybridSentry: 1317 return 'res:/UI/Texture/Icons/13_64_5.png' 1318 elif groupID == const.groupMobileMissileSentry: 1319 return 'res:/UI/Texture/Icons/12_64_16.png' 1320 elif groupID == const.groupMobileProjectileSentry: 1321 return 'res:/UI/Texture/Icons/12_64_9.png' 1322 else: 1323 return BaseCelestialContainer.GetIconName(self) 1324 1325 1326 class POSStructureChargeCrystal(POSStructureCharges): 1327 __guid__ = 'invCtrl.POSStructureChargeCrystal' 1328 iconName = 'res:/UI/Texture/Icons/8_64_2.png' 1329 1330 def __init__(self, *args, **kwargs): 1331 POSStructureCharges.__init__(self, *args, **kwargs) 1332 self.name = localization.GetByLabel('UI/Inventory/ActiveCrystal') 1333 1334 1335 class POSStructureChargesStorage(BaseCelestialContainer): 1336 __guid__ = 'invCtrl.POSStructureChargesStorage' 1337 locationFlag = const.flagNone 1338 iconName = 'res:/UI/Texture/Icons/8_64_1.png' 1339 1340 def __init__(self, *args, **kwargs): 1341 BaseCelestialContainer.__init__(self, *args, **kwargs) 1342 self.name = localization.GetByLabel('UI/Inventory/CrystalStorage') 1343 1344 1345 class POSStrontiumBay(BaseCelestialContainer): 1346 __guid__ = 'invCtrl.POSStrontiumBay' 1347 locationFlag = const.flagSecondaryStorage 1348 iconName = 'res:/UI/Texture/Icons/51_64_10.png' 1349 1350 def __init__(self, *args, **kwargs): 1351 BaseCelestialContainer.__init__(self, *args, **kwargs) 1352 self.name = localization.GetByLabel('UI/Inventory/StrontiumBay') 1353 1354 1355 class POSFuelBay(BaseCelestialContainer): 1356 __guid__ = 'invCtrl.POSFuelBay' 1357 locationFlag = const.flagNone 1358 iconName = 'res:/UI/Texture/Icons/98_64_9.png' 1359 1360 def __init__(self, *args, **kwargs): 1361 BaseCelestialContainer.__init__(self, *args, **kwargs) 1362 self.name = localization.GetByLabel('UI/Ship/FuelBay') 1363 1364 def PromptUserForQuantity(self, item, itemQuantity, sourceLocation, maxQtyAllowed = None): 1365 if sourceLocation == self.itemID: 1366 return None 1367 return BaseCelestialContainer.PromptUserForQuantity(self, item, itemQuantity) 1368 1369 1370 class POSShipMaintenanceArray(BaseCelestialContainer): 1371 __guid__ = 'invCtrl.POSShipMaintenanceArray' 1372 locationFlag = const.flagNone 1373 iconName = 'res:/ui/Texture/WindowIcons/settings.png' 1374 1375 1376 class POSPersonalHangar(BaseCelestialContainer): 1377 __guid__ = 'invCtrl.POSPersonalHangar' 1378 locationFlag = const.flagHangar 1379 iconName = 'res:/ui/Texture/WindowIcons/itemHangar.png' 1380 1381 def IsItemHere(self, item): 1382 return BaseCelestialContainer.IsItemHere(self, item) and session.charid == item.ownerID 1383 1384 def GetCapacity(self): 1385 cap = BaseCelestialContainer.GetCapacity(self) 1386 totalVolume = 0 1387 for item in self.GetItems(): 1388 totalVolume += GetItemVolume(item) 1389 1390 return utillib.KeyVal(capacity=cap.capacity, used=totalVolume) 1391 1392 1393 class POSMobileReactor(BaseCelestialContainer): 1394 __guid__ = 'invCtrl.POSMobileReactor' 1395 locationFlag = const.flagNone 1396 iconName = 'res:/UI/Texture/Icons/27_64_11.png' 1397 1398 def PromptUserForQuantity(self, item, itemQuantity, sourceLocation, maxQtyAllowed = None): 1399 if sourceLocation == self.itemID: 1400 return None 1401 return BaseCelestialContainer.PromptUserForQuantity(self, item, itemQuantity) 1402 1403 1404 class POSSilo(BaseCelestialContainer): 1405 __guid__ = 'invCtrl.POSSilo' 1406 locationFlag = const.flagNone 1407 iconName = 'res:/UI/Texture/Icons/26_64_12.png' 1408 1409 def PromptUserForQuantity(self, item, itemQuantity, sourceLocation, maxQtyAllowed = None): 1410 if sourceLocation == self.itemID: 1411 return None 1412 return BaseCelestialContainer.PromptUserForQuantity(self, item, itemQuantity) 1413 1414 1415 class ItemFloatingCargo(BaseCelestialContainer): 1416 __guid__ = 'invCtrl.ItemFloatingCargo' 1417 iconName = 'res:/UI/Texture/Shared/Brackets/containerCargo_20x20.png' 1418 1419 def GetIconName(self): 1420 return self.iconName 1421 1422 def GetItems(self): 1423 sm.GetService('wreck').MarkViewed(self.itemID, True) 1424 return BaseCelestialContainer.GetItems(self) 1425 1426 1427 class ShipMaintenanceBay(BaseCelestialContainer): 1428 __guid__ = 'invCtrl.ShipMaintenanceBay' 1429 locationFlag = const.flagShipHangar 1430 iconName = 'res:/ui/Texture/WindowIcons/settings.png' 1431 1432 def GetName(self): 1433 bayName = GetNameForFlag(self.locationFlag) 1434 if session.solarsystemid and self.itemID != eveCfg.GetActiveShip(): 1435 return localization.GetByLabel('UI/Inventory/BayAndLocationName', bayName=evetypes.GetName(self.GetTypeID()), locationName=bayName) 1436 return bayName 1437 1438 def GetOperationalDistance(self, *args): 1439 return const.maxCargoContainerTransferDistance 1440 1441 1442 class ShipFleetHangar(BaseCelestialContainer): 1443 __guid__ = 'invCtrl.ShipFleetHangar' 1444 locationFlag = const.flagFleetHangar 1445 iconName = 'res:/ui/Texture/WindowIcons/fleet.png' 1446 1447 def GetName(self): 1448 bayName = GetNameForFlag(self.locationFlag) 1449 if session.solarsystemid and self.itemID != eveCfg.GetActiveShip(): 1450 return localization.GetByLabel('UI/Inventory/BayAndLocationName', bayName=evetypes.GetName(self.GetTypeID()), locationName=bayName) 1451 return bayName 1452 1453 def GetOperationalDistance(self, *args): 1454 return const.maxCargoContainerTransferDistance 1455 1456 1457 class StationContainer(BaseCelestialContainer): 1458 __guid__ = 'invCtrl.StationContainer' 1459 hasCapacity = True 1460 isMovable = True 1461 1462 def __init__(self, *args, **kwargs): 1463 BaseCelestialContainer.__init__(self, *args, **kwargs) 1464 self._oneWay = None 1465 self.invItem = None 1466 1467 @property 1468 def oneWay(self): 1469 if self._oneWay is not None: 1470 return self._oneWay 1471 if self.invItem is None: 1472 try: 1473 self.invItem = self.GetInventoryItem() 1474 except Exception: 1475 self._oneWay = super(StationContainer, self).oneWay 1476 return self._oneWay 1477 1478 if self.invItem.ownerID == session.corpid and self.invItem.flagID in invConst.flagCorpSAGs: 1479 self._oneWay = True 1480 return self._oneWay 1481 1482 def GetMenu(self): 1483 return GetMenuService().InvItemMenu(self.GetInventoryItem()) 1484 1485 def GetName(self): 1486 name = cfg.evelocations.Get(self.itemID).name 1487 if not name: 1488 name = evetypes.GetName(self.GetTypeID()) 1489 return name 1490 1491 def IsInRange(self): 1492 return True 1493 1494 def CheckAndConfirmOneWayMove(self): 1495 if self.oneWay: 1496 return self.PromptOneWayMove() 1497 if session.solarsystemid: 1498 invItem = self.GetInventoryItem() 1499 bp = sm.GetService('michelle').GetBallpark() 1500 if bp: 1501 ball = bp.GetBallById(invItem.locationID) 1502 if ball and evetypes.GetGroupID(ball.typeID) in (const.groupCorporateHangarArray, const.groupAssemblyArray, const.groupMobileLaboratory): 1503 return self.PromptOneWayMove() 1504 if invItem.flagID == const.flagFleetHangar and invItem.ownerID != session.charid: 1505 return self.PromptOneWayMove() 1506 return True 1507 1508 def AddItems(self, items): 1509 allowedItems = [] 1510 forbiddenTypes = set() 1511 for item in items: 1512 typeID = item.typeID 1513 if can_be_added_to_container(typeID, self.typeID): 1514 allowedItems.append(item) 1515 else: 1516 forbiddenTypes.add(typeID) 1517 1518 if forbiddenTypes: 1519 raise ItemCannotBeAddedToContainer(type_ids=forbiddenTypes) 1520 super(StationContainer, self).AddItems(allowedItems) 1521 1522 1523 class AssetSafetyContainer(StationContainer): 1524 __guid__ = 'invCtrl.AssetSafetyContainer' 1525 scope = uiconst.SCOPE_DOCKED 1526 isMovable = False 1527 1528 def __init__(self, itemID = None, typeID = None, name = None): 1529 StationContainer.__init__(self, itemID, typeID) 1530 self.name = name 1531 1532 def GetName(self): 1533 return self.name or '' 1534 1535 def IsItemHere(self, item): 1536 return item.locationID == self.itemID 1537 1538 1539 class ItemWreck(BaseCelestialContainer): 1540 __guid__ = 'invCtrl.ItemWreck' 1541 hasCapacity = False 1542 1543 def GetIconName(self): 1544 slimItem = sm.GetService('michelle').GetBallpark().slimItems[self.itemID] 1545 return sm.GetService('bracket').GetBracketIcon(slimItem.typeID, slimItem.isEmpty) 1546 1547 @telemetry.ZONE_METHOD 1548 def GetItems(self): 1549 sm.GetService('wreck').MarkViewed(self.itemID, True, True) 1550 return BaseCelestialContainer.GetItems(self) 1551 1552 1553 class PlayerTrade(BaseInvContainer): 1554 __guid__ = 'invCtrl.PlayerTrade' 1555 scope = uiconst.SCOPE_DOCKED 1556 viewOnly = True 1557 hasCapacity = False 1558 isLockable = False 1559 filtersEnabled = False 1560 isMovable = False 1561 1562 def __init__(self, itemID = None, ownerID = None, tradeSession = None): 1563 self.itemID = itemID 1564 self.ownerID = ownerID 1565 self.tradeSession = tradeSession 1566 self.invID = (self.__class__.__name__, itemID, ownerID) 1567 1568 def _GetItems(self): 1569 return [ item for item in self.tradeSession.List().items ] 1570 1571 def IsItemHere(self, item): 1572 return item.ownerID == self.ownerID and self.itemID == item.locationID 1573 1574 def GetOwnerID(self): 1575 return self.ownerID 1576 1577 def AddItems(self, items): 1578 activeShipID = eveCfg.GetActiveShip() 1579 nonTradableTypes = set() 1580 for item in items: 1581 if item.itemID == activeShipID: 1582 raise UserError('PeopleAboardShip') 1583 if item.typeID == const.typeAssetSafetyWrap: 1584 raise UserError('CannotTradeAssetSafety') 1585 if not is_tradable(item.typeID): 1586 nonTradableTypes.add(item.typeID) 1587 1588 if nonTradableTypes: 1589 raise ItemCannotBeTraded(type_ids=nonTradableTypes) 1590 BaseInvContainer.AddItems(self, items) 1591 1592 def _GetInvCacheContainer(self): 1593 self.tradeSession.GetItem = self.tradeSession.GetSelfInvItem 1594 return self.tradeSession 1595 1596 1597 class SpaceComponentInventory(BaseCelestialContainer): 1598 __guid__ = 'invCtrl.SpaceComponentInventory' 1599 iconName = 'res:/ui/Texture/WindowIcons/itemHangar.png' 1600 locationFlag = const.flagCargo 1601 1602 def GetMenu(self): 1603 return GetMenuService().CelestialMenu(self.itemID) 1604 1605 def _GetAcceptedCargoBayTypeIDs(self): 1606 myTypeID = self.GetTypeID() 1607 if HasCargoBayComponent(myTypeID): 1608 cargo_bay = get_space_component_for_type(myTypeID, CARGO_BAY) 1609 return cargo_bay.acceptedTypeIDs 1610 1611 def DoesAcceptItem(self, item): 1612 if not BaseCelestialContainer.DoesAcceptItem(self, item): 1613 return False 1614 acceptedTypeIDs = self._GetAcceptedCargoBayTypeIDs() 1615 if acceptedTypeIDs is not None and item.typeID not in acceptedTypeIDs: 1616 return False 1617 return True 1618 1619 def HasUnderConstructionComponent(self): 1620 return HasUnderConstructionComponent(self.GetTypeID()) 1621 1622 def GetInputItems(self): 1623 if self.HasUnderConstructionComponent(): 1624 underConstructionComp = get_space_component_for_type(self.GetTypeID(), UNDER_CONSTRUCTION) 1625 return underConstructionComp.inputItems 1626 return {} 1627 1628 1629 class StructureContainer(BaseInvContainer): 1630 isMovable = False 1631 1632 def IsInRange(self): 1633 return session.structureid and self.itemID == session.structureid 1634 1635 def GetMenu(self): 1636 return [] 1637 1638 1639 class StructureBay(StructureContainer): 1640 1641 def IsItemHere(self, item): 1642 return item.locationID == self.itemID and item.flagID == self.locationFlag and item.ownerID == self.GetOwnerID() 1643 1644 1645 class Structure(StructureContainer): 1646 __guid__ = 'invCtrl.Structure' 1647 iconName = 'res:/ui/Texture/WindowIcons/structurebrowser.png' 1648 1649 def GetName(self): 1650 name = cfg.evelocations.Get(self.itemID).name 1651 if not name: 1652 name = evetypes.GetName(self.GetTypeID()) 1653 return name 1654 1655 def IsItemHere(self, item): 1656 return False 1657 1658 1659 class StructureAmmoBay(StructureBay): 1660 __guid__ = 'invCtrl.StructureAmmoBay' 1661 iconName = 'res:/ui/Texture/WindowIcons/itemHangar.png' 1662 locationFlag = const.flagCargo 1663 1664 def GetName(self): 1665 return localization.GetByLabel('UI/Ship/AmmoHold') 1666 1667 def DoesAcceptItem(self, item): 1668 return item.categoryID == const.categoryCharge 1669 1670 1671 class StructureFuelBay(StructureBay): 1672 __guid__ = 'invCtrl.StructureFuelBay' 1673 iconName = 'res:/UI/Texture/WindowIcons/fuelbay.png' 1674 locationFlag = const.flagStructureFuel 1675 1676 def GetName(self): 1677 return localization.GetByLabel('UI/Ship/FuelBay') 1678 1679 def DoesAcceptItem(self, item): 1680 return item.groupID == const.groupFuelBlock 1681 1682 1683 class StructureFighterBay(StructureBay): 1684 __guid__ = 'invCtrl.StructureFighterBay' 1685 iconName = 'res:/UI/Texture/WindowIcons/dronebay.png' 1686 locationFlag = const.flagFighterBay 1687 hasCapacity = True 1688 1689 def GetName(self): 1690 return localization.GetByLabel('UI/Ship/FighterBay') 1691 1692 def DoesAcceptItem(self, item): 1693 return item.categoryID == const.categoryFighter 1694 1695 1696 class StructureItemHangar(StructureContainer): 1697 __guid__ = 'invCtrl.StructureItemHangar' 1698 iconName = 'res:/ui/Texture/WindowIcons/itemHangar.png' 1699 locationFlag = const.flagHangar 1700 1701 def __init__(self, *args, **kwargs): 1702 BaseInvContainer.__init__(self, *args, **kwargs) 1703 self.name = localization.GetByLabel('UI/Inventory/ItemHangar') 1704 1705 def IsItemHere(self, item): 1706 return item.locationID == self.itemID and item.ownerID == session.charid and item.flagID == const.flagHangar and item.categoryID != const.categoryShip 1707 1708 1709 class StructureShipHangar(StructureContainer): 1710 __guid__ = 'invCtrl.StructureShipHangar' 1711 iconName = 'res:/ui/Texture/WindowIcons/shiphangar.png' 1712 locationFlag = const.flagHangar 1713 1714 def __init__(self, *args, **kwargs): 1715 BaseInvContainer.__init__(self, *args, **kwargs) 1716 self.name = localization.GetByLabel('UI/Inventory/ShipHangar') 1717 1718 def IsItemHere(self, item): 1719 return item.locationID == self.itemID and item.ownerID == session.charid and item.flagID == const.flagHangar and item.categoryID == const.categoryShip 1720 1721 1722 class StructureDeliveriesHangar(StructureContainer): 1723 __guid__ = 'invCtrl.StructureDeliveriesHangar' 1724 iconName = 'res:/ui/Texture/WindowIcons/personalDeliveries.png' 1725 locationFlag = const.flagDeliveries 1726 isMovable = False 1727 1728 def __init__(self, *args, **kwargs): 1729 BaseInvContainer.__init__(self, *args, **kwargs) 1730 self.name = localization.GetByLabel('UI/Inventory/DeliveriesHangar') 1731 1732 def IsItemHere(self, item): 1733 return item.locationID == self.itemID and item.ownerID == session.charid and item.flagID == const.flagDeliveries 1734 1735 def DoesAcceptItem(self, item): 1736 if item.typeID == invConst.typePlex and item.itemID is None: 1737 return False 1738 return super(StructureDeliveriesHangar, self).DoesAcceptItem(item) 1739 1740 1741 class StructureCorpHangar(BaseCorpContainer): 1742 __guid__ = 'invCtrl.StructureCorpHangar' 1743 1744 def IsInRange(self): 1745 office = sm.GetService('officeManager').GetCorpOfficeAtLocation() 1746 return office and office.officeID == self.itemID 1747 1748 def GetMenu(self): 1749 return [] 1750 1751 def GetItems(self): 1752 try: 1753 return BaseCorpContainer.GetItems(self) 1754 except UserError: 1755 return [] 1756 1757 def SetDivisionID(self, divisionID): 1758 BaseCorpContainer.SetDivisionID(self, divisionID) 1759 self.locationFlag = const.corpFlagByDivision.get(divisionID) 1760 1761 1762 class AssetSafetyCorpContainer(StructureCorpHangar): 1763 __guid__ = 'invCtrl.AssetSafetyCorpContainer' 1764 scope = uiconst.SCOPE_DOCKED 1765 isMovable = False 1766 1767 def GetName(self): 1768 if self.divisionID == invConst.flagCorpDeliveries: 1769 return localization.GetByLabel('UI/Inventory/CorpDeliveries') 1770 return StructureCorpHangar.GetName(self) 1771 1772 def SetDivisionID(self, divisionID): 1773 StructureCorpHangar.SetDivisionID(self, divisionID) 1774 self.locationFlag = invConst.corpAssetSafetyFlagsFromDivision.get(divisionID) 1775 1776 def GetIconName(self): 1777 if self.locationFlag == const.flagCorpDeliveries: 1778 return 'res:/UI/Texture/WindowIcons/corpdeliveries.png' 1779 return StructureCorpHangar.GetIconName(self) 1780 1781 def DoesAcceptItem(self, item): 1782 if item.typeID == invConst.typePlex and item.itemID is None: 1783 return False 1784 return super(AssetSafetyCorpContainer, self).DoesAcceptItem(item) 1785 1786 def _GetInvCacheContainer(self): 1787 return sm.GetService('invCache').GetInventoryFromId(self.itemID) 1788 1789 def IsInRange(self): 1790 return True 1791 1792 1793 class StructureDeedBay(StructureBay): 1794 __guid__ = 'invCtrl.StructureDeedBay' 1795 iconName = 'res:/UI/Texture/WindowIcons/fuelbay.png' 1796 locationFlag = invConst.flagStructureDeed 1797 1798 def GetName(self): 1799 return localization.GetByLabel('UI/Ship/StructureDeedBay') 1800 1801 def DoesAcceptItem(self, item): 1802 return item.groupID == invConst.groupStructureDeed 1803 1804 1805 class StructureMoonMaterialBay(BaseCelestialContainer): 1806 __guid__ = 'invCtrl.StructureMoonMaterialBay' 1807 iconName = 'res:/ui/Texture/WindowIcons/moon_material_bay.png' 1808 locationFlag = const.flagMoonMaterialBay 1809 1810 def __init__(self, *args, **kwargs): 1811 BaseInvContainer.__init__(self, *args, **kwargs) 1812 self.name = localization.GetByLabel('UI/Inventory/MoonMaterialBay') 1813 self._isLootable = True 1814 1815 def DoesAcceptItem(self, item): 1816 return False 1817 1818 def GetOperationalDistance(self, *args): 1819 return const.maxCargoContainerTransferDistance 1820 1821 def CheckCanAdd(self, typeID, quantity): 1822 return False 1823 1824 def IsInRange(self): 1825 bp = sm.GetService('michelle').GetBallpark() 1826 if bp is None: 1827 return False 1828 ball = bp.GetBall(self.itemID) 1829 if not ball: 1830 return False 1831 operationalDistance = const.maxCargoContainerTransferDistance 1832 if ball.surfaceDist > operationalDistance: 1833 return False 1834 return True 1835 1836 def GetIconName(self): 1837 return self.iconName 1838 1839 1840 def GetInvCtrlFromInvID(invID): 1841 from eve.client.script.environment import invControllers 1842 if invID is None: 1843 return 1844 cls = getattr(invControllers, invID[0], None) 1845 if cls is not None: 1846 return cls(*invID[1:]) 1847 1848 1849 class ItemSiphonPseudoSilo(BaseCelestialContainer): 1850 __guid__ = 'invCtrl.ItemSiphonPseudoSilo' 1851 iconName = 'res:/UI/Texture/Icons/38_20_12.png' 1852 1853 def GetIconName(self): 1854 return self.iconName 1855 1856 def GetItems(self): 1857 return BaseCelestialContainer.GetItems(self) 1858 1859 1860 class PlexVault(BaseInvContainer): 1861 __guid__ = 'invCtrl.PlexVault' 1862 iconName = PLEX_128_GRADIENT_YELLOW 1863 locationFlag = None 1864 hasCapacity = False 1865 oneWay = False 1866 viewOnly = False 1867 scope = None 1868 isLockable = False 1869 isMovable = False 1870 filtersEnabled = False 1871 typeID = None 1872 acceptsDrops = True 1873 1874 def IsItemHere(self, item): 1875 return False 1876 1877 def IsPrimed(self): 1878 return True 1879 1880 def DoesAcceptItem(self, item): 1881 return item.groupID == invConst.groupCurrency 1882 1883 def GetInventoryItem(self): 1884 return None 1885 1886 def GetMenu(self): 1887 return [] 1888 1889 def GetItems(self): 1890 return [] 1891 1892 def AddItems(self, items): 1893 locationID = session.stationid or session.structureid 1894 inventoryMgr = sm.GetService('invCache').GetInventoryMgr() 1895 for item in items: 1896 if item.groupID != invConst.groupCurrency: 1897 continue 1898 quantity = item.stacksize 1899 if len(items) == 1 and uicore.uilib.Key(uiconst.VK_SHIFT): 1900 quantity = self.PromptUserForQuantity(item, quantity) 1901 if not quantity: 1902 continue 1903 reference = inventoryMgr.DepositPlexToVault(locationID, item.itemID, quantity, InvoiceType.InventoryToVault) 1904 PlexDepositListener(session.userid, quantity, reference) 1905 1906 def OnDropData(self, nodes): 1907 items = super(PlexVault, self).OnDropData(nodes) 1908 for node in nodes: 1909 if getattr(node, '__guid__', None) == 'listentry.InvAssetItem': 1910 items.append(node.item) 1911 1912 return items 1913 1914 def CheckAndHandlePlexVaultItem(self, node): 1915 return False 1916 1917 def PromptUserForQuantity(self, item, itemQuantity, sourceLocation = None, maxQtyAllowed = None): 1918 message = localization.GetByLabel('UI/Inventory/ItemActions/DivideItemStack') 1919 quantity = item.stacksize 1920 ret = uix.QtyPopup(maxvalue=quantity, minvalue=0, setvalue=quantity, hint=message) 1921 if ret: 1922 return ret['qty']