
#####################################################################
#                CARGO
#####################################################################

default buttonall2 = False

screen cargo_manager_scr(*args):
    $ items = args[0]
    $ modes = args[1]
    $ qtymode = args[2]
    $ iFilters = args[3]
    $ iFilter = args[4]
    $ sLoc = args[5]
    $ sTitle = args[6] 
    $ yadj = args[7] # parts viewport manager y-pos
    $ colPos = [140, 400, 630, 650, 780, 800, 860, 960, 1060, 1160, 1260, 1320, 1540]

    if "transfer" in modes:
        $ colName = ["ware", "legality", "for transfer", " ", "your cargo", " ", " ", " "]

    else:
        $ colName = ["ware", "legality", "buy at", " ", "sell at", " ", " ", " "]

    # compile reserved contingent for missions 
    $ reserved = GAME.missionSys.getReserved()
    $ reserved2 = GAME.missionSys.getReserved2()

    # headline and headers
    text C_HI_B+"{}".format(sTitle)+C_HI_E size FSIZE_LARGE xpos 35 ypos 100
    # Filters
    hbox pos 440,85 spacing 20:
        for i in iFilters:
            if i == iFilter:
                frame xsize 180 ysize 40 background Solid("#0099cc88"):
                    text i.title() xalign 0.5 yalign 0.5 size FSIZE
                    button action Return(["filter", i])
            else:
                frame xsize 180 ysize 40 background Solid("#00000000"):
                    text i.title() xalign 0.5 yalign 0.5 size FSIZE
                    button action Return(["filter", i])
            if i != iFilters[-1]:
                text "|" size FSIZE yalign 0.5

    vbox xpos 440 ypos 145 spacing 5:
            frame xsize 1380 ysize 40 background Solid("#0099cc88"):
                for x in range(len(colName)):
                    if colName[x] in ["buy at", "sell at", "for transfer", "your cargo"]:
                        text colName[x].title() xalign 1.0 yalign 0.5 yoffset 2 xpos colPos[x] size FSIZE
                    else:
                        text colName[x].title() yalign 0.5 yoffset 2 xpos colPos[x] size FSIZE


    side "c r":
        area 440,195,1420,822

        viewport id "vp":
            draggable True
            mousewheel True
            yadjustment yadj

            # # wares and crates
            vbox xpos 40 ypos 200 spacing 5:
                for i in items:
                    if i.kind == iFilter:
                        frame xsize 1380 ysize 54 background Solid("#0099cc88"):
                            image "08_items/ico {}.png".format(i.ID) zoom 0.125 yalign 0.5 xpos 40
                            text i.name xpos colPos[0] yalign 0.5 size FSIZE
                            if sLoc.isLegal(i.ID):
                                text "Tradeable" xpos colPos[1] yalign 0.5 size FSIZE
                            else:
                                text C_RE_B+"Illegal"+C_RE_E xpos colPos[1] yalign 0.5 size FSIZE

                            # action buttons
                            if qtymode == "5x":
                                $ b_buy, b_sell, b_eject = "Buy 5x", "Sell 5x", "Eject 5x"
                            elif qtymode == "10x":
                                $ b_buy, b_sell, b_eject = "Buy 10x", "Sell 10x", "Eject 10x"
                            elif qtymode == "all":
                                $ b_buy, b_sell, b_eject = "Buy All", "Sell All", "Eject All"


                            button action NullAction() tooltip i

                            # market segment
                            if "buy" in modes and i in sLoc.wares and sLoc.isLegal(i.ID):
                                text "{:,}".format(sLoc.getPrice(i, "buy")) xpos colPos[2] xalign 1.0 yalign 0.5 size FSIZE
                                text "{} x".format(sLoc.wares.count(i)) xpos colPos[3] yalign 0.5 size FSIZE
                                frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[6]:
                                    text "Buy" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    button action Return(["buy",i])
                                frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[7]:
                                    text b_buy xalign 0.5 yalign 0.5 size FSIZE_MED
                                    button action Return(["buymore",i])


                            elif "transfer" in modes and i in sLoc.wares and sLoc.isLegal(i.ID):
                                text "({:,})".format(sLoc.getPrice(i, "buy")) xpos colPos[2] xalign 1.0 yalign 0.5 size FSIZE
                                text "{} x".format(sLoc.wares.count(i)) xpos colPos[3] yalign 0.5 size FSIZE
                                frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[6]:
                                    text "Transfer" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    button action Return(["transfer",i])

                            else:
                                text "-" xpos colPos[2] yalign 0.5 size FSIZE
                                text "-" xpos colPos[3] yalign 0.5 size FSIZE

                            # cargo segment
                            if i in GAME.ship.cargo:
                                text "{:,}".format(sLoc.getPrice(i, "sell")) xpos colPos[4] xalign 1.0 yalign 0.5 size FSIZE
                                text "{} x".format(GAME.ship.cargo.count(i)) xpos colPos[5] yalign 0.5 size FSIZE

                            else:
                                text "-" xpos colPos[4] yalign 0.5 size FSIZE
                                text "-" xpos colPos[5] yalign 0.5 size FSIZE

                            # buttons

                            if "sell" in modes and i in GAME.ship.cargo and sLoc.isLegal(i.ID) and i.ID not in ["ITMContainerBot"]:
                                frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[8]:
                                    text "Sell" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    button action Return(["sell",i])
                                if i.ID not in ["ITMContainerBot"]:
                                    frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[9]:
                                        text b_sell xalign 0.5 yalign 0.5 size FSIZE_MED
                                        button action Return(["sellmore",i])


                            if i.kind == "subsys" and i in GAME.ship.cargo:
                                frame xsize 80 ysize 30 background Solid ("#0099ccff") yalign 0.5 xpos colPos[10]:
                                    text "Install" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    button action Return(["install",i])


                            if "eject" in modes and i.ID not in ["ITMContainerBot"]:
                                if i in GAME.ship.cargo:
                                    if i.ID in ["ITMSlaves"]:
                                        frame xsize 140 ysize 30 background Solid ("#00aa00ff") yalign 0.5 xpos colPos[8] xoffset 25:
                                            button action Return(["eject",i])
                                            text "Free the Slaves!" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    else:
                                        frame xsize 70 ysize 30 background Solid ("#cc0000ff") yalign 0.5 xpos colPos[8]:
                                            button action Return(["eject",i])
                                            text "Eject" xalign 0.5 yalign 0.5 size FSIZE_MED
                                    if i.ID not in ["ITMContainerBot"] and i.ID not in ["ITMSlaves"]:
                                        frame xsize 90 ysize 30 background Solid ("#cc0000ff") yalign 0.5 xpos colPos[9]:
                                            text b_eject xalign 0.5 yalign 0.5 size FSIZE_MED
                                            button action Return(["ejectmore",i])

                            if i.ID in ["ITMCrateBots", "ITMCrateBotsRare", "ITMCrateBotsMil", "ITMCrateLiquor", "ITMCrateBotsPre"] and i in GAME.ship.cargo:
                                    frame xsize 80 ysize 30 background Solid ("#cc8500ff") yalign 0.5 xpos colPos[10]:
                                        button action Return(["open",i])
                                        text "Open" xalign 0.5 yalign 0.5 size FSIZE_MED

                            if i.ID in ["ITMContainerBot"] and i in GAME.ship.cargo:
                                    frame xsize 80 ysize 30 background Solid ("#cc8500ff") yalign 0.5 xpos colPos[10]:
                                        button action Return(["unpack",i])
                                        text "Open" xalign 0.5 yalign 0.5 size FSIZE_MED

                            # reserved contingent for missions
                            if i.ID in reserved.keys():
                                if reserved[i.ID] > GAME.ship.cargo.count(i):

                                    if reserved[i.ID] == reserved2[i.ID]:
                                            text "{}({}){}".format(C_OR_B, reserved2[i.ID],C_OR_E) yalign 0.5 xpos colPos[11] size FSIZE

                                    elif reserved2[i.ID] > GAME.ship.cargo.count(i):
                                            text C_OR_B + "({})\n({})*".format(reserved2[i.ID], reserved[i.ID]) + C_OR_E ypos -2 xpos colPos[11] size FSIZE line_spacing -2
                                    else:
                                            text "{}({}){}".format(C_YE_B,reserved2[i.ID],C_YE_E) ypos -2 xpos colPos[11] size FSIZE
                                            text "{}({})*{}".format(C_OR_B,reserved[i.ID],C_OR_E) ypos 23 xpos colPos[11] size FSIZE

                                else:
                                    if reserved[i.ID] == reserved2[i.ID]:
                                        text "{}({}){}".format(C_GR_B,reserved[i.ID],C_GR_E) yalign 0.5 xpos colPos[11] size FSIZE
                                    else:
                                        text "{}({})*{}".format(C_GR_B,reserved[i.ID],C_GR_E) yalign 0.5 xpos colPos[11] size FSIZE


        vbar value YScrollValue("vp")
    
    if reserved:
        text "[C_YE_B](x) = Reserved contingent for accepted mission (single sale only)[C_YE_E]" size FSIZE_MED xpos 1330 yalign 0.971
        text "[C_YE_B](x)* = Multiple contracts[C_YE_E]" size FSIZE_MED xpos 1330 yalign 0.995



    #####################################################################
    #                TOOLTIP
    #####################################################################
    $ tooltip = GetTooltip()
    if tooltip:
        frame padding 20,20 xsize 560 ysize 920 pos 40 , 200 background Solid("#39210000"):
            image "08_items/ico bg1.png" zoom 0.5 xpos 50 ypos 100
            image "08_items/ico {}.png".format(tooltip.ID) zoom 0.5 xpos 50 ypos 100
            vbox xsize 400 ypos 420 xpos -25 spacing 20:
                text tooltip.getName(["col", "cap", "noArt"]) xalign 0.5
                text tooltip.description xalign 0.5 size FSIZE
                text "Value: {:,} Cr".format(tooltip.price) xalign 0.5 size FSIZE

    text "A = Toggle 5x / 10x / All Mode" size FSIZE_MED xalign 0.9375 yalign 0.995

    #####################################################################
    #                EXIT BUTTON, KEYS, ...
    #####################################################################
    frame xsize 350 ysize 64 pos 0,980 background Solid("#00000000") padding 0,0:
        image "05_gui/gui_menu_option.png" yalign 0.5
        button action Return(["exit", None])
        textbutton "Exit (X)" yalign 0.5 action Return(["exit", None])xpos 20
        key "x" action Return(["exit", None])
        key "X" action Return(["exit", None])

    key "a" action Return (["qtymode"])

label cargo_manager(sLoc = False, modes = [], qtymode = [], attr = {}):

    $ qtymode = "10x"
    $ GAME.mc.hasDone("cargo")
    # background & scene
    $ sTitle = "CARGOBAY"
    if "title" in attr.keys():
        $ sTitle = attr["title"]

    show image "05_gui/mask 50.png"
    show screen header()
    play sound "audio/beep.wav"
    if not sLoc:
        $ sLoc = GAME.getSpaceLoc()
    $ itemsMarket = set([])
    $ iFilters = ["ware", "crate", "subunit", "subsys", "module", "pod"]
    $ iFilter = "ware"
    $ yadj = ui.adjustment() # to remember ypos in cargo lists

    # restock market
    if sLoc.hasMarket() and "restocked market" not in sLoc.doneToday:
        # weapons licenses
        $ extraGearTags = []
        if 'grade_1' in GAME.mc.done:
            $ extraGearTags += ["grade_1"]  
        if 'grade_2' in GAME.mc.done:
            $ extraGearTags += ["grade_2"]         
        if 'grade_3' in GAME.mc.done:
            $ extraGearTags += ["grade_3"]  

        $ sLoc.restock(extraGearTags)

        # quest related addons
        if sLoc.ID == "LIDStationIltari" and GAME.questSys.isActive("QID_VEE_MAINT_MINING"):
            $ sLoc.wares.append(GAME.items["ITMMiningMkII"])
        if sLoc.ID == "LIDStationIltari" and GAME.mc.lvl >= 5:
            $ sLoc.wares.append(GAME.items["ITMCargoMkII"])

    # presort
    if GAME.ship.status == "docked" or "transfer" in modes:
        $ itemsMarket = set(sLoc.wares)
    $ itemsShip = set(GAME.ship.cargo)
    $ sortedItems = list(itemsShip | itemsMarket)
    $ sortedItems.sort(key = lambda x : x.price, reverse=True)
    #$ sortedItems.sort(key = lambda x : x in GAME.ship.cargo, reverse = True)

    # manager loop

    while True:
        if GAME.ship.status == "docked" or "transfer" in modes:
            $ itemsMarket = set(sLoc.wares)
        $ itemsShip = set(GAME.ship.cargo)

        $ sortedItems = list(itemsShip | itemsMarket)
        $ sortedItems.sort(key = lambda x : x.price, reverse=True)

        if modes:
            pass
        elif GAME.ship.status == "docked":
            $ modes += ["buy", "sell"]
        else:
            $ modes = ["eject"]
        call screen cargo_manager_scr(sortedItems, modes, qtymode, iFilters, iFilter, sLoc, sTitle, yadj)

        if "exit" in _return:
            play sound "audio/click.wav"
            hide image "05_gui/mask 50.png"

            if "item sold" in GAME.mc.done and "first deal" not in GAME.mc.done:
                $ GAME.mc.hasDone("first deal")
                play sound "audio/success.wav"
                mc "\"My first deal!\""
                mc "\"Captain [GAME.mc.name], Merchant Tycoon!\""

            return()

        elif "filter" in _return:
            $ iFilter = _return[1]
            play sound "audio/click.wav"

        elif "qtymode" in _return:
            queue sound "audio/click.wav"
            $ qtymode = {"5x": "10x", "10x": "all", "all": "5x"}[qtymode]

        elif "eject" in _return:
            $ item = _return[1]
            play sound "audio/load.wav"
            if item.ID == "ITMSlaves":
                # ==== CR-0553 START
                $ slaves = GAME.ship.cargo.count(GAME.items["ITMSlaves"])
                $ amount = slaves*500
                $ GAME.mc.tallyUp("Slaves Rescued", slaves)
                call large_notify("SLAVES RESCUED", "You contact Space Patrol. A Rescue Cruiser rendevous with your ship and takes over the stasis units.\n\nA rescue fee of {:,} Cr is wired to your account.".format(amount), ["Continue"], "08_items/ico ITMSlaves.png") from _call_large_notify_31
                while GAME.items["ITMSlaves"] in GAME.ship.cargo:
                    $ GAME.ship.unloadWare("ITMSlaves")
                call find_notify(amount, "REWARD RECEIVED") from _call_find_notify_19
                call transaction("Space Rescue Rewards", amount, True) from _call_transaction_26
                # ==== CR-0553 END


                call attr_mod(GAME.mc, "REP", 1,50, 100, True) from _call_attr_mod_72
            elif item.ID == "ITMContainerBot":
                $ bot = GAME.unpackBot(GAME.inQueue[0]) # dump first in queue
                queue sound "audio/notify.wav"
                call large_notify("EJECTING STASIS POD", "You eject the stasis pod containing bot {0}.\n\nYour bot is irretrievably lost.".format(C_SU_B+bot.name+C_SU_E), ["Continue"], "08_items/ico ITMContainerBot.png") from _call_large_notify_32
                mc "\"I am not sure this was a good idea...\""
            else:
                $ GAME.ship.cargo.remove(item)

        elif "ejectmore" in _return:
            $ item = _return[1]
            $ qty = GAME.ship.cargo.count(item)
            if qtymode == "5x" and qty > 5:
                $ qty = 5
            elif qtymode == "10x" and qty > 10:
                $ qty = 10
            while qty > 0:
                $ qty -= 1
                $ GAME.ship.cargo.remove(item)
            play sound "audio/load.wav"

        elif "open" in _return:
            $ item = _return[1]
            if item.ID in ["ITMCrateBots"] and not GAME.questSys.isDone('QID_INTRO_LOWER3'):
                queue sound "audio/drone_beep.wav"
                bb2 "\"You need a Bot Lab to deal with these parts on board...\""
                bb2 "\"The Lab in the Lower Decks is not accessible at the moment due to the incident...\""

            elif item.ID in ["ITMCrateBots", "ITMCrateBotsMil", "ITMCrateBotsRare", "ITMCrateBotsPre"]:
                call loot_crate(item) from _call_loot_crate
                $ GAME.mc.hasDone("parts_procured") # bot tutorial procurement quest completion trigger

            elif item.ID == "ITMCrateLiquor":
                call loot_crate(item) from _call_loot_crate_1

        elif "unpack" in _return:
            queue sound "audio/load.wav"
            call stasis_pod_mgr() from _call_stasis_pod_mgr
         
        elif "sell" in _return:
            $ item = _return[1]
        # ============= DEPRECATED, NEVER CALLED ================
            if item.ID == "ITMContainerBot":
                $ bot = GAME.unpackBot(inQueueNew[0][1]) 
                queue sound "audio/notify.wav"
                call large_notify("SELLING STASIS POD", "You sell the stasis pod containing bot {0}.\n\nThe bot container is moved to a special impound for safety inspection.".format(C_SU_B+bot.name+C_SU_E), ["Continue"], "08_items/ico ITMContainerBot.png") from _call_large_notify_33
                $ GAME.mc.hasDone("item sold")      
                mc "\"I am not sure this was a good idea...\""
        # ============= DEPRECATED END ================
            else:
                $ GAME.mc.hasDone("item sold")
                $ GAME.ship.transferWare(item.ID, 1, sLoc)

            call transaction("Wares Sold", sLoc.getPrice(item, "sell"), True) from _call_transaction_27
            $ GAME.mc.tallyUp("Trade Volume (Cr)", sLoc.getPrice(item, "sell"))   



        elif "sellmore" in _return:            
            $ item = _return[1]
            $ GAME.mc.hasDone("item sold")
            $ sAmount = 0
            $ blocked = 0
            $ sold = False
            $ reserved = GAME.missionSys.getReserved()
            $ reserved2 = GAME.missionSys.getReserved2()

            $ qty = GAME.ship.cargo.count(item)
            if qtymode == "5x" and qty > 5:
                $ qty = 5
            elif qtymode == "10x" and qty > 10:
                $ qty = 10

            if item.ID in reserved.keys():
                $ blocked = reserved[item.ID]
            while item in GAME.ship.cargo and qty > 0: #GAME.ship.cargo.count(item) > blocked:
                $ qty -= 1
                $ GAME.ship.transferWare(item.ID, 1, sLoc)

                # $ GAME.ship.cargo.remove(item)
                # $ sLoc.wares.append(item)

                $ sAmount += sLoc.getPrice(item, "sell")
                $ GAME.mc.tallyUp("Trade Volume (Cr)", sLoc.getPrice(item, "sell"))
                $ sold = True
            if sold:
                call transaction("Wares Sold", sAmount, True) from _call_transaction_28
            else:
                play sound "audio/tech_fail.wav"

        #####################################################################
        #					SUBSYSTEMS INSTALL		
        #####################################################################
        # ===== CR-0762 START
        elif "install" in _return and GAME.hour >= 22:
            mc "\"I better do that when I am well rested...\""
        # ===== CR-0762 END


        elif "install" in _return:
            $ item = _return[1]
            $ subSysKey = item.req["slot"]
            if GAME.ship.hasSubSys(subSysKey):
                if GAME.ship.getSubSys(subSysKey) == item.ID:
                    mc "\"I have that one installed already...\""
                else:
                    $ itemRemoved = GAME.ship.swapSubSys(item) 
                    $ GAME.ship.cargo.remove(item)
                    $ GAME.ship.cargo.append(itemRemoved)
                    play sound "audio/install.wav"  
                    "With some help from BB-2, you manage to swap out the subsystems..." with fade
                    call hour_passes() from _call_hour_passes_68                     
            #elif GAME.ship.cargoLoaded() and item.req["slot"] == "cargo":
            #    mc "\"The cargo bay needs to be empty to install that...\""
            else:
                play sound "audio/install.wav"
                "With some help from BB-2, you manage to install the subsystem..." with fade
                call hour_passes() from _call_hour_passes_69
                $ GAME.ship.installSubSys(item)
                $ GAME.ship.cargo.remove(item)
                if item.ID == "ITMMiningMkI":
                    if not GAME.mc.hasDone("mining installed"):
                        hide image "05_gui/mask 50.png"
                        play sound "audio/drone_beep.wav"
                        bb2 "\"Great!\""
                        bb2 "\"The mining laser has been installed successfully!\""
                        bb2 "\"Now head over to the engine terminal and configure it.\""
                        return()


        elif "buy" in _return or "transfer" in _return:
            if GAME.ship.cargoFree() <= 0:
                queue sound "audio/beep.wav"
                call simple_notify("CARGO BAY FULL", "Sell or eject some cargo.", ["Continue"], "05_gui/ico Ship.png") from _call_simple_notify_51
            else:
                $ item = _return[1]
                if _return[0] == "transfer":
                    $ price = 0
                else:
                    $ price = sLoc.getPrice(item, "buy")

                if GAME.money  >= price:
                    $ GAME.ship.cargo.append(item)
                    $ sLoc.wares.remove(item)
                    call transaction("Wares Bought", -price, True) from _call_transaction_29

        elif "buymore" in _return:
            $ item = _return[1] 
            $ qty = min(GAME.ship.cargoFree(), sLoc.wares.count(item))
            if qtymode == "5x" and qty > 5:
                $ qty = 5
            elif qtymode == "10x" and qty > 10:
                $ qty = 10
            $ purchase = False
            while item in sLoc.wares and GAME.money > sLoc.getPrice(item, "buy") and GAME.ship.cargoFree() and qty > 0:
                $ qty -= 1
                $ purchase = True
                $ GAME.ship.cargo.append(item)
                $ sLoc.wares.remove(item)
                call transaction("Wares Bought", -sLoc.getPrice(item, "buy"), False) from _call_transaction_30
            if purchase:
                queue sound "audio/coin.wav"


        else:
            play sound "audio/click.wav"

    return()

#####################################################################
#					MULTIVERSE												  #
#####################################################################
label multiverse_manager(mode="store"):

    # paranoid config 
    $ GAME.podDir = config.savedir    

    # bot function related
    $ botsToStore = []
    $ botsRetrieved = []
    $ botContainer = GAME.items["ITMContainerBot"] # still available bot pods

    # create one-time "shop" for exchange
    $ cargoItems = [x for x in GAME.ship.cargo if x.kind in ["subunit", "subsys", "ware", "module"] or x.ID in ["ITMEternium"]] # CR-0303 # CR-0450 # CR-0531
    if mode == "store":
        $ cargoItems += [botContainer]*5 # CR-0389
    $ podItems = []


    #####################################################################
    #					RETRIEVE		
    #####################################################################
    if mode == "retrieve":
        queue sound "audio/notify.wav"
        call large_notify("WARNING", "The Multiverse Pod can only be opened once per game. Ensure that your cargo capacity is sufficient. Extraneous content of the pod will discarded.\n\nDo you want to continue?", ["Continue", "Abort"], "08_items/ico ITMMultiPod.png", "orange") from _call_large_notify_34
        if _return == "Abort":
            return()
        scene space_bg_smart with fade
        queue sound "audio/teleport.wav"
        show image "08_items/ico ITMMultiPod.png" at truecenter with zoomin
        "A Multiverse Pod appears from the depths of space and time..."
        mc "\"Nice...\""
        mc "\"Let's see, what's in there...\""
        queue sound "audio/install.wav"
        # ===== CR-0588 START
        # python:
        #    with open(GAME.podDir + "/multiverse_pod.json", "r") as f:
        #        podData = json.load(f)
        $ podData = GAME.mvPodData 
        # ===== CR-0588 END
        # differentiate version
        if podData: # nonempty 
            #####################################################################
            #					NEW VERSION		
            #####################################################################
            if "VERSION" in podData[0]: # V0.50 upwards 
                $ podDataVersion = podData[0] 
                $ podItemData = podData[1] 
                $ podBotData = podData[2]
                # reconstruct bots
                $ reconstructedBots = []
                while podBotData:
                    $ bot = GAME.lab.reconstruct(podBotData.pop(0), podDataVersion)
                    $ reconstructedBots.append(bot) 

                # retrieve cargo items 
                $ checksum = podItemData[-1] 
                $ podItemData = podItemData[:-1]
                $ checksum2 = hash(" ".join(podItemData))
                while podItemData:
                    $ podItems.append(GAME.items[podItemData.pop(0)])
                if False: #checksum != checksum2:
                    hide image "08_items/ico ITMMultiPod.png" with dissolve 
                    "As you approach the pod, it becomes unstable and shimmers out of existence..."
                    mc "\"Aaarggh....\""
                    mc "\"It must have been corrupted somehow...\""
                    mc "\"Too bad.\""
                    return()

            #####################################################################
            #					LEGACY		
            #####################################################################
            else: # simple V040 items only
                $ checksum = podData[-1] 
                $ podData = podData[:-1]
                $ checksum2 = hash(" ".join(podData))
                while podData:
                    $ podItems.append(GAME.items[podData.pop(0)])
                if checksum != checksum2:
                    hide image "08_items/ico ITMMultiPod.png" with dissolve 
                    "As you approach the pod, it becomes unstable and shimmers out of existence..."
                    mc "\"Aaarggh....\""
                    mc "\"It must have been corrupted somehow...\""
                    mc "\"Too bad.\""
                    return()

    #####################################################################
    #					STORAGE AND RETRIVAL GUI												  #
    #####################################################################
    while True:

        #####################################################################
        #                PREP INVENTORY
        #####################################################################
        $ cargoItems.sort(key = lambda x: x.name)
        $ podItems.sort(key = lambda x: x.name)

        #####################################################################
        #                STORAGE SHOW SHOP
        #####################################################################
        call screen item_shop_scr(podItems, "POD TRANSFER",  cargoItems, "CARGO ({}t Free)".format(GAME.ship.cargoFree()), [1.0,1.0], "multi")
        if mode == "store":
            if not _return:
                scene space_bg_smart with fade
                show image "08_items/ico ITMMultiPod.png" at truecenter
                # "Executing Transfer..."
                queue sound "audio/teleport.wav"
                queue sound "audio/rumble.wav"
                hide image "08_items/ico ITMMultiPod.png" with zoomout 
                scene space_bg_smart with blueflash
                "You watch the selected components and the pod shimmer and vanish..."
                mc "\"All those expensive parts, gone...\""
                mc "\"Let's hope I will see them again in another universe...\""

                # prepare data structure
                $ podFileVersion = "POD_VERSION_060"

                # items
                $ podItemData = [x.ID for x in podItems] 
                $ podItemData.sort()
                $ podItemData.append(hash(" ".join(podItemData)))

                # bots 
                $ podBotData = []
                python:
                    for bot in botsToStore:
                        bFlatData = GAME.lab.dumpData(bot)      
                        podBotData.append(bFlatData)

                # overall file 
                $ podFileData = [podFileVersion, podItemData, podBotData]

                # write out pod 
                python:
                    with open(GAME.podDir + "/multiverse_pod.json", "w") as f:
                        json.dump(podFileData, f)            

                queue sound "audio/notify.wav"
                call large_notify("SYSTEM INFORMATION", "Your pod content has been stored at {}. It will be automatically found in new games.\n\nBack it up elsewhere if you want multiple pods to avoid overwrite.".format(GAME.podDir+"/multiverse_pod.json"),  ["Continue"], "08_items/ico ITMMultiPod.png", "orange") from _call_large_notify_35

                call sandbox_interior_prepare_scene() from _call_sandbox_interior_prepare_scene_44

                # remove pod
                $ GAME.mc.remItem("ITMMultiPod")
                $ GAME.tags.append("pod_sent")
                return()

            elif "buy" in _return:
                queue sound "audio/tech_fail.wav"

            elif "sell" in _return:
                queue sound "audio/click.wav"
                $ item = _return[1] 
                # special case bot container? 
                if item.ID == "ITMContainerBot":
                    call stasis_pod_mgr("export") from _call_stasis_pod_mgr_1 
                    # call mg_sexbot_bot_storage("export") xxx
                    if _return:
                        play sound "audio/tech_success.wav"
                        $ bot = _return
                        call simple_notify("MULTIVERSE EXPORT", "{} transferred into Pod.".format(C_HI_B+bot.name+C_HI_E),["Continue"], "08_items/ico ITMContainerBot.png") from _call_simple_notify_52
                        $ botsToStore.append(bot)
                        $ cargoItems.remove(item)
                        $ podItems.append(item)
                        #"Foo"
                else:
                    # normal case
                    $ GAME.ship.unloadWare(item.ID)
                    $ cargoItems.remove(item)
                    $ podItems.append(item)

        elif mode == "retrieve":
            if not _return:
                queue sound "audio/beep.wav"
                "Ship Control" "\"Executing Transfer...\""
                scene space_bg_smart
                show image "08_items/ico ITMMultiPod.png" at truecenter 
                queue sound "audio/load.wav"
                "You extract the selected components into your cargobay..."
                queue sound "audio/teleport.wav"
                hide image "08_items/ico ITMMultiPod.png" with zoomout
                queue sound "audio/rumble.wav"
                scene space_bg_smart with blueflash # CR-0328

                "The pod vanishes before your eyes..."
                mc "\"Thank you, other Captain [GAME.mc.name]...\""
                mc "\"Let's install my new components right away...\""
                $ bg = "02_locations/backdrop_{}.png".format(GAME.getStarSys().name.lower())
                scene expression(bg) with fade

                # wipe file / close rift    
                $ GAME.getStarSys().locs["LIDRift"].found = False
                $ GAME.tags.append("pod_retrieved")
                return()

            elif "sell" in _return:
                queue sound "audio/tech_fail.wav"

            elif "buy" in _return:
                queue sound "audio/click.wav"
                $ item = _return[1] 
                if not GAME.ship.cargoFree():
                    play sound "audio/tech_fail.wav"
                elif item.ID == "ITMContainerBot":
                    # ===== CR-0588 START
                    # align unpacking token item with bot queue list
                    if reconstructedBots:
                        $ cargoItems.append(item)
                        $ GAME.ship.packBot(reconstructedBots.pop(), "Pod Retrieval")
                    $ podItems.remove(item)
                    # ===== CR-0588 END

                else:
                    $ GAME.ship.loadWare(item.ID)
                    # pod GUI
                    $ cargoItems.append(item)
                    $ podItems.remove(item)

#####################################################################
#					LOOT CRATES												  #
#####################################################################
label loot_crate(item, tags = [], attr = {}):
    call simple_notify("{}".format(item.name.upper()), "Opening crate...", ["Continue"], "08_items/ico {}.png".format(item.ID)) from _call_simple_notify_53
    $ GAME.ship.unloadWare(item.ID)
   
    if item.ID == "ITMCrateLiquor":
        $ roll = random.choice(["ITMLiquorFairy", "ITMLiquorDrengar", "ITMLiquorIltari"]*4+["ITMLiquorVortex"]) 
        $ amount = random.choice([6,6,6,12,12,18])
        if roll == "ITMLiquorVortex":
            $ amount = 1
        $ loot = GAME.items[roll]     
        queue sound "audio/success.wav"  
        call simple_notify("LIQUOR FOUND", "{}x Bottle of {}".format(amount, loot.getName(["col", "noArt", "cap"])), ["Stash"], "08_items/ico {}.png".format(loot.ID)) from _call_simple_notify_54
        queue sound "audio/load.wav"
        while amount: 
            $ amount -= 1 
            $ GAME.mc.addItem(loot.ID) 

    elif item.ID in ["ITMCrateBots", "ITMCrateBotsMil", "ITMCrateBotsRare", "ITMCrateBotsPre"]:
        $ parts = []
        $ lootReport = ""
        $ crateIco = "08_items/ico {}.png".format(item.ID)
        $ amount = random.choice([3,3,3,3,4,4,4,5,5])

        if item.ID == "ITMCrateBotsRare":
            $ genList = [2,2,2,3]
        else:
            $ genList = [1,1,1,1,1,1,2,2,2,3]

        while amount:
            $ gen = random.choice(genList)
            $ amount -= 1
            $ kind = random.choice(["sexbot addons", "sexbot parts", "sexbot parts", "sexbot parts"])

            if item.ID in ["ITMCrateBotsPre"]:
                $ lootList = [x for x in GAME.sbPartsData.values() if x.slot =="cube"]*3+[GAME.sbPartsData["SBPCortexPre"]]
            elif kind == "sexbot parts":
                $ lootList = [x for x in GAME.sbPartsData.values() if x.kind == kind and x.cat == gen and "no_find" not in x.tags]
            else:
                $ lootList = [x for x in GAME.sbPartsData.values() if x.kind == kind and "no_find" not in x.tags and x.cat == gen]

            $ loot = random.choice(lootList)
            if item.ID == "ITMCrateBotsMil":
                $ loot = loot.clone({"prefs": ["military grade"]})
                $ crateIco = "08_items/ico ITMCrateBotsMil.png"
            elif item.ID == "ITMCrateBotsRare":
                $ loot = loot.clone({"prefs": ["basic", "advanced", "advanced", "advanced", "military grade"]})                
                $ crateIco = "08_items/ico ITMCrateBotsRare.png"
            else:
                $ loot = loot.clone()
            $ lootReport += loot.getName(["col", "noArt", "cap"])+"\n"
            $ parts.append(loot) 

        $ GAME.lab.parts += parts 
        queue sound "audio/success.wav"  
        call large_notify("BOT PARTS FOUND", lootReport, ["Stash"], crateIco) from _call_large_notify_36
        #queue sound "audio/notify.wav"
        #call simple_notify("CRATE SUMMARY", "{}x Bot Parts to Storage".format(len(parts)), ["Continue"], "05_gui/ico Ship.png") 
        queue sound "audio/load.wav"       
    return()

#####################################################################
#					STASIS POD PROCESSOR		
#####################################################################
screen stasis_pod_mgr_scr(*args):

    $ mode = args[0]  # manage, export, warehouse 
    # headline and headers
    text C_HI_B+"{}".format("BOT CONTAINER PROCESSING")+C_HI_E size FSIZE_LARGE xalign 0.5 ypos 100

    #####################################################################
    #					GRID WITH BOT CONTAINERS		
    #####################################################################
    $ gX = 4
    $ gY = int(len(GAME.inQueueNew)/gX)+1

    side "c r":
        area 440,190,1000,620
        viewport id "vp":
            draggable True
            mousewheel True

            grid gX gY xalign 0.5 ypos 190 spacing 10:
                for i in range(gX*gY):
                    if i < len(GAME.inQueueNew):
                        frame xsize 228 ysize 300 padding 20, 20:
                            $ qItem = GAME.inQueueNew[i]
                            if qItem[2] in ["Space Find"]:
                                $ botName = "Unknown"
                                $ botValue = "? Cr"
                                $ botSource = C_HI_B+qItem[2]+C_HI_E
                            elif qItem[2] in ["Arcade Return"]:
                                $ botName = qItem[1].name
                                $ botValue = "{:,} Cr".format(qItem[1].getPrice())
                                $ botSource = C_SU_B+qItem[2]+C_SU_E
                            else:
                                $ botName = qItem[1].name
                                $ botValue = "{:,} Cr".format(qItem[1].getPrice())
                                $ botSource = C_GR_B+qItem[2]+C_GR_E

                            image "08_items/ico ITMContainerBot.png" zoom 0.5 xalign 0.5 yalign 0.0
                            image "03_minigames/ico_type_{}.png".format(qItem[1].getShellConfig().lower()) pos 90,80 zoom 0.75
                            if qItem[1].getIQ() >= 140:
                                image "03_minigames/ico_label_illegal.png"  xalign 1.0 yalign 0.0
                            vbox yalign 1.0 spacing 5: 
                                hbox:
                                    for i in range(qItem[1].getStars()):
                                        image "03_minigames/star.png" zoom 0.5
                                text "{}".format(botName) size FSIZE
                                text "{}".format(C_GO_B+botValue+C_GO_E) size FSIZE_MED
                                text botSource size FSIZE_MED
                            vbox spacing 10:
                                if mode == "manage": # sell, store, unpack to lab
                                    frame xsize 80 ysize 30 background Solid("#0099ccff"):
                                        text "Unpack" size FSIZE_MED xalign 0.5 yalign 0.5
                                        button action Return(["unpack", qItem])
                                    if GAME.ship.status == "docked":
                                        frame xsize 80 ysize 30 background Solid("#0099ccff"):
                                            text "Sell" size FSIZE_MED xalign 0.5 yalign 0.5
                                            button action Return(["auction", qItem])
                                    if GAME.ship.status == "landed" and GAME.ship.surfaceID == "SUIDTenaris" and GAME.surfaces["SUIDTenaris"].elems["SEIDTenarisWarehouse"].found:
                                        frame xsize 80 ysize 30 background Solid("#0099ccff"):
                                            text "Store" size FSIZE_MED xalign 0.5 yalign 0.5
                                            button action Return(["store", qItem])

                                        
                                elif mode == "export": # multiverse only
                                    frame xsize 80 ysize 30 background Solid("#0099ccff"):
                                        text "Store" size FSIZE_MED xalign 0.5 yalign 0.5
                                        button action Return(["export", qItem])

                    else:
                        frame xsize 228 ysize 300 padding 20, 20 background Solid("#00000000"):
                            text " " xalign 0.5 yalign 0.5

        vbar value YScrollValue("vp")



    #####################################################################
    #                EXIT BUTTON, KEYS, ...
    #####################################################################
    frame xsize 350 ysize 64 pos 0,980 background Solid("#00000000") padding 0,0:
        image "05_gui/gui_menu_option.png" yalign 0.5
        button action Return(["exit", None])
        textbutton "Exit (X)" yalign 0.5 action Return(["exit", None])xpos 20
        key "x" action Return(["exit", None])
        key "X" action Return(["exit", None])


label stasis_pod_mgr(mode = "manage"):
    while True:
        call screen stasis_pod_mgr_scr(mode)
        queue sound "audio/click.wav"
        if "exit" in _return:
            queue sound "audio/load.wav"
            return()

        elif "unpack" in _return:
            $ qItem = _return[1]
            $ bot = qItem[1]
            if not GAME.lab.hasFreeCell():
                queue sound "audio/beep.wav"
                call simple_notify("LAB MANAGER", "Free up lab capacity.", ["Continue"]) from _call_simple_notify_55
            elif "bot_intro" not in GAME.mc.done:
                queue sound "audio/drone_beep.wav"
                bb2 "\"You need a Bot Lab to deal with these parts on board...\""
                bb2 "\"The Lab in the Lower Decks is not accessible at the moment due to the incident...\""
            else:
                queue sound "audio/install.wav"
                $ GAME.ship.unpackBot(bot)
                queue sound "audio/notify.wav"
                call large_notify("UNPACKING BOT", "You unpack {0} from the stasis pod and transfer her to the Bot Lab.\n\n{0} is available for reconfiguration now.".format(C_SU_B+bot.name+C_SU_E), ["Continue"], "08_items/ico ITMContainerBot.png") from _call_large_notify_37
                $ GAME.lab.storeBot(bot) 
        
        elif "store" in _return: # send to warehouse:
            $ qItem = _return[1]
            $ bot = qItem[1]   
            $ botTag = "Storage"
            if qItem[2] == "Space Find":
                $ botTag = "Space Find"
            queue sound "audio/load.wav"
            call simple_notify("WAREHOUSE INFO", "Bot moved to warehouse", ["Continue"], "08_items/ico ITMContainerBot.png") from _call_simple_notify_56
             # remove from cargo and store
            $ GAME.ship.unpackBot(bot)            
            $ GAME.base.stockBot(bot, botTag)  


            
        elif "export" in _return: # retrieve for mv pod
            $ qItem = _return[1]
            $ bot = qItem[1]     
            $ GAME.ship.unpackBot(bot)     
            return(bot)

        elif "auction" in _return:
            $ qItem = _return[1]
            $ bot = qItem[1] 
            if bot.getShellConfig() == "I":
                queue sound "audio/notify.wav"
                mc "\"I better not auction off that Infiltrator...\""
                mc "\"I have the feeling I might still need it...\""

            elif bot.isIllegal() and GAME.getSpaceLoc().ID not in ["LIDStationArellarti", "LIDPirate"]:
                queue sound "audio/drone_beep.wav"
                $ msg = GAME.getSpaceLoc().name
                bb2 "\"Bots with an IQ of 140 or higher are illegal to sell at [msg]...\""
                bb2 "\"Try it at the pirate outpost...\""
                bb2 "\"They are known to be less discriminating...\""
            else:
                if qItem[2] in ["Space Find", "Surprise Crate"]:
                    $ price = 50000 
                else:
                    $ price = bot.getPrice() 

                # Bot Valuation
                $ escapeFac = 0.6
                if bot.getEscapeProb() <= 0.0001:
                    $ escapeFac = 1.2 
                elif bot.getEscapeProb() < 0.1:
                    $ escapeFac = 0.9
                elif bot.getEscapeProb() < 0.2:
                    $ escapeFac = 0.8 

                $ price = int(price/100.0*random.uniform(0.8,1.2)*escapeFac)*100 
                 
                # Sale
                queue sound "audio/notify.wav"
                call simple_notify("AUCTION", "You advertise the packaged Bot for sale...".format(bot.name), ["Continue"]) from _call_simple_notify_57
                queue sound "audio/success.wav"
                call large_notify("SELLING STASIS POD", "You receive a number of offers. You accept the best offer of {}{:,} Cr{} for the packaged Bot.\n\nThe Bot container is shipped out to a special impound area in the docking zone.".format(C_GO_B, price, C_GO_E), ["Continue"], "08_items/ico ITMContainerBot.png") from _call_large_notify_38
                $ GAME.ship.unpackBot(bot) # remove bot from cargo  

                # Accounting
                call transaction("Bot Sales (Cr)", price, True) from _call_transaction_31
                $ GAME.mc.tallyUp("Trade Volume (Cr)", price)  
                $ GAME.mc.tallyUp("Bot Sales (Cr)", price)  
                if GAME.mc.getTally("Bot Sales (Cr)") >= 1000000 and not GAME.mc.hasAchievement("million seller"):
                    call achievement_notify(GAME.mc, "million seller", "20_gallery/gallery 83.jpg") from _call_achievement_notify_3   #xxx 
                    $ GAME.galleryAdd(83)  
                $ GAME.mc.tallyUp("Bots Shipped",1) 
                if GAME.mc.getTally("Bots Shipped") == 3:             
                    call achievement_notify(GAME.mc, "Power Seller", "20_gallery/gallery 22.jpg") from _call_achievement_notify_4  
                    $ GAME.galleryAdd(22)                      

    return()

#####################################################################
#					INCOMING CARGO ITEM QUEUE		
#####################################################################
label incoming_cargo_queue():
    if GAME.ship.cargoFree() <= 0:
        return()
    # process incoming item 
    $ processing = True
    $ GAME.inQueuePending.sort(key = lambda x : x[2]) # arrival day sort
    while GAME.ship.cargoFree() and GAME.inQueuePending and processing:
        if GAME.inQueuePending[0][2] > GAME.day:
            $ processing = False
        else:
            $ qItem = GAME.inQueuePending.pop(0)
            $ item = qItem[1]
            $ kind = qItem[0]
            if kind == "bot":
                queue sound "audio/notify.wav"
                call large_notify("DELIVERY DRONE", "A bot stasis pod containing {0} has been returned from the arcade to your ship via a delivery drone as requested.\n\n{0} can be retrieved from her stasis pod in the cargo bay.".format(C_SU_B+item.name+C_SU_E), ["Continue"], "03_minigames/ico_BotArcade.png", "orange") from _call_large_notify_39
                queue sound "audio/install.wav"
                # align unpacking token item with bot queue list
                $ GAME.ship.packBot(item, "Arcade Return")  
            else:
                "Delivery queue processing issue: Unknow Entity '[kind]'"
                "Entity has been purged from queue. It is safe to continue."
    return()