invItemFunctions.py (25628B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\menuSvcExtras\invItemFunctions.py 2 import collections 3 from collections import defaultdict 4 import blue 5 from carbon.client.script.environment.AudioUtil import PlaySound 6 from carbon.common.script.net.moniker import Moniker 7 from carbon.common.script.util.linkUtil import GetShowInfoLink 8 from carbonui import uiconst 9 from carbonui.uicore import uicore 10 import uthread2 11 import destiny 12 from cosmetics.client.shipSkinApplicationSvc import get_ship_skin_application_svc 13 from eve.client.script.ui.shared.neocom.corporation.corp_ui_votes import VoteWizardDialog 14 from eve.client.script.ui.shared.neocom.ownerSearch import OwnerSearchWindow 15 from eve.client.script.ui.shared.shipNameDialog import prompt_rename_ship 16 from eve.common.lib import appConst as const 17 from eve.common.script.sys import eveCfg, idCheckers 18 from eve.common.script.sys.eveCfg import IsControllingStructure 19 from eve.common.script.util import notificationconst 20 from eveexceptions import UserError 21 from eveexceptions.const import UE_TYPEIDL 22 import evetypes 23 from inventorycommon.util import IsModularShip 24 from inventoryrestrictions import is_trashable, CANNOT_TRASH_ERROR 25 from inventoryutil.client.inventory import get_hangar_inventory 26 import localization 27 import logging 28 from eve.client.script.ui.util import uix 29 from corporation import voting 30 from player_messaging.client.ui_message import prompt_player_fsd_dialog 31 from shipprogression.boarding_moment.boardingMomentSvc import GetBoardingMomentService 32 logger = logging.getLogger(__name__) 33 34 def LaunchSMAContents(invItem): 35 _CheckIfValidStateToLaunchFromContainer() 36 sm.GetService('gameui').GetShipAccess().LaunchFromContainer(invItem.locationID, invItem.itemID) 37 38 39 def LaunchShipOrContainerFromWreckOrContainer(invItem): 40 _CheckIfValidStateToLaunchFromContainer() 41 sm.RemoteSvc('eject').LaunchShipOrContainerFromWreckOrContainer(invItem.locationID, invItem.itemID) 42 43 44 def _CheckIfValidStateToLaunchFromContainer(): 45 bp = sm.GetService('michelle').GetBallpark() 46 myShipBall = bp.GetBall(session.shipid) 47 if myShipBall and myShipBall.mode == destiny.DSTBALL_WARP: 48 raise UserError('ShipInWarp') 49 50 51 def Jettison(invItems, showPrompt = True): 52 if showPrompt and prompt_player_fsd_dialog('ConfirmJettison', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES: 53 return 54 itemsByID = {invItem.itemID:invItem for invItem in invItems} 55 ship = sm.StartService('gameui').GetShipAccess() 56 if ship: 57 itemIDs = itemsByID.keys() 58 jettisonedToCanIDs, jettisonItemList = ship.Jettison(itemIDs) 59 notJettisonedIDs = set(itemIDs) - set(jettisonedToCanIDs) - set(jettisonItemList) 60 notJettisonedTypeIDs = set() 61 for itemID in notJettisonedIDs: 62 if itemID in itemsByID: 63 item = itemsByID[itemID] 64 notJettisonedTypeIDs.add(item.typeID) 65 66 if notJettisonedTypeIDs: 67 raise UserError('NotAllItemsWereJettisoned', {'itemList': (UE_TYPEIDL, notJettisonedTypeIDs)}) 68 69 70 def JettisonStructureFuel(invItems): 71 if prompt_player_fsd_dialog('ConfirmJettison', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES: 72 return 73 Moniker('structure', session.structureid).JettisonStructureFuel([ i.itemID for i in invItems ]) 74 75 76 def Reprocess(invItems): 77 if not session.stationid and not session.structureid: 78 return 79 sm.StartService('reprocessing').ReprocessDlg(invItems) 80 81 82 def TrainNow(invItems): 83 if len(invItems) > 1: 84 prompt_player_fsd_dialog('TrainMoreTheOne') 85 return 86 InjectSkillIntoBrain(invItems) 87 blue.pyos.synchro.SleepWallclock(500) 88 sm.GetService('skillqueue').TrainSkillNow(invItems[0].typeID, 1) 89 90 91 def InjectSkillIntoBrain(invItems): 92 sm.StartService('skills').InjectSkillIntoBrain(invItems) 93 94 95 def PlugInImplant(invItems): 96 if prompt_player_fsd_dialog('ConfirmPlugInImplant', {}, uiconst.OKCANCEL) != uiconst.ID_OK: 97 return 98 PlaySound(uiconst.SOUND_ADD_OR_USE) 99 for invItem in invItems: 100 sm.StartService('godma').GetDogmaLM().InjectImplant(invItem.itemID) 101 sm.GetService('notificationSvc').MakeAndScatterNotification(notificationconst.notificationTypeImplantPluggedIn, {'typeID': invItem.typeID}) 102 103 104 def ConsumeBooster(invItems): 105 if type(invItems) is not list: 106 invItems = [invItems] 107 for invItem in invItems: 108 sm.StartService('godma').GetDogmaLM().UseBooster(invItem.itemID, invItem.locationID) 109 sm.GetService('notificationSvc').MakeAndScatterNotification(notificationconst.notificationTypeBoosterConsumed, {'typeID': invItem.typeID}) 110 111 112 def ConsumeExpertSystem(invItem): 113 sm.GetService('expertSystemSvc').ConsumeExpertSystem(invItem.itemID) 114 115 116 def DeliverToStructure(items, invCacheSvc): 117 if not session.structureid: 118 return 119 if not isinstance(items, collections.Iterable): 120 items = [items] 121 items = [ item for item in items if invCacheSvc.GetStationIDOfItem(item) == session.structureid ] 122 if not items: 123 return 124 125 def Confirm(characterID): 126 formatted = [ '<t>- %sx %s<br>' % (item.stacksize, GetShowInfoLink(item.typeID, evetypes.GetName(item.typeID), item.itemID)) for item in items ] 127 data = {'items': ''.join(formatted), 128 'character': characterID} 129 if prompt_player_fsd_dialog('ConfirmDeliverItems', data, uiconst.YESNO) == uiconst.ID_YES: 130 sm.RemoteSvc('structureDeliveries').Deliver(session.structureid, characterID, [ item.itemID for item in items ]) 131 132 def Deliver(results): 133 for row in results(): 134 OwnerSearchWindow.CloseIfOpen(windowID='DeliverToStructure') 135 return Confirm(row.charID) 136 137 OwnerSearchWindow.CloseIfOpen(windowID='DeliverToStructure') 138 OwnerSearchWindow.Open(windowID='DeliverToStructure', actionBtns=[(localization.GetByLabel('UI/Inventory/ItemActions/DeliverItems'), Deliver, True)], caption=localization.GetByLabel('UI/Inventory/ItemActions/DeliverItemsHeader'), input='', showContactList=True, multiSelect=False, ownerGroups=[const.groupCharacter]) 139 140 141 def AssembleShip(invItems): 142 import stackless 143 from eve.client.script.ui.station.assembleModularShip import prompt_assemble_modular_ship 144 itemIDs = [] 145 subSystems = None 146 invCache = sm.GetService('invCache') 147 for item in invItems: 148 lockInfo = invCache.IsItemLocked_NoLock(item.itemID) 149 cfg.evelocations.RemoveFromKnowLuzers(item.itemID) 150 if lockInfo[0] and lockInfo[7] != stackless.getcurrent(): 151 continue 152 if IsModularShip(item.typeID): 153 if not (eveCfg.IsDocked() or IsControllingStructure()): 154 prompt_player_fsd_dialog('CantAssembleModularShipInSpace') 155 return 156 subSystems = prompt_assemble_modular_ship(item) 157 if subSystems: 158 itemIDs = item.itemID 159 break 160 else: 161 continue 162 itemIDs.append(item.itemID) 163 164 if itemIDs: 165 singleItem = not isinstance(itemIDs, list) or len(itemIDs) == 1 166 if singleItem and not settings.user.suppress.Get('suppress.ShipNameChangeOnAssemble', False): 167 name = prompt_rename_ship(ship_type_id=item.typeID, show_suppress=True) 168 else: 169 name = None 170 PlaySound('ship_goals_assemble_ship_play') 171 bmSvc = GetBoardingMomentService() 172 if not bmSvc.HasSeen(item.typeID): 173 bmSvc.SetUnseen(item.typeID) 174 item_id = sm.StartService('gameui').GetShipAccess().AssembleShip(itemIDs, name=name, subSystems=subSystems) 175 try: 176 if item_id is not None: 177 if isinstance(item_id, list): 178 for current_id in item_id: 179 type_id = sm.GetService('invCache').GetInventoryFromId(current_id).typeID 180 get_ship_skin_application_svc().apply_default_skin(current_id, type_id) 181 182 else: 183 type_id = sm.GetService('invCache').GetInventoryFromId(item_id).typeID 184 get_ship_skin_application_svc().apply_default_skin(item_id, type_id) 185 except Exception as e: 186 logger.error('Failed to apply default skin during ship assembly', e) 187 188 return item_id 189 190 191 def AssembleAndBoardShip(invItem): 192 shipID = AssembleShip([invItem]) 193 if not shipID: 194 return 195 if isinstance(shipID, list): 196 shipID = shipID[0] 197 if session.stationid: 198 ship = None 199 if shipID != invItem.itemID: 200 uthread2.Yield() 201 inventory = get_hangar_inventory() 202 for item in inventory.List(): 203 if item.itemID == shipID: 204 ship = item 205 break 206 207 else: 208 ship = invItem 209 if bool(ship): 210 sm.GetService('station').TryActivateShip(ship) 211 elif session.structureid: 212 sm.GetService('structureDocking').ActivateShip(shipID) 213 PlaySound('ship_goals_assemble_board_ship_play') 214 215 216 def CheckItemsInSamePlace(invItems): 217 if len(invItems) == 0: 218 return 219 locationID = invItems[0].locationID 220 flag = invItems[0].flagID 221 ownerID = invItems[0].ownerID 222 for item in invItems: 223 if item.locationID != locationID or item.flagID != flag or item.ownerID != ownerID: 224 raise UserError('ItemsMustBeInSameHangar') 225 locationID = item.locationID 226 ownerID = item.ownerID 227 flag = item.flagID 228 229 230 def InSameStructureWithCorrectFlag(invItem, allowedFlags): 231 currentStructureID = session.structureid 232 if not currentStructureID: 233 return False 234 if invItem.locationID != currentStructureID: 235 return False 236 if invItem.flagID in allowedFlags: 237 return True 238 return False 239 240 241 def CheckIfInPrimedOffice(invItem): 242 office = sm.StartService('officeManager').GetCorpOfficeAtLocation() 243 return office is not None and invItem.locationID == office.officeID 244 245 246 def CheckSameStation(invItem): 247 if session.stationid: 248 if invItem.locationID == session.stationid: 249 return 1 250 if isinstance(invItem, blue.DBRow) and 'stationID' in invItem.__columns__ and invItem.stationID == session.stationid: 251 return 1 252 if CheckIfInPrimedOffice(invItem): 253 return 1 254 if idCheckers.IsPlayerItem(invItem.locationID) and sm.GetService('invCache').IsInventoryPrimedAndListed(invItem.locationID): 255 return 1 256 return 0 257 258 259 def InvalidateItemLocation(ownerID, stationID, flag, invCacheSvc): 260 if ownerID == session.corpid: 261 which = 'offices' 262 if flag == const.flagCorpDeliveries: 263 which = 'deliveries' 264 if flag == const.flagCapsuleerDeliveries: 265 which = 'capsuleerdeliveries' 266 sm.services['objectCaching'].InvalidateCachedMethodCall('corpmgr', 'GetAssetInventoryForLocation', session.corpid, stationID, which) 267 else: 268 sm.services['objectCaching'].InvalidateCachedMethodCall('stationSvc', 'GetStation', stationID) 269 invCacheSvc.GetInventory(const.containerGlobal).InvalidateStationItemsCache(stationID) 270 271 272 def DeliverToCorpHangarFolder(invItemAndFlagList, invCacheSvc): 273 if len(invItemAndFlagList) == 0: 274 return 275 invItems = [] 276 itemIDs = [] 277 for item, flagID in invItemAndFlagList: 278 invItems.append(item) 279 itemIDs.append(item.itemID) 280 281 CheckItemsInSamePlace(invItems) 282 fromID = invItems[0].locationID 283 doSplit = bool(uicore.uilib.Key(uiconst.VK_SHIFT) and len(invItemAndFlagList) == 1 and invItemAndFlagList[0][0].stacksize > 1) 284 stationID = invCacheSvc.GetStationIDOfItem(invItems[0]) 285 if stationID is None: 286 raise UserError('CanOnlyDoInStations') 287 ownerID = invItems[0].ownerID 288 flag = invItems[0].flagID 289 deliverToFlag = invItemAndFlagList[0][1] 290 qty = None 291 if doSplit: 292 invItem = invItems[0] 293 caption = '%s: %s' % (localization.GetByLabel('UI/Inventory/ItemActions/DivideItemStack'), evetypes.GetName(invItem.typeID)) 294 ret = uix.QtyPopup(invItem.stacksize, 1, 1, None, caption) 295 if ret is not None: 296 qty = ret['qty'] 297 invCacheSvc.GetInventoryMgr().DeliverToCorpHangar(fromID, stationID, itemIDs, qty, ownerID, deliverToFlag) 298 InvalidateItemLocation(ownerID, stationID, flag, invCacheSvc) 299 if ownerID == session.corpid: 300 sm.ScatterEvent('OnCorpAssetChange', invItems, stationID) 301 302 303 def DeliverToCorpMember(invItems, invCacheSvc): 304 if len(invItems) == 0: 305 return 306 CheckItemsInSamePlace(invItems) 307 corpMemberIDs = sm.GetService('corp').GetMemberIDs() 308 cfg.eveowners.Prime(corpMemberIDs) 309 memberslist = [] 310 for memberID in corpMemberIDs: 311 who = cfg.eveowners.Get(memberID) 312 memberslist.append([who.ownerName, memberID, who.typeID]) 313 314 stationID = invCacheSvc.GetStationIDOfItem(invItems[0]) 315 if stationID is None: 316 raise UserError('CanOnlyDoInStations') 317 res = uix.ListWnd(memberslist, 'character', localization.GetByLabel('UI/Corporations/Common/SelectCorpMember'), localization.GetByLabel('UI/Corporations/Common/SelectCorpMemberToDeliverTo'), 1) 318 if res: 319 corporationMemberID = res[1] 320 return _DeliverToCorpMemberID(corporationMemberID, invItems, invCacheSvc) 321 322 323 def _DeliverToCorpMemberID(corporationMemberID, invItems, invCacheSvc): 324 doSplit = uicore.uilib.Key(uiconst.VK_SHIFT) and len(invItems) == 1 and invItems[0].stacksize > 1 325 stationID = invCacheSvc.GetStationIDOfItem(invItems[0]) 326 if stationID is None: 327 raise UserError('CanOnlyDoInStations') 328 ownerID = invItems[0].ownerID 329 flagID = invItems[0].flagID 330 itemIDs = [ item.itemID for item in invItems ] 331 qty = None 332 if doSplit: 333 invItem = invItems[0] 334 caption = '%s: %s' % (localization.GetByLabel('UI/Inventory/ItemActions/DivideItemStack'), evetypes.GetName(invItem.typeID)) 335 ret = uix.QtyPopup(invItem.stacksize, 1, 1, None, caption) 336 if ret is not None: 337 qty = ret['qty'] 338 invCacheSvc.GetInventoryMgr().DeliverToCorpMember(corporationMemberID, stationID, itemIDs, qty, ownerID, flagID) 339 InvalidateItemLocation(ownerID, stationID, flagID, invCacheSvc) 340 if ownerID == session.corpid: 341 sm.ScatterEvent('OnCorpAssetChange', invItems, stationID) 342 343 344 def DeliverToMyself(invItems, invCacheSvc): 345 if len(invItems) == 0: 346 return 347 CheckItemsInSamePlace(invItems) 348 _DeliverToCorpMemberID(session.charid, invItems, invCacheSvc) 349 350 351 def SplitStack(invItems, invCacheSvc): 352 if len(invItems) != 1: 353 raise UserError('CannotPerformOnMultipleItems') 354 invItem = invItems[0] 355 caption = '%s: %s' % (localization.GetByLabel('UI/Inventory/ItemActions/DivideItemStack'), evetypes.GetName(invItem.typeID)) 356 ret = uix.QtyPopup(invItem.stacksize, 1, 1, None, caption) 357 if ret is not None: 358 qty = ret['qty'] 359 stationID = invCacheSvc.GetStationIDOfItem(invItem) 360 if stationID is None: 361 raise UserError('CanOnlyDoInStations') 362 flag = invItem.flagID 363 invCacheSvc.GetInventoryMgr().SplitStack(stationID, invItem.itemID, qty, invItem.ownerID) 364 InvalidateItemLocation(invItem.ownerID, stationID, flag, invCacheSvc) 365 if invItem.ownerID == session.corpid: 366 invItem.quantity = invItem.quantity - qty 367 sm.ScatterEvent('OnCorpAssetChange', [invItem], stationID) 368 369 370 def LockDownBlueprint(invItem): 371 try: 372 stationID = {o.stationID for o in sm.StartService('officeManager').GetMyCorporationsOffices() if o.officeID == invItem.locationID}.pop() 373 except KeyError: 374 return 375 376 blueprint = sm.GetService('blueprintSvc').GetBlueprintItem(invItem.itemID) 377 description = localization.GetByLabel('UI/Corporations/Votes/ProposeLockdownDescription', blueprintLocation=stationID, efficiencyLevel=blueprint.materialEfficiency, productivityLevel=blueprint.timeEfficiency) 378 formData = {'voteType': voting.voteItemLockdown, 379 'voteTitle': localization.GetByLabel('UI/Corporations/Votes/LockdownItem', blueprint=invItem.typeID), 380 'voteDescription': description, 381 'voteDays': 1, 382 'itemID': invItem.itemID, 383 'typeID': invItem.typeID, 384 'flagInput': invItem.flagID, 385 'locationID': stationID} 386 dlg = VoteWizardDialog.Open(**formData) 387 dlg.GoToStep(len(dlg.steps)) 388 dlg.ShowModal() 389 390 391 def UnlockBlueprint(invItem): 392 dlg = VoteWizardDialog.Open() 393 stationID = dlg.locationID 394 blueprint = sm.GetService('blueprintSvc').GetBlueprintItem(invItem.itemID) 395 description = localization.GetByLabel('UI/Corporations/Votes/ProposeLockdownDescription', blueprintLocation=stationID, efficiencyLevel=blueprint.materialEfficiency, productivityLevel=blueprint.timeEfficiency) 396 dlg.voteType = voting.voteItemUnlock 397 dlg.voteTitle = localization.GetByLabel('UI/Corporations/Votes/UnlockItem', blueprint=invItem.typeID) 398 dlg.voteDescription = description or dlg.voteTitle 399 dlg.voteDays = 1 400 dlg.itemID = invItem.itemID 401 dlg.typeID = invItem.typeID 402 dlg.flagInput = invItem.flagID 403 dlg.locationID = stationID 404 dlg.GoToStep(len(dlg.steps)) 405 dlg.ShowModal() 406 407 408 def ALSCLock(invItems, invCacheSvc): 409 if len(invItems) < 1: 410 return 411 container = invCacheSvc.GetInventoryFromId(invItems[0].locationID) 412 container.ALSCLockItems([ i.itemID for i in invItems ]) 413 414 415 def ALSCUnlock(invItems, invCacheSvc): 416 if len(invItems) < 1: 417 return 418 container = invCacheSvc.GetInventoryFromId(invItems[0].locationID) 419 container.ALSCUnlockItems([ i.itemID for i in invItems ]) 420 421 422 def GetContainerContents(containerItem, invCacheSvc, dockableID): 423 dockableID = containerItem.locationID if dockableID is None else dockableID 424 if not (idCheckers.IsStation(dockableID) or sm.GetService('structureDirectory').GetStructureInfo(dockableID)): 425 raise RuntimeError('GetContainerContents: dockableID is neither structure nor station.') 426 DoGetContainerContents(containerItem.itemID, dockableID, containerItem.typeID, invCacheSvc) 427 428 429 def DoGetContainerContents(itemID, stationID, containerTypeID, invCacheSvc): 430 from eve.client.script.ui.shared.inventory.containerContentWindow import ContainerContentWindow 431 wnd = ContainerContentWindow.GetIfOpen() 432 if not wnd or wnd.destroyed: 433 wnd = ContainerContentWindow() 434 wnd.LoadContent(itemID=itemID, stationID=stationID, containerTypeID=containerTypeID, invCacheSvc=invCacheSvc) 435 wnd.Maximize() 436 437 438 def CheckLocked(func, invItemsOrIDs, invCacheSvc): 439 if not len(invItemsOrIDs): 440 return 441 if type(invItemsOrIDs[0]) == int or not hasattr(invItemsOrIDs[0], 'itemID'): 442 ret = func(invItemsOrIDs) 443 else: 444 lockedItems = [] 445 try: 446 for item in invItemsOrIDs: 447 if invCacheSvc.IsItemLocked(item.itemID): 448 continue 449 if invCacheSvc.TryLockItem(item.itemID): 450 lockedItems.append(item) 451 452 if not len(lockedItems): 453 prompt_player_fsd_dialog('BusyItems') 454 return 455 ret = func(lockedItems) 456 finally: 457 for invItem in lockedItems: 458 invCacheSvc.UnlockItem(invItem.itemID) 459 460 return ret 461 462 463 def CheckRepackageItems(invItems, warnAboutContainers): 464 repackage = [] 465 if not invItems: 466 return repackage 467 insuranceQ_OK = 0 468 containerQ_OK = -1 469 insuranceContracts = None 470 godma = sm.GetService('godma') 471 for item in invItems: 472 if item.typeID == const.typePlasticWrap: 473 continue 474 itemState = godma.GetItem(item.itemID) 475 if itemState and (itemState.damage or item.categoryID in (const.categoryShip, const.categoryDrone) and itemState.armorDamage): 476 prompt_player_fsd_dialog('CantRepackageDamagedItem') 477 continue 478 if item.categoryID == const.categoryShip: 479 if insuranceContracts is None: 480 insuranceContracts = sm.StartService('insurance').GetContracts() 481 if not insuranceQ_OK and item.itemID in insuranceContracts: 482 if prompt_player_fsd_dialog('RepairUnassembleVoidsContract', {}, uiconst.YESNO) != uiconst.ID_YES: 483 continue 484 insuranceQ_OK = 1 485 containerGroups = (const.groupCargoContainer, 486 const.groupSecureCargoContainer, 487 const.groupAuditLogSecureContainer, 488 const.groupFreightContainer) 489 if warnAboutContainers and item.singleton and item.groupID in containerGroups: 490 if not containerQ_OK: 491 continue 492 if containerQ_OK == -1: 493 if sm.GetService('invCache').GetInventoryFromId(item.itemID).List(): 494 if prompt_player_fsd_dialog('RepackageContainers', {}, uiconst.YESNO) != uiconst.ID_YES: 495 containerQ_OK = 0 496 continue 497 containerQ_OK = 1 498 repackage.append(item) 499 500 return repackage 501 502 503 def RepackageItems(invItems): 504 if any([ i.singleton for i in invItems ]): 505 if prompt_player_fsd_dialog('ConfirmRepackageItem', {}, uiconst.YESNO) != uiconst.ID_YES: 506 return 507 invItems = CheckRepackageItems(invItems, len(invItems) > 1) 508 if not invItems: 509 return 510 invCache = sm.GetService('invCache') 511 itemsByStation = collections.defaultdict(list) 512 for item in invItems: 513 itemsByStation[invCache.GetStationIDOfItem(item) or item.locationID].append((item.itemID, item.locationID)) 514 515 itemsByStation = dict(itemsByStation) 516 try: 517 sm.RemoteSvc('repackagingSvc').RepackageItems(itemsByStation) 518 except UserError as exception: 519 if exception.msg == 'ConfirmRepackageSomethingWithUpgrades': 520 if prompt_player_fsd_dialog(exception.msg, exception.dict, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 521 sm.RemoteSvc('repackagingSvc').RepackageItems(dict(itemsByStation), destroyable=True) 522 elif exception.msg == 'ConfirmRepackageMultipleItemsWithUpgrades': 523 failedItemIDs = exception.dict.get('itemIDs') 524 itemStationTupleByItemID = {} 525 for stationID, itemList in itemsByStation.iteritems(): 526 for itemTuple in itemList: 527 itemStationTupleByItemID[itemTuple[0]] = (stationID, itemTuple) 528 529 newItemsByStation = defaultdict(list) 530 for eachItemID in failedItemIDs: 531 itemStationTuple = itemStationTupleByItemID.get(eachItemID, None) 532 if itemStationTuple: 533 stationID, itemTuple = itemStationTuple 534 newItemsByStation[stationID].append(itemTuple) 535 536 if prompt_player_fsd_dialog(exception.msg, exception.dict, uiconst.YESNO) == uiconst.ID_YES: 537 sm.RemoteSvc('repackagingSvc').RepackageItems(dict(newItemsByStation), destroyable=True) 538 else: 539 raise 540 541 PlaySound('ship_goals_repackage_ship_play') 542 543 544 def Break(invItems, invCacheSvc): 545 ok = 0 546 validIDs = [] 547 for invItem in invItems: 548 if ok or prompt_player_fsd_dialog('ConfirmBreakCourierPackage', {}, uiconst.OKCANCEL) == uiconst.ID_OK: 549 validIDs.append(invItem.itemID) 550 ok = 1 551 552 for itemID in validIDs: 553 invCacheSvc.GetInventoryFromId(itemID).BreakPlasticWrap() 554 555 556 def TrashInvItems(invItems, invCacheSvc, showPrompt = True): 557 if len(invItems) == 0: 558 return 559 CheckItemsInSamePlace(invItems) 560 if showPrompt and not _IsTrashingAcceptedByUser(invItems[:]): 561 return 562 stationID = invCacheSvc.GetStationIDOfItem(invItems[0]) 563 itemsToTrash = [] 564 for item in invItems: 565 if is_trashable(item.typeID): 566 itemsToTrash.append(item.itemID) 567 else: 568 prompt_player_fsd_dialog(CANNOT_TRASH_ERROR) 569 return 570 571 locationID = stationID if stationID else invItems[0].locationID 572 errors = invCacheSvc.GetInventoryMgr().TrashItems(itemsToTrash, locationID) 573 if errors: 574 for e in errors: 575 prompt_player_fsd_dialog(e) 576 577 return 578 isCorp = invItems[0].ownerID == session.corpid 579 InvalidateItemLocation(session.corpid if isCorp else session.charid, stationID, invItems[0].flagID, invCacheSvc) 580 if isCorp: 581 sm.ScatterEvent('OnCorpAssetChange', invItems, stationID) 582 583 584 def _IsTrashingAcceptedByUser(invItems): 585 if len(invItems) == 1: 586 question = 'ConfirmTrashingSin' 587 itemWithQuantity = cfg.FormatConvert(const.UE_TYPEIDANDQUANTITY, invItems[0].typeID, invItems[0].stacksize) 588 args = {'itemWithQuantity': itemWithQuantity} 589 else: 590 question = 'ConfirmTrashingPlu' 591 report = '' 592 overflow_item_count = max(len(invItems) - 10, 0) 593 if overflow_item_count > 0: 594 invItems = invItems[:10] 595 for item in invItems: 596 report += '<t>- %s<br>' % cfg.FormatConvert(const.UE_TYPEIDANDQUANTITY, item.typeID, item.stacksize) 597 598 if overflow_item_count > 0: 599 report += u'<t>{}<br>'.format(localization.GetByLabel('UI/Inventory/TrashItemsOverflowCount', count=overflow_item_count)) 600 args = {'items': report} 601 response = prompt_player_fsd_dialog(question, args, uiconst.YESNO) 602 return response == uiconst.ID_YES 603 604 605 def FindInPersonalAssets(typeID): 606 from eve.client.script.ui.shared.assetsWindow import AssetsWindow 607 wnd = AssetsWindow.GetIfOpen() 608 if wnd and not wnd.destroyed: 609 wnd.Maximize() 610 wnd.SearchTypeID(typeID) 611 else: 612 wnd = AssetsWindow.Open(exactTypeID=typeID) 613 wnd.tabGroup.SelectByID('search')