Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

IMyInventory GetItems working?

Discussion in 'Programming (In-game)' started by Loues S. Cat, Mar 1, 2019.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Loues S. Cat Apprentice Engineer

    Messages:
    143
    Hmm The behavior of this has changed from how it was before and how it was during the release tests and it seems to be broken.
    from the ingamte script interface for "IMyInventory" the method "GetItems"
    void GetItems(List<MyInventoryItem> items, Func<MyInventoryItem, bool> filter = null);

    Originaly this retruned the neede dinfo.
    During the release tests it was changed to return void but ot accepted a list with the out keyword so that list would be populated with the needed info rather than having it returned so....
    the problem is it no longer accepts the out keyword and still returns void. am I missing something here? I can't see how to actualy use this function.
    While I am at it the returned list contains MyInventoryItem rather than IMyInventoryItem objects.
     
  2. 2nd Engr. 3Dog Trainee Engineer

    Messages:
    16
    I'm having a similar issue since updating the MDK. Now this code block is telling me that I "Cannot assign void to an implicitly-typed variable":

    var ContainerOne = Container.GetInventory(0);
    foreach (var block in FromContainers)
    {
    var Inventory = block.GetInventory(0);
    var blockItems = Inventory.GetItems();
    for (int i = blockItems.Count - 1; i >= 0; i--)
    {
    Inventory.TransferItemTo(ContainerOne, 0, null, true, null);
    }
    }

    The potential solutions say to use GetItemAt, but that returns a single item not a list of items.
     
  3. Loues S. Cat Apprentice Engineer

    Messages:
    143
    Well I filed a bug rep on it anyway.
    What is weird is this change was made in all the tests, but they all properly implamented the new code so it was workable even if it did break all existing scripts that used it. You just needed to update them.
    the release version is the only one where this method has been entirely broken :woot:
     
  4. Sinus32 Trainee Engineer

    Messages:
    22
    The solution is simple:

    var myList = new List<MyInventoryItem>();
    inventory.GetItems(myList, null);
    DoSomethingWith(myList);

    or without any list:

    inventory.GetItems(null, item =>
    {
    DoSomethingWith(item);
    return false;
    });
     
    • Like Like x 1
  5. 2nd Engr. 3Dog Trainee Engineer

    Messages:
    16
    Thanks @Sinus32, that does look simple. Is there a thread that I should be monitoring to keep informed of these types of changes? I had no idea that this changed until it was broken.
    --- Automerge ---
    Well... that still gives me an error, but now it's an even more ridiculous error message...
    I've changed the red squigglies in VS to red text underlined.
    <--------------------------------------->
    var blockItems = new List<IMyInventoryItem>();
    FromContainers = GetBlocksFromGroup("Cargo");
    foreach (var block in FromContainers)
    {
    var Inventory = block.GetInventory();
    Inventory.GetItems(blockItems, null);
    for (int i = blockItems.Count - 1; i >= 0; i--)
    {
    Inventory.TransferItemTo(ToContainer, 0, null, true, null);
    }
    }

    The new intellisense error I get when mousing over blockItems is I "cannot convert from MyInventoryItem to MyInventoryItem". How's that helpful!!!?? "throw me a freaking bone here". How does one fix this?
     
  6. Pembroke Trainee Engineer

    Messages:
    7
    Note, that the error message is actually "from MyInventoryItem to IMyInventoryItem". There's an "I" in the latter so two different classes. And that's actually the problem here... The GetItems() function gives you now MyInventoryItem objects instead of IMyInventoryItem objects. These classes have different methods, too, so you can't switch unless you then also change how you use them and those changes might cause additional changes... Maybe it's a legitimate and deliberate change and we're supposed to now use MyInventoryItems instead of IMyInventoryItems but it suspiciously looks more like a bug or an oversight and it *really* should give you IMyInventoryItem objects... Anyone got more info about this change or reported it as a bug? It definitely breaks almost all inventory handling scripts.
     
  7. Sinus32 Trainee Engineer

    Messages:
    22
    The message is that you cannot convert from IMyInventoryItem to MyInventoryItem. You can no longer use the IMyInventoryItem interface, you have to use struct MyInventoryItem instead.

    And I don't know about any thread that is up to date and explains all changes in the API.
     
  8. 2nd Engr. 3Dog Trainee Engineer

    Messages:
    16
    For whatever reason, I could not see that difference even though I stared at it for several minutes.
    Changing the var declaration fixed the issue. I (pun intended) just couldn't see any distinction between the two

    from: var blockItems = new List<IMyInventoryItem>();
    to: var blockItems = new List<MyInventoryItem>(); // no I
    ------------------------
    ^
    -------------------------Missing I
     
  9. FrederickJolio Trainee Engineer

    Messages:
    4
    IMyCargoContainer Container;
    IMyTextPanel TP;
    List<IMyInventoryItem> ContainerItems;


    Program()
    {
    Runtime.UpdateFrequency = UpdateFrequency.Update10;
    Container = GridTerminalSystem.GetBlockWithName("DrillContainer") as IMyCargoContainer;
    TP = GridTerminalSystem.GetBlockWithName("LCD") as IMyTextPanel;
    ContainerItems = new List<IMyInventoryItem>();
    }

    void Main(string argument)
    {
    IMyInventory ContainerInventory = Container.GetInventory(0);
    ContainerItems = ContainerInventory.GetItems();
    TP.WritePublicText("ContainerItems:\n",false);
    foreach (IMyInventoryItem Item in ContainerItems)
    {
    TP.WritePublicText(Item.Content.SubtypeName + ": " + Item.Amount + "\n", true);
    }
    }

    void Save()
    {

    }


    I'm confused... Why it doesn't work??? Anybody help me, please
     
  10. Malware Master Engineer

    Messages:
    9,861
    Because there's no bug and it's not broken. It works exactly as intended. There's no need for any `out` keyword, you're supposed to use the new item and not the interface. I'm sure you've already noticed this, but still :)

    It now works exactly the same way as GridTerminalSystem.GetBlocksOfType.
    --- Automerge ---
    Because you're using the deprecated API. It's been updated, and for very good reason.

    https://github.com/malware-dev/MDK-SE/wiki/VRage.Game.ModAPI.Ingame.IMyInventory
     
    • Like Like x 1
  11. FrederickJolio Trainee Engineer

    Messages:
    4
    So gotta learn how to do it a new way. I just can't understand how to make it work:(
     
    Last edited: Mar 10, 2019
  12. 2nd Engr. 3Dog Trainee Engineer

    Messages:
    16
    So look, this is the script I wrote for moving inventory, It does containers and drills. Take it apart and understand how it works, because it does work...
    Code:
    // --------------- This part is setup -----------------------------------
    List<IMyCargoContainer> am5CargoBlocks = new List<IMyCargoContainer>();
    
    		public void Main(string argument, UpdateType updateSource)
    		{
    			try
    			{
    				GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(am5CargoBlocks, block => block.CustomName.EndsWith("[am5]"));
    				navStatus = GetKey("Status", DataPanelBlock);  /  This is just text from a text panel
    				if (navStatus == "Docked")
    				{
    					TransferCargo();
    				}
    
    // ---------------------  This is the part you care about -----------------------
    		private void TransferCargo()
    		{
    			List<IMyCargoContainer> FromContainers = new List<IMyCargoContainer>();
    			List<IMyCargoContainer> ToContainers = new List<IMyCargoContainer>();
    			List<IMyCockpit> shipCockpits = new List<IMyCockpit>();
    			IMyCargoContainer ToContainer;
    			IMyInventory invSender;
    			GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>
    // ---- this uses a single large cargo container named [DockingCargo] to receive everything (note there is only one)
    // --- from there an inventory manager like Isy's transfers ore and ice to the proper containers
    (ToContainers, block => block.CustomName.EndsWith("[DockingCargo]"));
    			if(ToContainers.Count < 1)
    			{
    				Echo("No DockingCargo Container Found");
    			}
    			//Echo("ToContainer =: " + ToContainers[0].CustomName);
    			ToContainer = ToContainers[0];
    			Echo("ToContainer set to: " + ToContainer.CustomName);
    			IMyInventory invReceiver = ToContainer.GetInventory(0);
    
    			GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(FromContainers, block => block.CustomName.EndsWith("[am5]"));
    			Echo("Starting Cargo Transfer");
    			foreach (IMyCargoContainer am5Container in FromContainers)
    			{
    				invSender = am5Container.GetInventory(0);
    				Echo("Sender set to: " + am5Container.CustomName);
    				Echo("Contains: " + invSender.ItemCount);
    				if (invSender.ItemCount > 0)
    				{
    					if (invSender.IsConnectedTo(invReceiver))
    					{
    						Echo("Transferring...");
    						invSender.TransferItemTo(invReceiver, 0, null, true, null); //(receiverContainer, SourceItemIndex, DestItemIndex, StackIfPossible, Amount)
    					}
    					else { Echo("Transfer ability to " + am5Container.CustomName + " is disconnected"); }
    				}
    
    			}
    			// Remove any inventory overloaded to Cockpit
    			IMyCockpit am5Cockpit;
    			GridTerminalSystem.GetBlocksOfType<IMyCockpit>(shipCockpits, block => block.CustomName.EndsWith("[am5]"));
    			am5Cockpit = shipCockpits[0];
    			invSender = am5Cockpit.GetInventory(0);
    			if (invSender.ItemCount > 0)
    			{
    				if (invSender.IsConnectedTo(invReceiver))
    				{
    					Echo("Transferring...");
    					invSender.TransferItemTo(invReceiver, 0, null, true, null); //(receiverContainer, SourceItemIndex, DestItemIndex, StackIfPossible, Amount)
    				}
    				else { Echo("Transfer ability to " + am5Cockpit.CustomName + " is disconnected"); }
    			}
    }
    I have conveyor sorters that remove everything from the drills, so you may need to check that if you are scripting a mining ship.

    [RANT]Now, you can look at my avatar and see that I'm a noob to this, but I'm trying to help you. All I got when I first started asking questions is snarky comments. Whatever, I can figure it out on my own if I have to, but asking people that do it all the time is quicker. The thing with scripting and software is that there are always several ways to solve the same problem. Right and wrong is subjective. just because someone else would solve the same problem differently doesn't make one solution wrong and the other right. It either works or it doesn't. There are more extensible ways to do things, so listening to other people's feedback can be helpful if they are trying to help. Most don't want to help though, they just want to throw their two cents in. [/RANT]
     
    • Like Like x 1
  13. Malware Master Engineer

    Messages:
    9,861
    It's all about asking in the right place, @2nd Engr. 3Dog. Go to the #programming-in-game channel in the Keen discord and you'll get all the answers you need ;)
     
  14. 2nd Engr. 3Dog Trainee Engineer

    Messages:
    16
    Now this is very true and an extremely important point. I found a lot of help there @Malware
     
  15. FrederickJolio Trainee Engineer

    Messages:
    4

    Thank you very much!
     
Thread Status:
This last post in this thread was made more than 31 days old.