1. This forum is obsolete and read-only. Feel free to contact us at support.keenswh.com

Item Transfer Script throwing exception

Discussion in 'Programming (In-game)' started by SubtleSloth, Apr 8, 2019.

  1. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    Hey guys,

    I've been trying to write a simple item transfer script so I can get the idea down before I write a larger script with this one incorporated into it. This one, I thought was going to be straight forward...but I keep getting this:

    "Caught exception during execution of script: The given key was not present in the dictionary.
    at System.ThrowHelper.ThrowKeyNotFoundException()
    at System.Collections.Generic.Dictionary'2.get_Item(Tkey key)
    at Program.Main(string argument)
    at Sandbox.Game.Entities.Blocks.MyProgrammableBlock.<>c__DisplayClass26.<ExecuteCode>b__25(IMyGridProgram program)
    at Sandbox.Game.Entities.Blocks.MyProgrammableBlock.RunSandboxedProgramAction(Action'1 action, String& response)

    All I am trying to do is transfer Uranium Ingots to a reactor if it doesn't have enough fuel.

    Code:
    void Main(string argument)
    {
    	Echo("A");
    	IMyReactor LRTest = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR Test");
    	Echo("B");
    	IMyInventory ReactorInv = LRTest.GetInventory(0);
    	Echo("C");
    	IMyCargoContainer LCCTest =(IMyCargoContainer)GridTerminalSystem.GetBlockWithName("LCC Test");
    	Echo("D");
    	IMyInventory Cargo = LCCTest.GetInventory(0);
    	Echo("E");
    	var iType = new MyItemType("Ingot", "Uranium");
    	Echo("F");
    	var item = (MyInventoryItem)Cargo.FindItem(iType);
    	Echo("G");
    
    	if (ReactorInv.GetItemAmount(iType) < 10)
    	{
    		Cargo.TransferItemTo(ReactorInv, item, 10);
    		Echo("H");
    	}
    	else
    	{
    		Echo("Fuel Good");
    		Echo("I");
    	}
    }
    When I run the program, it Echos A through E, then throws the exception. I have moved the line 'var iType = new MyItemType("Ingot", "Uranium");' to another echo point to see if that was actually the problem line and it has thrown the same exception, except at the new line location.

    Can anyone tell me what I am doing wrong and how to fix it?
     
  2. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Hey man I'm fixing this right now and adding some more stuff too I'll post the script when I finish here.
     
  3. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Hey man I've been working on this script for a while now when it hit me. What's the purpose of this script? Uranium ingots automatically transfer into reactors...
     
  4. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Anyway here's the script.
    Code:
    /*Change these to your reactor, conveyor sorter, storage, and LCD Name. Set the minimum amount of Uranium you want to
    keep in your reactor. No need to touch the sorter or LCD the code does it for you */
    string ReactorName = "Reactor";
    string StorageName = "Storage";
    string LCDName = "Uranium Display";
    string ConveyorSorterName = "Uranium Sorter";
    int MinimumReactorUranium = 10;
    
    public Program()
    {
    	//Setting Frequency of the Code
    	Runtime.UpdateFrequency = UpdateFrequency.Update10;
    	//Setting Up Conveyer
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    	IMyConveyorSorter Conveyor = GridTerminalSystem.GetBlockWithName(ConveyorSorterName) as IMyConveyorSorter;
    	List<MyInventoryItemFilter> filterlist = new List<MyInventoryItemFilter>();
    	MyInventoryItemFilter UI = new MyInventoryItemFilter(iType);
    	filterlist.Add(UI);
    	Conveyor.SetFilter(MyConveyorSorterMode.Whitelist, filterlist);
    	//Setting Up LCD
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    	LCD.SetValue("Content", Convert.ToInt64(2));
    }
    public void Save()
    {
    }
    public void Main()
    {
    	decimal ReactorUranium = 0;
    	decimal StorageUranium = 0;
    
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium"); //Uranium ItemType
    	IMyConveyorSorter Conveyor = GridTerminalSystem.GetBlockWithName(ConveyorSorterName) as IMyConveyorSorter;
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    	//Setting Up Inventories
    	IMyReactor Reactor = GridTerminalSystem.GetBlockWithName(ReactorName) as IMyReactor;
    	IMyInventory ReactorInv = Reactor.GetInventory();
    	IMyCargoContainer Storage = GridTerminalSystem.GetBlockWithName(StorageName) as IMyCargoContainer;
    	IMyInventory StorageInv = Storage.GetInventory();
    
    	//Searching Reactor for Uranium Ingots
    	try
    	{
    		string ReactorUraniumTemp = ReactorInv.FindItem(iType).ToString();
    		ReactorUraniumTemp = ReactorUraniumTemp.Substring(0, ReactorUraniumTemp.IndexOf("x"));
    		ReactorUranium = Convert.ToDecimal(ReactorUraniumTemp);
    	}
    	catch
    	{
    		ReactorUranium = 0;
    
    	}
    	//Searching Cargo for Uranium Ingots
    	try
    	{
    		string StorageUraniumTemp = StorageInv.FindItem(iType).ToString();
    		StorageUraniumTemp = StorageUraniumTemp.Substring(0, StorageUraniumTemp.IndexOf("x"));
    		StorageUranium = Convert.ToDecimal(StorageUraniumTemp);
    	}
    	catch
    	{
    		StorageUranium = 0;
    	}
    	
    	//Enabling Conveyor and allowing Uranium into the reactor
    		if (ReactorUranium <= MinimumReactorUranium && StorageUranium > 0)
    		{
    		Conveyor.ApplyAction("OnOff_On");
    		}
    		else
    		{
    		Conveyor.ApplyAction("OnOff_Off");
    		}
    
    	Echo("Reactor Uranium: " + ReactorUranium.ToString() + "\n" + "Storage Uranium: " + StorageUranium.ToString());
    	LCD.WriteText("Reactor Uranium: " + ReactorUranium.ToString() + "\n" + "Storage Uranium: " + StorageUranium.ToString());
    }
    
     
  5. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @GreenBeanio

    Dude, Thank you. That’s all I can say. I have been racking my brain trying to figure this thing out for days. I also understand that the reactors automatically siphon uranium from wherever they can, this was just a test script for a later, much larger script with instances of checking for components inside a cargo container. But also, I was hoping I could get the the reactors to instantaneously get the fuel instead of waiting for the conveyors to do the work, but I’m ok with either at this point .

    As for the purpose of the script, it will be part of an automating system for my space elevator cable builder. It will be one of the checks before the building cart disconnects from the tower and starts moving on the rails again.

    Again, THANK YOU SO MUCH! i am going to pick apart what you’ve done here and try and learn from it. I’ll give you an update once I get it all together and functioning properly.

    Also, is there any documentation that can show me what the parameters inside the () of MyItemType have to be when checking for stuff like ingots and such? Where can I find that? The MyObjectBuilder_ Ingot seems to be what I was missing, and I have no clue where I would find a list of those things. I don’t think it’s on Malware’s API index, but I could be wrong.
    --- Automerge ---
    @GreenBeanio

    As I thought, as soon as I changed "Ingot" to "MyObjectBuilder_Ingot" in the typeId parameter of MyItemType, the original script worked exactly as I intended...

    Thank you so much man, this is exactly what I have been trying to figure out. I still plan on using some of your code I think though after I figure out how it all works!
     
  6. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Hey man I'm on my laptop right now but once I get on my main pc I'll send you the little codeblock I used to get the name. One of the reasons that I changed your script so drastically is because I wanted it to scan the entire cargo container for uranium instead of it having to be in the first spot. That's one of the reasons I used the sorters as well because I couldn't figure out how to get the location of the item in the container with a script. Another thing is since reactors can only hold uranium ingots I can scrap part of the code, I'll send the change later too.
     
  7. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    Thanks for the help man, I appreciate it. Also, couldn’t we declare the variable
    Code:
    IMyInventory Cargo = LCCTest.GetInventory()
    Instead of with the 0 in the ()?

    And then use Cargo.GetItemAmount(iType) to figure out how much uranium is in a storage container regardless of the inventory slot?
     
  8. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    See that's what I meant by I wanted it to search the whole container. If you know 100% that you will always keep your uranium in the first spot of storage then yes. That's a fixed point so it has to be in that exact spot for it to read it. With the conveyors in the script I wrote it can grab it from anywhere in the container. You can with 100% positivity (I think) change the reactor to that since it'll always only have uranium and will keep it in the first spot.
    --- Automerge ---
    I'll rewrite the code a bit for you here so you see what I'm talking about, but know that if you don't use the try and catch or some kind of if and else it'll make an error in the script if uranium isn't found in that position.
    --- Automerge ---
    Code:
    /*Change these to your reactor, conveyor sorter, storage, and LCD Name. Set the minimum amount of Uranium you want to
    keep in your reactor. No need to touch the sorter or LCD the code does it for you */
    string ReactorName = "Reactor";
    string StorageName = "Storage";
    string LCDName = "Uranium Display";
    string ConveyorSorterName = "Uranium Sorter";
    int MinimumReactorUranium = 10;
    //Change to true if keeping Uranium in a specific spot, and change fixed point (Default is the first inventory space)
    bool SpecificUraniumPlacement = false;
    MyFixedPoint FixedPoint = 0;
    
    public Program()
    {
    	//Setting Frequency of the Code
    	Runtime.UpdateFrequency = UpdateFrequency.Update10;
    	//Setting Up Conveyer
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    	IMyConveyorSorter Conveyor = GridTerminalSystem.GetBlockWithName(ConveyorSorterName) as IMyConveyorSorter;
    	List<MyInventoryItemFilter> filterlist = new List<MyInventoryItemFilter>();
    	MyInventoryItemFilter UI = new MyInventoryItemFilter(iType);
    	filterlist.Add(UI);
    	Conveyor.SetFilter(MyConveyorSorterMode.Whitelist, filterlist);
    	//Setting Up LCD
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    	LCD.SetValue("Content", Convert.ToInt64(2));
    }
    public void Save()
    {
    }
    public void Main()
    {
    	MyFixedPoint ReactorUranium = 0;
    	MyFixedPoint StorageUranium = 0;
    
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium"); //Uranium ItemType
    	IMyConveyorSorter Conveyor = GridTerminalSystem.GetBlockWithName(ConveyorSorterName) as IMyConveyorSorter;
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    	//Setting Up Inventories
    	IMyReactor Reactor = GridTerminalSystem.GetBlockWithName(ReactorName) as IMyReactor;
    	IMyInventory ReactorInv = Reactor.GetInventory();
    	IMyCargoContainer Storage = GridTerminalSystem.GetBlockWithName(StorageName) as IMyCargoContainer;
    	IMyInventory StorageInv = Storage.GetInventory();
    
    	//Searching Reactor for Uranium Ingots
    	try
    	{
    		ReactorUranium = ReactorInv.GetItemAmount(iType);
    	}
    	catch
    	{
    		ReactorUranium = 0;
    	}
       
    	//Searching Storage for Uranium Based on the mode selected
    	if(SpecificUraniumPlacement == false)
    	{
    	   
    		//Searching Cargo for Uranium Ingots
    		try
    		{
    			StorageUranium = StorageInv.GetItemAmount(iType);
    		}
    		catch
    		{
    			StorageUranium = 0;
    		}
    	}
    	else
    	{
    		try
    		{ 
    			if(StorageInv.ContainItems(FixedPoint, iType) == true)
    			{
    				StorageUranium = StorageInv.GetItemAmount(iType);
    			} 
    		}
    		catch
    		{
    			StorageUranium = 0;
    		}
    	}
       
    	//Enabling Conveyor and allowing Uranium into the reactor
    		if (ReactorUranium <= MinimumReactorUranium && StorageUranium > 0)
    		{
    		Conveyor.ApplyAction("OnOff_On");
    		}
    		else
    		{
    		Conveyor.ApplyAction("OnOff_Off");
    		}
    
    	Echo("Reactor Uranium: " + ReactorUranium.ToString() + "\n" + "Storage Uranium: " + StorageUranium.ToString());
    	LCD.WriteText("Reactor Uranium: " + ReactorUranium.ToString() + "\n" + "Storage Uranium: " + StorageUranium.ToString());
    }
    
    There's the updated code that allows for selecting between searching the whole storage and selecting a specific spot. I also improved the logic a bit.

    Code:
    	List<MyInventoryItem> yes = new List<MyInventoryItem>();
    	StorageInv.GetItems(yes);
    	foreach(var display in yes)
    	{
    		Echo(display.ToString());
    	}
    There's the little script you can throw in anywhere to get all the item names and stuff.
    --- Automerge ---
    Also, I hope you're fine that I added an LCD alongside the Echo. I put one of those on all my projects without thinking.
     
  9. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    I think I’m missing something lol. If we do the first one, I am under the impression that it will search the entire inventory, and get the items regardless of their location. Am I right? Or do I have a serious misconception of .GetItemAmount()?
     
  10. Sinus32

    Sinus32 Trainee Engineer

    Messages:
    22
    The other types are:
    Code:
    private const string OreType = "MyObjectBuilder_Ore";
    // eg: new MyItemType(OreType, "Uranium");
    private const string IngotType = "MyObjectBuilder_Ingot";
    // eg: new MyItemType(IngotType, "Uranium");
    private const string ComponentType = "MyObjectBuilder_Component";
    // eg: new MyItemType(ComponentType, "SteelPlate");
    private const string AmmoType = "MyObjectBuilder_AmmoMagazine";
    // eg: new MyItemType(AmmoType, "NATO_25x184mm");
    private const string OxygenType = "MyObjectBuilder_OxygenContainerObject";
    // eg: new MyItemType(OxygenType, "OxygenBottle");
    private const string GasType = "MyObjectBuilder_GasContainerObject";
    // eg: new MyItemType(GasType, "HydrogenBottle");
    private const string GunType = "MyObjectBuilder_PhysicalGunObject";
    // eg: new MyItemType(GunType, "WelderItem");
    Full list can be extracted from xml files located in "<SteamLibrary>\steamapps\common\SpaceEngineers\Content\Data\*.sbc"

    You can also extract names from mods. Required data can be found in zip archives located in "<SteamLibrary>\steamapps\workshop\content\244850\**\*_legacy.bin", which contains ".sbc" files.
     
  11. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Ohhhh I see what I thought. When you said

    I thought you meant putting the 0 in the () not taking it out. Because in my scripts I never put the 0 in, but you did in yours. And alright I gotta admit something here I way over engineered my script to work specifically for uranium to a reactor, which needs a conveyor for it not to drag all uranium over at all times. Now if you want to drag over other items then bam that's easy peasy. Your script basically already had that figured out besides the ingot name and a try catch to stop it from breaking when there's no uranium in the storage container.
    Code:
    public Program()
    
    
    {
    
    	Runtime.UpdateFrequency = UpdateFrequency.Update10;
    }
    
    
    
    public void Save()
    
    {
    
    }
    
    
    
    void Main()
    {
    		IMyCargoContainer Cargo1 = GridTerminalSystem.GetBlockWithName("Cargo 1") as IMyCargoContainer;
    		IMyInventory Cargo1Inv = Cargo1.GetInventory();
    
    		IMyCargoContainer Cargo2 = GridTerminalSystem.GetBlockWithName("Cargo 2") as IMyCargoContainer;
    		IMyInventory Cargo2Inv = Cargo2.GetInventory();
      
    	MyInventoryItem item = new MyInventoryItem();
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
      
    	try
    	{
    			item = (MyInventoryItem)Cargo1Inv.FindItem(iType);
    		Echo("Uranium is in Container 1");
    	}
    	catch
    	{
    		Echo("No Uranium in Container 1");
    	}
    
    		if (Cargo2Inv.GetItemAmount(iType) < 10)
    		{
    				Cargo1Inv.TransferItemTo(Cargo2Inv, item, 10);
    		Echo("Cargo 2 Need Uranium");
    		}
    		else
    		{
    				Echo("Uranium is in Cargo 2");
    		}
    }
    
    That's basically just your original script but instead of a reactor, it has two large containers. It will transfer whatever over from container 1 to 2. I still have it set up for uranium though. Hit me up with whatever else you need man we're going to make this space elevator thing working.
    --- Automerge ---
    Ignore the weird spacing in that script too I don't know why it looks like that
    --- Automerge ---
    Code:
    //Variables to change if you want to
    int TransferAmount = 10;
    int Storage2Minimum = 10;
    String Storage1Name = "Cargo 1";
    String Storage2Name = "Cargo 2";
    String LCDName = "Display";
    
    public Program()
    
    {
    
    	//Setting Up Frequency
    	Runtime.UpdateFrequency = UpdateFrequency.Update10;
    	//Setting Up LCD
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    	LCD.SetValue("Content", Convert.ToInt64(2));
    }
    
    
    
    public void Save()
    
    {
    
    }
    
    
    
    void Main()
    {
    	//Setting Up Everything
    		IMyCargoContainer Cargo1 = GridTerminalSystem.GetBlockWithName(Storage1Name) as IMyCargoContainer;
    		IMyInventory Cargo1Inv = Cargo1.GetInventory();
    
    		IMyCargoContainer Cargo2 = GridTerminalSystem.GetBlockWithName(Storage2Name) as IMyCargoContainer;
    		IMyInventory Cargo2Inv = Cargo2.GetInventory();
    	
    	MyInventoryItem item1 = new MyInventoryItem();
    	MyInventoryItem item2 = new MyInventoryItem();
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    
    	IMyTextPanel LCD = GridTerminalSystem.GetBlockWithName(LCDName) as IMyTextPanel;
    
    	MyFixedPoint Storage1Uranium = 0;
    	MyFixedPoint Storage2Uranium = 0;
    	String TransferStatus;
    	
    	//Checking Storages for Uranium
    	try
    	{
    			item1 = (MyInventoryItem)Cargo1Inv.FindItem(iType);
    		Storage1Uranium = Cargo1Inv.GetItemAmount(iType);
    	}
    	catch
    	{
    		Storage1Uranium = 0;
    	}
    	try
    	{
    			item2 = (MyInventoryItem)Cargo2Inv.FindItem(iType);
    		Storage2Uranium = Cargo2Inv.GetItemAmount(iType);
    	}
    	catch
    	{
    		Storage2Uranium = 0;
    	}
    
    	//Transfering
    		if (Storage2Uranium < Storage2Minimum && Storage1Uranium > 0)
    		{
    				Cargo1Inv.TransferItemTo(Cargo2Inv, item1, TransferAmount);
    		TransferStatus = "Transferring";
    		}
    		else
    		{
    		TransferStatus = "Not Transferring";
    		}
    
    	Echo("Storage 1 Uranium: " + Storage1Uranium + "\n" + "Storage 2 Uranium: " + Storage2Uranium + "\n" + "Transfer Status: " + TransferStatus);
    	LCD.WriteText("Storage 1 Uranium: " + Storage1Uranium + "\n" + "Storage 2 Uranium: " + Storage2Uranium + "\n" + "Transfer Status: " + TransferStatus);
    }
    
    Updated the code a little bit more
     
  12. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @Sinus32

    Thank Man! I was completely lost as to where to find that stuff.

    @GreenBeanio

    I just tested the script with the uranium in a spot other than the first one to prove that we both aren't going insane lol. .GetInventory() does indeed get the entire inventory regardless of location of items. Again, thanks a ton for your help bud, I'll post any further issues in this thread if you wanna keep an eye on it. I should have the thing automated within a week or two, considering I have a 2-year-old to run after :p
     
  13. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Ah alright man I will keep checking in if you got any more questions. And yeah man I know that GetInventory() will scan the whole container but I thought having the 0 in wouldn't. I guess they have it set so the inventory starts on 1 not 0, not used to that in programming I guess.
     
  14. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    I changed the code to .GetInventory() without the 0 to make it work, I haven’t tried with the other items in the inventory with the 0 in the code. But I’m pretty sure you were correct in saying that it will make it scan only that inventory slot.
    --- Automerge ---
    New discovery, I have no idea what the number in the () of .GetInventory() does. I just tried making both the Cargo and the Reactor.GetInventory(0) and I got the same exact result as if nothing was there. @Sinus32 maybe you could shed some light bud?
     
  15. Malware

    Malware Master Engineer

    Messages:
    9,867
    Some blocks, like the assembler and refinery, have more than one inventory. (input/output) The number is the inventory index.
     
  16. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @Malware
    Thanks for that info man. Is there any documentation that shows us which number is for input or output? Or should I just write a program and figure out which one is which?
     
  17. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @GreenBeanio

    Alright, here's the code so far. Haven't exactly gotten a design for the elevator up and running yet, but I will design it around the code, and if I have to add anything, which I already know I will, I'll do it once the bottom section is made. The numbers in the ComponentSearch() Method are based on what I would need for the current design that I have running in creative. I don't plan on using that design, but I will most likely test the program on it.

    Code:
    public class ConnectorLogic: MyGridProgram
    {
    	IMyShipConnector PlatConn;
    	IMyReactor BaseReactor;
    	IMyReactor LR1;
    	IMyReactor LR2;
    	IMyCargoContainer LCC;
    	IMyInventory LR1Inv;
    	IMyInventory LR2Inv;
    	IMyInventory BaseReactorInv;
    
    	void Main(string argument)
    	{
    		PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    
    		if (PlatConn.Status == MyShipConnectorStatus.Connectable)
    		{
    			PlatConn.ApplyAction("Lock");
    		}
    		else if (PlatConn.Status == MyShipConnectorStatus.Connected)
    		{
    			FuelCheck();
    		}
    	}
    
    	void FuelCheck()
    	{
    		LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    		LR1Inv = LR1.GetInventory();
    		LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    		LR2Inv = LR2.GetInventory();
    		MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    		var LR1Fuel = LR1Inv.GetItemAmount(iType);
    		var LR2Fuel = LR2Inv.GetItemAmount(iType);
    
    		if (LR1Fuel < 10 || LR2Fuel < 10)
    		{
    			FuelTransfer();
    		}
    		else
    		{
    			ComponentSearch();
    		}
    	}
    
    	void ComponentSearch()
    	{
    		LCC = (IMyCargoContainer)GridTerminalSystem.GetBlockWithName("LCC");
    		IMyInventory Storage = LCC.GetInventory();
    
    		MyItemType iType2 = new MyItemType("MyObjectBuilder_Component", "SteelPlate");
    		MyItemType iType3 = new MyItemType("MyObjectBuilder_Component", "Construction");
    		MyItemType iType4 = new MyItemType("MyObjectBuilder_Component", "InteriorPlate");
    		MyItemType iType5 = new MyItemType("MyObjectBuilder_Component", "Motor");
    		MyItemType iType6 = new MyItemType("MyObjectBuilder_Component", "LargeTube");
    		MyItemType iType7 = new MyItemType("MyObjectBuilder_Component", "SmallTube");
    		MyItemType iType8 = new MyItemType("MyObjectBuilder_Component", "Computer");
    
    		if (Storage.GetItemAmount(iType2) >= 62000 && Storage.GetItemAmount(iType3) >= 2100 && Storage.GetItemAmount(iType4) >= 1400 && Storage.GetItemAmount(iType5) >= 600 && Storage.GetItemAmount(iType6) >= 20 && Storage.GetItemAmount(iType7) >= 1300 && Storage.GetItemAmount(iType8) >= 50)
    		{
    			Disconnect();
    		}
    		else
    		{
    			ComponentSearch();
    		}
    	}
    
    	void FuelTransfer()
    	{
    		LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    		LR1Inv = LR1.GetInventory();
    		LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    		LR2Inv = LR2.GetInventory();
    		BaseReactor = (IMyReactor)GridTerminalSystem.GetBlockWithName("Base Reactor");
    		BaseReactorInv = BaseReactor.GetInventory();
    		MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    		var item = (MyInventoryItem)BaseReactorInv.FindItem(iType);
    		var LR1Fuel = LR1Inv.GetItemAmount(iType);
    		var LR2Fuel = LR2Inv.GetItemAmount(iType);
    
    		if (LR1Fuel < 10 && LR2Fuel < 10)
    		{
    			BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    			BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    		}
    		else if(LR1Fuel < 10 && LR2Fuel >= 10)
    		{
    			BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    		}
    		else if(LR2Fuel < 10 && LR1Fuel >= 10)
    		{
    			BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    		}
    	}
    
    	void Disconnect()
    	{
    		PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    		PlatConn.ApplyAction("Unlock");
    	}
    }
    The only issue I have so far, is that the program compiles just fine, but when I hit run, it give me a "Main method not found. Please add Main method into script" error...and now I am thoroughly confused lol.
    --- Automerge ---
    Fixed the Main() Method thing...apparently ingame scripts don't like classes =/
     
  18. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Yeah I was gonna say I don't think that script would work. You gotta remember that the program block scripts are all this kind of self-contained thing. So you can make custom classes in the script but they need to be separate. I'd also add back in the public Program() method just in case you ever want to set some variables on start. The issue I see happening with this script though is even though it checks for Uranium and tells it to transfer the moment you connect it's going to drain uranium anyway. It might just be more worthwhile to check if the tanks have fuel continuously and set a bool for disconnect based on if they have it. Unless you do end up using a conveyor with the reactor it's going to keep draining uranium from the base regardless.
    Code:
    IMyShipConnector PlatConn;
    //	IMyReactor BaseReactor;
    	IMyReactor LR1;
    	IMyReactor LR2;
    	IMyCargoContainer LCC;
    	IMyInventory LR1Inv;
    	IMyInventory LR2Inv;
    	//IMyInventory BaseReactorInv;
    
    bool ShipIsFueled;
    
    public Program()
    
    {
    
    	//Setting Frequency of the Code
    	Runtime.UpdateFrequency = UpdateFrequency.Update10;
    }
    
    
    
    public void Save()
    
    {
    
    	
    }
    
    public 	void Main(string argument)
    	{
    			PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    
    			if (PlatConn.Status == MyShipConnectorStatus.Connectable)
    			{
    				PlatConn.ApplyAction("Lock");
    			}
    			else if (PlatConn.Status == MyShipConnectorStatus.Connected)
    			{
    				FuelCheck();
    	ComponentSearch();
    			}
    	}
    
    	void FuelCheck()
    	{
    			LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    			LR1Inv = LR1.GetInventory();
    			LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    			LR2Inv = LR2.GetInventory();
    			MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    			var LR1Fuel = LR1Inv.GetItemAmount(iType);
    			var LR2Fuel = LR2Inv.GetItemAmount(iType);
    
    	if(LR1Fuel >= 10 && LR2Fuel >= 10)
    	{
    		ShipIsFueled = true;
    	}
    	else
    	{
    		ShipIsFueled = false;
    	}
    
    		/*	if (LR1Fuel < 10 || LR2Fuel < 10)
    			{
    				FuelTransfer();
    			}
    			else
    			{
    				ComponentSearch();
    			}*/
    	}
    
    	void ComponentSearch()
    	{
    			LCC = (IMyCargoContainer)GridTerminalSystem.GetBlockWithName("LCC");
    			IMyInventory Storage = LCC.GetInventory();
    
    			MyItemType iType2 = new MyItemType("MyObjectBuilder_Component", "SteelPlate");
    			MyItemType iType3 = new MyItemType("MyObjectBuilder_Component", "Construction");
    			MyItemType iType4 = new MyItemType("MyObjectBuilder_Component", "InteriorPlate");
    			MyItemType iType5 = new MyItemType("MyObjectBuilder_Component", "Motor");
    			MyItemType iType6 = new MyItemType("MyObjectBuilder_Component", "LargeTube");
    			MyItemType iType7 = new MyItemType("MyObjectBuilder_Component", "SmallTube");
    			MyItemType iType8 = new MyItemType("MyObjectBuilder_Component", "Computer");
    
    			if (Storage.GetItemAmount(iType2) >= 62000 && Storage.GetItemAmount(iType3) >= 2100 && Storage.GetItemAmount(iType4) >= 1400 && Storage.GetItemAmount(iType5) >= 600 && Storage.GetItemAmount(iType6) >= 20 && Storage.GetItemAmount(iType7) >= 1300 && Storage.GetItemAmount(iType8) >= 50 && ShipIsFueled == true)
    			{
    				Disconnect();
    			}
    			else
    			{
    				ComponentSearch();
    			}
    	}
    
    /*	void FuelTransfer()
    	{
    			MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    
    			LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    			LR1Inv = LR1.GetInventory();
    			LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    			LR2Inv = LR2.GetInventory();
    		var LR1Fuel = LR1Inv.GetItemAmount(iType);
    			var LR2Fuel = LR2Inv.GetItemAmount(iType);
    			BaseReactor = (IMyReactor)GridTerminalSystem.GetBlockWithName("Base Reactor");
    			BaseReactorInv = BaseReactor.GetInventory();
    			var item = (MyInventoryItem)BaseReactorInv.FindItem(iType);
    
    			if (LR1Fuel < 10 && LR2Fuel < 10)
    			{
    					BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    					BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    			}
    				else if(LR1Fuel < 10 && LR2Fuel >= 10)
    			{
    					BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    			}
    				else if(LR2Fuel < 10 && LR1Fuel >= 10)
    			{
    					BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    			}
    	}*/
    
    	void Disconnect()
    	{
    			PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    			PlatConn.ApplyAction("Unlock");
    }
    
    I edited the code a little bit to use the bool I meant and commented out the rest of your script just to see what I mean. You also need to remember to set the frequency in the program() or it wont run.
     
  19. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @GreenBeanio

    So, I have a working version of the script. I had change a few things, and it's not completely finished yet, but so far, it compiles, runs, and doesn't throw any errors in my face, so that is a start :D. The ComponentTransfer() method I am pretty proud of because it is the first time I actually sat down and really thought myself through exactly what I wanted the method to do, used my brain a little, and wrote it from nothing. When I compiled it for the first time, it ran perfectly as I intended it to with no errors...I almost crapped my pants :woot:. Also, I have been thinking about the Uranium transfer thing, I think all I have to do is turn off the "Use Conveyors" property on the platform reactors and it won't drain the uranium unless I tell it to transfer. There are also a lot of places in the code where I need to add null catches for inventories, so that is what I plan on doing once I have this thing running smoothly in creative.

    Anyways, here is my updated code.
    Code:
    public Program()
    {
    	Runtime.UpdateFrequency = UpdateFrequency.Update100;
    }
    
    public void Main(string argument, UpdateType updateSource)
    {
    	IMyShipConnector PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    	IMyProgrammableBlock CruiseControl = (IMyProgrammableBlock)GridTerminalSystem.GetBlockWithName("PB Cruise Control");
    
    	if (PlatConn.Status == MyShipConnectorStatus.Connectable)
    	{
    		PlatConn.ApplyAction("Lock");
    		CruiseControl.TryRun("cruise stop");
    	}
    	else if (PlatConn.Status == MyShipConnectorStatus.Connected)
    	{
    		FuelCheck();
    	}
    }
    
    void FuelCheck()
    {
    	IMyReactor LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    	IMyInventory LR1Inv = LR1.GetInventory();
    	IMyReactor LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    	IMyInventory LR2Inv = LR2.GetInventory();
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    	var LR1Fuel = LR1Inv.GetItemAmount(iType);
    	var LR2Fuel = LR2Inv.GetItemAmount(iType);
    
    	if (LR1Fuel < 10 || LR2Fuel < 10)
    	{
    		FuelTransfer();
    	}
    	else
    	{
    		ComponentSearch();
    	}
    }
    
    void ComponentSearch()
    {
    	IMyCargoContainer LCC = (IMyCargoContainer)GridTerminalSystem.GetBlockWithName("LCC");
    	IMyInventory Storage = LCC.GetInventory();
    	MyItemType iType2 = new MyItemType("MyObjectBuilder_Component", "SteelPlate");
    	MyItemType iType3 = new MyItemType("MyObjectBuilder_Component", "Construction");
    	MyItemType iType4 = new MyItemType("MyObjectBuilder_Component", "InteriorPlate");
    	MyItemType iType5 = new MyItemType("MyObjectBuilder_Component", "Motor");
    	MyItemType iType6 = new MyItemType("MyObjectBuilder_Component", "LargeTube");
    	MyItemType iType7 = new MyItemType("MyObjectBuilder_Component", "SmallTube");
    	MyItemType iType8 = new MyItemType("MyObjectBuilder_Component", "Computer");
    
    	if (Storage.GetItemAmount(iType2) >= 62000 && Storage.GetItemAmount(iType3) >= 2100 && Storage.GetItemAmount(iType4) >= 1400 && Storage.GetItemAmount(iType5) >= 600 && Storage.GetItemAmount(iType6) >= 20 && Storage.GetItemAmount(iType7) >= 1300 && Storage.GetItemAmount(iType8) >= 50)
    	{
    		Disconnect();
    	}
    	else
    	{
    		ComponentTransfer();
    	}
    }
    
    void FuelTransfer()
    {
    	IMyReactor LR1 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR1");
    	IMyInventory LR1Inv = LR1.GetInventory();
    	IMyReactor LR2 = (IMyReactor)GridTerminalSystem.GetBlockWithName("LR2");
    	IMyInventory LR2Inv = LR2.GetInventory();
    	IMyReactor BaseReactor = (IMyReactor)GridTerminalSystem.GetBlockWithName("Base Reactor");
    	IMyInventory BaseReactorInv = BaseReactor.GetInventory();
    	MyItemType iType = new MyItemType("MyObjectBuilder_Ingot", "Uranium");
    	var item = (MyInventoryItem)BaseReactorInv.FindItem(iType);
    	var LR1Fuel = LR1Inv.GetItemAmount(iType);
    	var LR2Fuel = LR2Inv.GetItemAmount(iType);
    
    	if (LR1Fuel < 10 && LR2Fuel < 10)
    	{
    		BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    		BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    	}
    	else if (LR1Fuel < 10 && LR2Fuel >= 10)
    	{
    		BaseReactorInv.TransferItemTo(LR1Inv, item, 10 - LR1Fuel);
    	}
    	else if (LR2Fuel < 10 && LR1Fuel >= 10)
    	{
    		BaseReactorInv.TransferItemTo(LR2Inv, item, 10 - LR2Fuel);
    	}
    }
    
    void Disconnect()
    {
    	IMyShipConnector PlatConn = (IMyShipConnector)GridTerminalSystem.GetBlockWithName("Platform Connector");
    	IMyProgrammableBlock CruiseControl = (IMyProgrammableBlock)GridTerminalSystem.GetBlockWithName("PB Cruise Control");
    	PlatConn.ApplyAction("Unlock");
    	CruiseControl.TryRun("cruise 1.5 up");
    }
    
    void ComponentTransfer()
    {
    	IMyCargoContainer BaseStorage = (IMyCargoContainer)GridTerminalSystem.GetBlockWithName("Base Storage");
    	IMyInventory BaseStorageInv = BaseStorage.GetInventory();
    	IMyCargoContainer LCC = (IMyCargoContainer)GridTerminalSystem.GetBlockWithName("LCC");
    	IMyInventory Storage = LCC.GetInventory();
    	MyItemType iType2 = new MyItemType("MyObjectBuilder_Component", "SteelPlate");
    	MyItemType iType3 = new MyItemType("MyObjectBuilder_Component", "Construction");
    	MyItemType iType4 = new MyItemType("MyObjectBuilder_Component", "InteriorPlate");
    	MyItemType iType5 = new MyItemType("MyObjectBuilder_Component", "Motor");
    	MyItemType iType6 = new MyItemType("MyObjectBuilder_Component", "LargeTube");
    	MyItemType iType7 = new MyItemType("MyObjectBuilder_Component", "SmallTube");
    	MyItemType iType8 = new MyItemType("MyObjectBuilder_Component", "Computer");
    
    
    	MyItemType[] iTypes = { iType2, iType3, iType4, iType5, iType6, iType7, iType8 };
    	List<MyItemType> ItemsNeeded = new List<MyItemType>();
    	ItemsNeeded.AddRange(iTypes);
    
    	for (int k = 0; k < ItemsNeeded.Count; k++)
    	{
    		int[] Minimums = new int[7] { 62000, 2100, 50, 20, 1300, 1400, 600 };
    
    		if (Storage.GetItemAmount(ItemsNeeded[k]) < Minimums[k])
    		{
    			MyInventoryItem NeededItems = (MyInventoryItem)BaseStorageInv.FindItem(ItemsNeeded[k]);
    			BaseStorageInv.TransferItemTo(Storage, NeededItems, Minimums[k] - Storage.GetItemAmount(ItemsNeeded[k]));
    		}
    		else
    		{
    			Disconnect();
    		}
    
    	}
    }
    Can I take those MyItemType declarations and stick them after the Program method? if so, that will clean this beast up a bit. Really, the more variables I can stick up there, the better, if the system allows for it.
     
  20. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    I believe you can put the MyItemTypes above everything else but I'm not quite sure. And yeah turning off the conveyors would work but I'm not sure of how to do that. I've never tried doing that I assume it's probably like LR1.UseConveyers() or something but I've never tried. I'm currently with my girl though so I'll look into it tommorow
     
  21. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    All you have to do is go into the reactor in game and go to it's properties and turn off "Use Conveyors" :p. Super simple :D
     
  22. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Oh yeah I know how to turn it off from the reactor but I also figured out how to turn it off in a script. It's ReactorName.SetValue("UseConveyor", true); or false.
     
  23. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @GreenBeanio

    So far, I’ve got the elevator building platform running smoothly, I just have to add a timer block to turn back on the merge blocks once it disconnects and it will be all set to try out in survival. I think I’m going to have to either make my own script, or use TIM to manage the storage at the bottom of the elevator shaft so it will always have the required materials. We will see. I basically retrofitted my old platform design with a few improvements to hopefully stave off the Klang gods and implemented the script onto it and it runs beautifully! Only a few more steps to full automation . If I can figure it out, I will upload a video somewhere once it is finished.
     
  24. SubtleSloth

    SubtleSloth Trainee Engineer

    Messages:
    54
    @GreenBeanio

    Hey Man, I have the elevator cart moving up and down the shaft without explosions finally! Trying to trigger something on a downward or upward velocity at a certain altitude i.e. If cart is at certain altitude, and going up, slow it down. Or, if cart is at the same altitude and going down, do something different. I've got the altitude part down, its the vector thing that is giving me issues. Let me know what ya think!
     
  25. GreenBeanio

    GreenBeanio Trainee Engineer

    Messages:
    14
    Yo @SubtleSloth I haven't been here in a hot minute. Did you ever finish our creation