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.

Selective Refining

Discussion in 'Programming Questions and Suggestions' started by Jakaya, Jan 8, 2015.

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

    Messages:
    123
    I am after a script that will allow me to input the name of a type of ore (so "Iron", "Cobalt", "Gold" etc) into a programmable block to allow me to select the chosen ore to be refined.
     
  2. Saladin Trainee Engineer

    Messages:
    9
    Jakaya you can possible use the script already for the inventory sorting... i am not currently at home so cannot get on steam to post up the sorting program but it does have a video of a sorting on the workshop... THat would assist in starting to create the script if you are able to... if not once i get a chance i will see what i can come up with to make a script to do that... Might need some more information for the creation.

    add 1980 to my name to find me on steam if that is somthing your interested in ...
     
  3. aaraujo Trainee Engineer

    Messages:
    8
    Agreed. A slight change to the inventory sorting script plus turning off the auto-feed on the refinery should do it... I think...

    Now the inventory sorting script was working by totally bypassing conveyors (it could move stuff from one place to another even if the two places were not connected by a conveyor)... Today's patch fixed that... so the two locations have to be connected by a conveyor otherwise the transfer is a no-go...

    So I'm wondering... To stop the Refinery from auto-pulling, we would have to set the "Use Conveyor" to "Off", right? Now when we do that does it mean that the Refinery is no longer on the conveyor system (i.e. no transfer to/from allowed) or does it just turn off the auto-pull?

    Have to test that out...
     
  4. Jakaya Apprentice Engineer

    Messages:
    123
    Sadly my coding knowledge is limited to a very basic level and I have no clue where to start if you could make said script that would be fantastic :D

    Let me know what you need from me in regards of info
     
    Last edited by a moderator: Jan 9, 2015
  5. Digi Senior Engineer

    Messages:
    2,393
    I did a quick script for this with some quick tests so it might fail under some rare circumstances.

    It will empty refineries then fill them with the ore specified on top.

    Code:
    string refineOre = "Uranium"; // the ore you want to make sure it's being refined 
    string refineryContains = null; // a string that refineries must have in the name to be affected, or use null to affect all refineries 
    string containerContains = null; // a string that containers must have in the name to be affected, or use null to affect all containers 
    bool disableConveyorSystem = false; // true = keep "use conveyor system" off to prevent other ores from getting in the refineries (but they also won't unload) 
     
    void Main() 
    { 
        var blocks = GridTerminalSystem.Blocks; 
        List<IMyInventory> refineries = new List<IMyInventory>(); 
        List<IMyInventory> storage = new List<IMyInventory>(); 
         
        // first find all storage containers that we can place the existing ores into 
        for(int b = 0; b < blocks.Count; b++) 
        { 
            var block = blocks[b]; 
             
            if(block is IMyCargoContainer) 
            { 
                if(containerContains != null && !block.CustomName.Contains(containerContains)) 
                    continue; 
                 
                storage.Add((block as IMyInventoryOwner).GetInventory(0)); 
            } 
        } 
         
        // then find all refineries and get all other ores out of it, into the containers we just collected 
        for(int b = 0; b < blocks.Count; b++) 
        { 
            var block = blocks[b]; 
             
            if(block is IMyRefinery) 
            { 
                if(refineryContains != null && !block.CustomName.Contains(refineryContains)) 
                    continue; 
                 
                var inv = (block as IMyInventoryOwner).GetInventory(0); 
                var items = inv.GetItems(); 
                 
                refineries.Add(inv); 
                 
                if(items.Count == 0) 
                    continue; 
                 
                for(int i = 0; i < items.Count; i++) 
                { 
                    if(!(items[i].Content.ToString().EndsWith("Ore") && items[i].Content.SubtypeName.Equals(refineOre))) 
                    { 
                        for(int s = 0; s < storage.Count; s++) 
                        { 
                            inv.TransferItemTo(storage[s], i, null, true, null); 
                        } 
                    } 
                } 
            } 
        } 
         
        // then go through everything that can hold ore and find all the ore that we'll be transfering to the refineries 
        for(int b = 0; b < blocks.Count; b++) 
        { 
            var block = blocks[b]; 
             
            if(block is IMyCargoContainer || block is IMyShipConnector || block is IMyCollector || block is IMyShipDrill || block is IMyShipGrinder || block is IMyShipWelder) 
            { 
                var inv = (block as IMyInventoryOwner).GetInventory(0); 
                var items = inv.GetItems(); 
                 
                if(items.Count == 0) 
                    continue; 
                 
                for(int i = 0; i < items.Count; i++) 
                { 
                    if(items[i].Content.ToString().EndsWith("Ore") && items[i].Content.SubtypeName.Equals(refineOre)) 
                    { 
                        for(int r = 0; r < refineries.Count; r++) 
                        { 
                            inv.TransferItemTo(refineries[r], i, null, true, null); 
                        } 
                    } 
                } 
            } 
        } 
         
        // TransferItemTo() seems to enable conveyor system, added option to keep it off 
        if(disableConveyorSystem) 
        { 
            for(int b = 0; b < refineries.Count; b++) 
            { 
                var block = refineries[b].Owner as IMyRefinery;
                var refinery = block as IMyRefinery; 
                 
                if(refinery.UseConveyorSystem) 
                { 
                    refinery.GetActionWithName("UseConveyor").Apply(refinery); 
                } 
            } 
        } 
    }
    
    
     
    Last edited by a moderator: Jan 9, 2015
  6. Kuu Lightwing Senior Engineer

    Messages:
    1,503
    To be honest, the number of parameters that TransferItemTo takes scares me since I just don't understand what they are.
     
  7. reptar1025 Trainee Engineer

    Messages:
    28
    The parameters are:

    Code:
    IMyInventory dst, int sourceItemIndex, Nullable<int> targetItemIndex = [COLOR= #0000ff]null[/COLOR], Nullable<bool> stackIfPossible = [COLOR= #0000ff]null[/COLOR], Nullable<MyFixedPoint> amount = [COLOR= #0000ff]null
    
    The first being the destination inventory, the second the index of the item we are moving(where it is in the source inventory), the third the index of the slot of the target inventory(basically where we want to put the item) which is nullable, meaning if it null it doesn't really care where it's put, the fourth is another nullable that will stack the item if possible if true, and the last another nullable that will move a specified amount of items if set.[/COLOR]
    
    
     
    Last edited by a moderator: Jan 9, 2015
  8. Kuu Lightwing Senior Engineer

    Messages:
    1,503
    Aha, thanks.
    By the way, am I getting it right that "Use conveyor system" only affects block's push/pull requests and not the ability to move items across the conveyor network via scripts or by hand? Because it seems like it's better to turn if off so that nasty refineries wont mess with the script behavior...
     
  9. Knsgf Junior Engineer

    Messages:
    538
    Yes, turning off "Use conveyor system" only disables automatic grabbing/dumping of resources.
     
  10. Kuu Lightwing Senior Engineer

    Messages:
    1,503
    I tried to make a loadbalancer for refineries, but it does nothing for some reason.
    The idea was to find all the refineries and then for each refinery put a small amount of something it could accept from conveyor system.
    I assume that boolean value TransferItemTo returns, indicates the success of transfer, so if I try to put teddy bear into refinery, it will do nothing and return false. But script does nothing for some reason. No exceptions, no runtime errors, just nothing :/

    Code:
    public const int LOAD_AMOUNT = 100;
    
    public void AddType <T>(List <IMyTerminalBlock> blocks)
    {
        List<IMyTerminalBlock> newBlocks = new List<IMyTerminalBlock>();
        GridTerminalSystem.GetBlocksOfType<T> (newBlocks);
        blocks.AddRange (newBlocks);
    }
    
    void Main()
    {    
        List<IMyTerminalBlock> refineries = new List<IMyTerminalBlock>();
        AddType <IMyRefinery> (refineries);
    
        List<IMyTerminalBlock> sourceInventories = new List <IMyTerminalBlock>();
        AddType <IMyCargoContainer> (sourceInventories);
        AddType <IMyShipConnector> (sourceInventories);
    
        for (int i = 0; i < refineries.Count; i++) {
            IMyInventory refineryInput = (refineries[i] as IMyInventoryOwner).GetInventory(0);
            if (refineryInput.CurrentMass < (VRage.MyFixedPoint)LOAD_AMOUNT) {
                bool hasLoaded = false;
                for (int j = 0; j < sourceInventories.Count && !hasLoaded; j++) {
                    IMyInventory sourceContent = (sourceInventories[i] as IMyInventoryOwner).GetInventory(0);
                    List <IMyInventoryItem> items = sourceContent.GetItems ();
                    for (int k = 0; k < items.Count && !hasLoaded; k++) {
                        hasLoaded = sourceContent.TransferItemTo (refineryInput, k, null, true, (VRage.MyFixedPoint)LOAD_AMOUNT);                                 
                    } // item loop
                } // inventory loop
            } // if
            IMyRefinery refinery = refineries[i] as IMyRefinery;                         
            if(refinery.UseConveyorSystem)     
                refinery.GetActionWithName("UseConveyor").Apply(refinery);     
        } // refinery loop
    }
    
     
    Last edited by a moderator: Jan 9, 2015
  11. DarrikVkir Trainee Engineer

    Messages:
    80
    Script's working fine for me... if it's intended to put 100 units of ore into each refinery if the refinery doesn't already have 100 on each 'run', that's what it's doing on my test. Three refineries, three containers, multiple ore types (in storage). After a number of test presses, I've got the same amount of iron ingots in all three refineries, so looks like it's stable.

    Power? Conveyor system? Ownership? Mine was all unowned.
     
    Last edited by a moderator: Jan 9, 2015
  12. Kuu Lightwing Senior Engineer

    Messages:
    1,503
    Uh, in my test all was powered, connected and owned by me, but script did nothing...
    And yeah, it should put 100 ore units in the input inventory of every refinery on the grid. I want to run this script by a 2-second heartbeat timer, so that every refinery would process ore, not just one.
     
    Last edited by a moderator: Jan 9, 2015
  13. Jakaya Apprentice Engineer

    Messages:
    123
    Your a hero i know have this code running on my refinery station and my ship and it works a beaut
     
  14. AutoMcD Senior Engineer

    Messages:
    2,369
    Just running the stone ejection script is good enough for me. If there's something in particular I need I'll just drag it to the front of the line and it stays.
     
  15. DarrikVkir Trainee Engineer

    Messages:
    80
    It worked as expected for me. I went back in just now and changed everything to owned by me, recompiled the script, and ran it again, and it worked like that as well. It's the same code you used, just with a couple extra lines with a debug.

    https://gist.github.com/anonymous/d4d0252d2c89768b5903
     
  16. reptar1025 Trainee Engineer

    Messages:
    28
    I made if you guys are interested. Does pretty much what you were asking for I think, but I had started working on it before I saw this thread and just finished it now :p. I stole the title of your post for the title of the script, hope you don't mind. Source code is here if anyone wants to see it.

    http://steamcommunity.com/sharedfiles/filedetails/?id=372675028
     
    Last edited by a moderator: Jan 10, 2015
Thread Status:
This last post in this thread was made more than 31 days old.