Empty Assemblers 4.5/5 (4)

posted in: Inventory Management | 2

This script will take all of the raw materials (ingots, wafers, etc) out of the assembler and put them back into cargo containers.

This avoids the problem of having items in the assembler and the assembler not being able to produce because it needs some other item as raw material, but there is no room in the raw material inventory in which to put the item.

I *THINK* that this script still has one bug: If there is stuff in the assembler inventory but ALL cargo containers are 100% full, the script will hang. If that happens, it will get killed by the game engine and give you the “Script too complex” message.

  1. void Main()
  2. {
  3.     // Declare and load the list of Assembler blocks
  4.     List<IMyTerminalBlock> assemblers = new List<IMyTerminalBlock>();
  5.     GridTerminalSystem.GetBlocksOfType<IMyAssembler>(assemblers);
  6.  
  7.     // Declare and load the list of CargoContainer blocks
  8.     List<IMyTerminalBlock> containers = new List<IMyTerminalBlock>();
  9.     GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(containers);
  10.  
  11.     // Loop through list of assemblers
  12.     for (int assemblerIndex = 0; assemblerIndex < assemblers.Count; assemblerIndex++)
  13.     {
  14.         // Get the first inventory (the one with the ingots/wafers/etc) for the assembler
  15.         var assemblerInventory = (assemblers&#91;assemblerIndex] as IMyInventoryOwner).GetInventory(0);
  16.  
  17.         // Initialize cargo_touse to -1
  18.         int cargo_touse = -1;
  19.  
  20.         // Check if the assembler has anything in the first inventory. If it doesn't,
  21.         // we skip it (there's nothing to empty)
  22.         if (assemblerInventory.CurrentVolume.RawValue > 0)
  23.         {
  24.             // Grab list of all items in the assembler's first inventory
  25.             var assemblerItems = assemblerInventory.GetItems();
  26.  
  27.             // Loop through the list of cargo containers
  28.             for (int cargoIndex = 0; cargoIndex  < containers.Count; cargoIndex ++)
  29.             {
  30.                 // Get the InventoryOwner object from the container
  31.                 var cargoInventoryOwner = containers&#91;cargoIndex] as IMyInventoryOwner;
  32.  
  33.                 // If the cargoInventoryOwner is not null (it shouldn't be, but we'll check
  34.                 // anyway) and the first inventory (cargo containers only have one, but it is
  35.                 // still a List of inventories object) is not full
  36.                 if (cargoInventoryOwner != null && !cargoInventoryOwner.GetInventory(0).IsFull)
  37.                 {
  38.                     // Set the cargo_touse variable to the index of the current cargo container
  39.                     // in the list. This is the cargo container that we are going to use to store
  40.                     // the items (assemblerItems) we remove from the assembler.
  41.                     cargo_touse = cargoIndex;
  42.  
  43.                     // Since we already have a cargo container to use, break out of the loop
  44.                     break;
  45.                 }
  46.             }
  47.  
  48.             // If cargo_touse is still -1 (which we set at the beginning of the assembler
  49.             // loop) it means that either the assumbler was already empty, or that we  
  50.             // couldn't find a container with available space. So only execute the code
  51.             // below if cargo_touse is not -1
  52.             if (cargo_touse != -1)
  53.             {
  54.                 // Get the InventoryOwner object from the container pointed to by the
  55.                 // cargo_touse variable
  56.                 var cargoInventoryOwner = containers&#91;cargo_touse] as IMyInventoryOwner;
  57.  
  58.                 // If the cargoInventoryOwner object is not null (it shouldn't be, but  
  59.                 // we'll check anyway)
  60.                 if (cargoInventoryOwner != null)
  61.                 {
  62.                     // Get the first inventory of the cargoInventoryOwner object (cargo
  63.                     // containers only have one, but it is still a List of inventories  
  64.                     // object)
  65.                     var cargoInventory = cargoInventoryOwner.GetInventory(0);
  66.  
  67.                     // Loop through the assemblerItems list that we retrieved up top
  68.                     // (when we determined that the assembler was not empty). Notice
  69.                     // that we loop through the assemblerItems list backwards (we start
  70.                     // at the last item and move toward the first as the loop progresses.
  71.                     // This is because if you don't do that (unless you control it in some
  72.                     // other fashion), you will process one, skip one, process one,
  73.                     // skip one, etc. The reason this happens is because when you transfer
  74.                     // an item to the cargo container, if that slot in the inventory is
  75.                     // then empty, the slot disappears from the list, and the next item
  76.                     // in the list now occupies that slot. But you already processed that
  77.                     // slot and when the loop restarts, you skip to the next item.
  78.                     for (int assemblerItem = assemblerItems.Count-1; assemblerItem >= 0; assemblerItem--)
  79.                     {
  80.                         // Check to see if the cargoInventory is *STILL* not full. Since we
  81.                         // are inside a loop, we might have already moved stuff to the cargo
  82.                         // container and have filled it up. So before we try to move anything,
  83.                         // we check again to make sure there is still room. If it's not full,
  84.                         // go ahead and transfer the item from the assembler inventory to the
  85.                         // cargo container inventory
  86.                         if (!cargoInventory.IsFull)
  87.                         {
  88.                             assemblerInventory.TransferItemTo(cargoInventory, assemblerItem , null, true, null);
  89.                         }
  90.                         // If the cargoInventory is now full, it means we filled it up (because
  91.                         // it wasn't full when we entered this assemblerItem loop. This means  
  92.                         // that there is still stuff in the assembler inventory that wasn't  
  93.                         // transferred. If we let the assembler loop continue as-is, it will
  94.                         // skip to the next assembler and the items remaining in the current
  95.                         // assembler's inventory will remain there. So...
  96.                         else
  97.                         {
  98.                             // We decrement the assemblerIndex variable (the one that controls
  99.                             // the assembler loop. That way, when the loop starts again, it will
  100.                             // process the current assembler again and, hopefully, find another
  101.                             // non-full cargo container to transfer stuff to.
  102.                             assemblerIndex--;
  103.  
  104.                             // Break out of the current (assemblerItems) loop, because the cargo
  105.                             // container filled up, so no point in continuing. We need to find  
  106.                             // another cargo container to use to transfer items
  107.                             break;
  108.                         }
  109.                     }
  110.                 }
  111.             }
  112.         }
  113.     }
  114. }

Please rate this post

2 Responses

  1. >>I *THINK* that this script still has one bug: If there is stuff in the assembler inventory but ALL cargo containers >>are 100% full, the script will hang. If that happens, it will get killed by the game engine and give you the “Script >>too complex” message.

    This happens because when you indexed the last container and it is full, you decrease the index of the for loop (line 102: assemblerIndex–) then the for loop (line 12) will never terminate.

    • That is entirely possible… I’ll look at it and see if I can implement a fix. Thanks for the heads-up!

Leave a Reply