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

My Insane Inventory Sorting Script

Discussion in 'Programming Released Codes' started by randomname, Feb 26, 2015.

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

    randomname Apprentice Engineer

    Messages:
    103
    Hello! This script is not the ultimate script to end all hunger on earth and not some kind of super uber script.... but what it is, is my Master Sort script. In my base, there are many scripts to do many things to do with inventory, but when I want all inventory to be sorted in a jiff - enter the sort script. It's Features include DUAL HEAD lcd/textpanel support on numerous panels/text panels/lcds etc. All null objects are handled with my funky loop coding style, so there shouldn't be any object reference not set shenanigans. I didn't use stringbuilder. Probably some other coding issues, who knows. Read and enjoy!
    Link:


    Edit: updated code to latest knowledge level: properties. Enabled mass deobfuscation of code.
    updated wordwrap code to primal command line debugged code. no more garbage. Also, Addition of trivial property that is actually the dictionary key.
     
    Last edited: Jul 4, 2016
  2. randomname

    randomname Apprentice Engineer

    Messages:
    103
    I have a couple more scripts that should be useful to any random person: Star Trek Doors and Inventory Count. I'll post them later. Here's the scripts at work:
    [​IMG]
     
    Last edited by a moderator: Feb 26, 2015
  3. Burillo

    Burillo Junior Engineer

    Messages:
    648
    actually, doing TransferItemTo until the end of the loop is a nice idea. i got around the return value by checking current load after each transfer, but it seems like your idea should be more efficient :)
     
  4. randomname

    randomname Apprentice Engineer

    Messages:
    103
    Yah splunk the code, I know I was the code splunker before.... reading everyone's scripts and absorbing programming block tricks. I cherry picked all the good ideas heh heh. I've seen lots of youtube vids on space engineers, but I've never seen star trek doors! You need 1 door and a sensor as well as a timer block and two programming blocks.
    Code:
    void Main()
    {
    List<IMyTerminalBlock> airLocks = new List<IMyTerminalBlock>();
    GridTerminalSystem.SearchBlocksOfName("HomeBase Door", airLocks);
    ITerminalAction openDoor = airLocks[0].GetActionWithName("Open_On");
    for (int i = 0; i < airLocks.Count; i++)
        openDoor.Apply(airLocks[i]);
    var timeblock = GridTerminalSystem.GetBlockWithName("Timer Block Close Door");
    ITerminalAction Aktung = timeblock.GetActionWithName("Start");
    Aktung.Apply(timeblock); //stop trigger
    }
    
    and the one that closes the doors.
    Code:
    void Main()
    {
    List<IMyTerminalBlock> doorSensors = new List<IMyTerminalBlock>();
    GridTerminalSystem.SearchBlocksOfName("HB Sensor", doorSensors);
    bool stillDetected = false;
    for (int h = 0; h < doorSensors.Count; h++)
        if ((doorSensors[h] as IMySensorBlock).LastDetectedEntity != null) stillDetected = true;
    if (!stillDetected) {
    List<IMyTerminalBlock> airLocks = new List<IMyTerminalBlock>();
    GridTerminalSystem.SearchBlocksOfName("HomeBase Door", airLocks);
    ITerminalAction closeDoor = airLocks[0].GetActionWithName("Open_Off");
    for (int i = 0; i < airLocks.Count; i++)
        closeDoor.Apply(airLocks[i]);
    } else {
        var timeblock = GridTerminalSystem.GetBlockWithName("Timer Block Close Door"); 
        ITerminalAction Aktung = timeblock.GetActionWithName("Start"); 
        Aktung.Apply(timeblock); //stop trigger
    }
    }
    
    you can see I just open all the doors at once, then close them all. I'm lazy, so you can steal this idea and change it to do the thing with individual doors, if you want. It shows important IMyEntity interface using the sensor block, definitely a cherry worth picking ;) not sure who I stole it from.
     
  5. randomname

    randomname Apprentice Engineer

    Messages:
    103
    hahhah I posted the inventory script too soon now. I have some excellent loop collapsing in case of no cargo system, so it stops all attempts to transfer and tells you to check it. It's mostly about gathering information inside to post to the lcd/text panel. I'll give it a couple of days to ferment and then I'll spaff out the latest copy of the script. I'm waiting to see if there are any naughty index violations in the word wrapping as well.
     
  6. randomname

    randomname Apprentice Engineer

    Messages:
    103
    Too strange!!! Gravel is called "Stone ingots" *MindBlown*
     
  7. randomname

    randomname Apprentice Engineer

    Messages:
    103
    ok here's the super ultimate ultra edition of the script hah hah just kidding. It's got the ability to tell you why the transfer failed, as well as word wrapping function built into the text output. I determined the word wrap won't violate index bounds, even though it seems like it would at first glance. I didn't add stringbuilder or put any tabs in some areas of the code. Perhaps the code tag will auto format the thing? Anyways, enjoy again! The conveyor detection code is the coup de gras lol.
    Edit: this is the old script for posterity, it had "insane" label, if you look at it, you'll know why ;) good script is in the first post.
    Code:
    void Main()
    {
    //this script sorts all inventories into any number of inventories. Including sorting the inventories
    //it's sorting into at the same time. Excludes Reactors and my repair ship. excludes ingot "Uranium"
    // ex all ore(s) in a connector will wind up in the "ore cargo container"(s) going to the next
    //inventory once the current one is full on the destination. 
    //output is on a series of 2 displays, one for items that it can transfer, and one for items it can't
    //check the end of the script. LCD or TEXT panels work. No panels = no Display.
    // Declare THREE Object types for sorting, which is all of them... all the ones that matter, I mean.
    const string comType = "MyObjectBuilder_Component";
    const string oreType = "MyObjectBuilder_Ore";
    const string ingotType = "MyObjectBuilder_Ingot";
    //transfer to inventory containing blocks below
    string oreCargo = "Ore Cargo Container"; //ore goes here
    List<IMyInventoryOwner> oreInventory = new List<IMyInventoryOwner>();
    string componentCargo = "Large Cargo Components Container"; //components here
    List<IMyInventoryOwner> componentsInventory = new List<IMyInventoryOwner>();
    string ingotsCargo = "Large Cargo Metals Container"; //ingots here
    List<IMyInventoryOwner> ingotsInventory = new List<IMyInventoryOwner>();
    List<String> filter = new List<String>();//filter names will not be sorted
    filter.Add("Reactor"); //don't sort reactor
    //filter.Add("Tow Large Cargo Container");//add this container to list of no sorting
    List<String> filterItems = new List<String>(); //don't sort these items
    filterItems.Add("Uranium"); //don't sort uranium, the conveyor does it already. ore filter never applies. special case.
    //inventories to transfer FROM eg refinery
    List<IMyInventoryOwner> transferFrom = new List<IMyInventoryOwner>();
    List<IMyTerminalBlock> allBlocks = GridTerminalSystem.Blocks; //capture all blocks
    String output = ""; //strings to store information for LCD output
    String FailOutput = "";
    string SuccessOutput = "";
    for (int x = 0; x < allBlocks.Count; x++) {
        var InventoryOwner = allBlocks[x] as IMyInventoryOwner;
        string blockName = allBlocks[x].DisplayNameText;
        if (InventoryOwner != null && !filter.Contains(blockName)) //it's an inventory block, with all filters applied
        {
        transferFrom.Add(InventoryOwner); //I want to transfer from this inventory owner including
        } // the ones to transfer TO *evil grin* *mainiac laughter* logic uses list matching.if the one to transfer
        //from exists in the list to transfer to, it skips transfer of that single item. see below
        if (blockName == oreCargo) oreInventory.Add(InventoryOwner); //and transfer TO these ones
        if (blockName == ingotsCargo) ingotsInventory.Add(InventoryOwner); //transfer to
        if (blockName == componentCargo) componentsInventory.Add(InventoryOwner); //transfer to
    } //everything is sorted, at this point, time to initiate item transfer.
    bool componentFull = false; //three variables to terminate three loops.
    bool oreFull = false; //it will fail transfer on the first item failed, reason: speed
    bool ingotFull = false; //sorting every item every time worked, until I had a million items and nowhere to put them.
    IMyInventory inventory = null;
    int staleCount = 0; //hold the number of items before transfer
    for (int i = 0; i<transferFrom.Count; i++) { //count through the inventorys
        inventory = transferFrom[i].GetInventory(1); //they all have at least 1 inventory, or two
        if (inventory == null) inventory = transferFrom[i].GetInventory(0); //must only have one
        var item = inventory.GetItems();
        for (int j = item.Count-1; j >= 0 ;j--) { //reverse iteration for game mechanic
        int storeIndex = 0; //which cargo pod to transfer into
        switch (item[j].Content.TypeId.ToString()) //switch based on item type. unknown types do nothing.
        {
            case comType: 
                    if (!componentFull && !componentsInventory.Contains(transferFrom[i])
                        && !filterItems.Contains(item[j].Content.SubtypeName)) { //don't transfer to itself or transfer filters
                    while (storeIndex < componentsInventory.Count) {
                                 staleCount = inventory.GetItems().Count; //inventory before transfer
                                if (!output.Contains(inventory.GetItems()[j].Content.SubtypeId.ToString()))
                                         output = inventory.GetItems()[j].Content.SubtypeId.ToString();
                                //loop through target inventories, until it hits the end, or transfers it.
                                inventory.TransferItemTo(componentsInventory[storeIndex].GetInventory(0), 
                                                                                j , stackIfPossible: true);
                                if (inventory.GetItems().Count == staleCount) { //compares before and after
                                 //increment storage index, because the transfer failed, ergo the cargo is full
                                storeIndex++;
                                } else { 
                                    if (!SuccessOutput.Contains(output)) SuccessOutput += " " + output; //only add new ones
                                    break; //break out
                                } //success !
                    }
                    if (storeIndex == componentsInventory.Count) {
                            componentFull = true;
                            if (!FailOutput.Contains(output)) FailOutput += " " + output; //only add new ones
                            }
                    }
                    break;
            case oreType: 
                    if (!oreFull && !oreInventory.Contains(transferFrom[i])) { //don't transfer to itself, No filters
                    while (storeIndex < oreInventory.Count) { 
                                staleCount = inventory.GetItems().Count; //inventory before transfer
                                if (!output.Contains(inventory.GetItems()[j].Content.SubtypeId.ToString()))
                                    output = inventory.GetItems()[j].Content.SubtypeId.ToString();
                                //loop through inventories, until it hits the end, or transfers it. 
                                inventory.TransferItemTo(oreInventory[storeIndex].GetInventory(0),  
                                                                                j , stackIfPossible: true); 
                                if (inventory.GetItems().Count == staleCount) { 
                                 //increment storage index, because the transfer failed, ergo the cargo is full 
                                storeIndex++; 
                                } else { 
                                    if (!SuccessOutput.Contains(output)) SuccessOutput += " " + output; //only add new ones
                                    break; //break out 
                                } //success ! 
                    }
                    if (storeIndex == oreInventory.Count) {
                            oreFull = true;
                            if (!FailOutput.Contains(output)) FailOutput += " " + output; //only add new ones
                            }
                    }
                    break;
            case ingotType: 
                    if (!ingotFull && !ingotsInventory.Contains(transferFrom[i]) 
                            && !filterItems.Contains(item[j].Content.SubtypeName)) { //don't transfer to itself or transfer filters
                    while (storeIndex < ingotsInventory.Count) { 
                                staleCount = inventory.GetItems().Count; //inventory before transfer
                                if (!output.Contains(inventory.GetItems()[j].Content.SubtypeId.ToString()))
                                    output = inventory.GetItems()[j].Content.SubtypeId.ToString();
                                //loop through inventories, until it hits the end, or transfers it. 
                                inventory.TransferItemTo(ingotsInventory[storeIndex].GetInventory(0),  
                                                                                j , stackIfPossible: true); 
                                if (inventory.GetItems().Count == staleCount) {
                                 //increment storage index, because the transfer failed, ergo the cargo is full
                                storeIndex++;
                                } else {
                                    if (!SuccessOutput.Contains(output)) SuccessOutput += " " + output; //only add new ones
                                    break; //break out 
                                } //success ! 
                    }
                    if (storeIndex == ingotsInventory.Count) {
                            ingotFull = true;
                            if (!FailOutput.Contains(output)) FailOutput += " " + output; //only add new ones
                            }
                    }
                    break;
            default: break;
        }
        }
    } //if you understand the above code loops, congrats - you're now insane. ;)
    
    List<IMyTerminalBlock> lcd = new List<IMyTerminalBlock>();
    GridTerminalSystem.SearchBlocksOfName("Master Sort Text panel 1", lcd); //success side
    if (SuccessOutput.Length > 0) {
        SuccessOutput = DateTime.Now.ToString()+"\n" + "Transfer Success: \n"+ SuccessOutput;
    } else { 
        if (FailOutput.Length == 0) {SuccessOutput = DateTime.Now.ToString() + "\n" + "No Cargo To Transfer.";}
        else {SuccessOutput = DateTime.Now.ToString() + "\n" + "No Transferred Items.";}
    }
    for (int i = 0; i < lcd.Count; i++) { 
        var Display = lcd[i] as IMyTextPanel;
        Display.WritePublicText(SuccessOutput); 
        Display.ShowTextureOnScreen(); 
        Display.ShowPublicTextOnScreen();
    }
    
    GridTerminalSystem.SearchBlocksOfName("Master Sort Text panel 2", lcd); //fail side 
    if (FailOutput.Length > 0) { 
        FailOutput = DateTime.Now.ToString() + "\n" + "Transfer Failed: \n"+ FailOutput; 
    } else {  //line below will never be true, unless you alter the code structure.
        if (SuccessOutput.Length == 0) {FailOutput = DateTime.Now.ToString() + "\n" + "No Cargo To Transfer."; }
        else {FailOutput = DateTime.Now.ToString() + "\n" + "No Failed Items.";}
    }
    for (int i = 0; i < lcd.Count; i++) {  
        var Display = lcd[i] as IMyTextPanel; 
        Display.WritePublicText(FailOutput);  
        Display.ShowTextureOnScreen();  
        Display.ShowPublicTextOnScreen(); 
    }
    }
    
    
     
    Last edited by a moderator: Mar 23, 2015
  8. Qon

    Qon Trainee Engineer

    Messages:
    6
    Very nice script!

    I wanted to use this on my faction's manufacturoid base, unfortunately we have SO MANY components (esp. steel plates) that they need 2-3 large containers to fit into.

    My plan is to adapt your script to be able to use a list of containers, instead of just one container for each type. But I've got to dig it at some more.

    I have added a check so that it won't pull items from connected ships unless you tell it to, which I'm including here incase you want to use it.

    First add these constants:


    Code:
    const string pbName = "Program Block - MFG 02"; // Name of this programming block. Used to determine if we are exiting this grid or not
    
    const bool spanConnected = false; // If set to true, we will pull stuff from any docked ships too.
    
    Then at the start of Main() add:

    Code:
    // Make sure we can find our ProgrammingBlock. We need this so we can determine if we are spanning other grids or not
    var progBlock = GridTerminalSystem.GetBlockWithName(pbName) as IMyProgrammableBlock;
    if(progBlock == null)
          return;
    
    
    And finally replace the if(InventoryOwner != Null .. ) block with this:

    Code:
     if (InventoryOwner != null && !filter.Contains(blockName)) //it's an inventory block, with all filters applied
        {
            if(allBlocks[x].CubeGrid == progBlock.CubeGrid) // Same grid
                transferFrom.Add(InventoryOwner); //I want to transfer from this inventory owner including
    
            else if (allBlocks[x].CubeGrid != progBlock.CubeGrid && spanConnected) // Different grid, but we want to span other connected grids
    
                transferFrom.Add(InventoryOwner);
        } // the ones to transfer TO *evil grin* *mainiac laughter* logic uses list matching.if the one to transfer
    
    Thanks!
    -Qon
     
  9. randomname

    randomname Apprentice Engineer

    Messages:
    103
    hey thanks for the interest in the script. I would use the inventory filter to stop it from filtering "specific" ships://filter.Add("Tow Large Cargo Container");//add this container to list of no sorting. I just add the name of anything I don't want it to empty out. That way, with a quick edit I could turn on or off the ship/container filter.the reason I made all components go into the same container like that was the fact you can just type the name of what you wanted into the top of the inventory column and it would find it anyways. heh heh also, there's the infinitely expanding part of the inventory as well. If you just keep adding more cargo pods with the same name, it just expands the inventory to match. It'll require some changes to "case comtype" to sort the components into special inventories. That's actually the crazy part is the fact the cargo pod is referenced once as string componentCargo = "Large Cargo Components Container"; //components here you will probably have to make a dictionary of cargo pods that refer to specific types of components EG componentsCargo(string, string) where one string is the name of the component to store and the other is the name of the pod. Meh just one of many ways to createdeeper and deeper loops ;) Just be careful with the speed hack I put in there, if you edit that out it increases the script execution time by 1000 bool componentFull = false; This is the speed hack to collapse loops in case the destination inventories are full. I did it on all three of the inventory types. lol the downside of this script is the strange loops are hard to spelunk through.
    Code:
    
    
     
    Last edited by a moderator: Mar 3, 2015
  10. randomname

    randomname Apprentice Engineer

    Messages:
    103
    huh that last post went all funky on me! Like I was typing in code.
     
  11. Qon

    Qon Trainee Engineer

    Messages:
    6
    The reason I added the option to not span docked ships is because our base is huge, with 12+ docking ports, at least half always in use.

    I'll probably end up tweaking the script some more to allow for separating specific components into their own container(s) as well. We're now at over 20million pieces of metalsheet's, to give you an idea of the scope of this manufacturing base.

    What I did in my last tweak was to change
    Code:
    [COLOR= #000088]string[/COLOR] componentCargo [COLOR= #666600]=[/COLOR] [COLOR= #008800]"Large Cargo Components Container"[/COLOR][COLOR= #666600];[/COLOR] [COLOR= #880000]//components here
    if (blockName == componentCargo)[/COLOR]
    to
    Code:
    string componentCargo = "[Components]";
    if (blockName.Contains(componentCargo))
    
    
    Which would allow me to use multiple containers holding components, just by adding the [Components] tag to their names.

    It works well enough for now. :)

    Thanks again for sharing the script!
     
  12. randomname

    randomname Apprentice Engineer

    Messages:
    103
    heh heh yah, I hear that, we all have our own inventory needs! Have you noticed yet how if you don't configure the script with the right names it just collapses the code until nothing happens..... ahh the silent fail :) I was initially sad about how the removal of the signalling lights for the inventory system meant you weren't sure if something had run because the lights never changed color, but now...enter the datetime stamp! I am still secretly hoping there will be access to System.Diagnostics namespace for the profiling of programmable block code. mmmm a nice millisecond readout on code execution would be "the bomb" in a good way. Removal of the signalling lights really opened up the logic to indicate any status problems with the conveyor system. I'm still "working" (aka thinking but not coding) on the inventory counting script. My crazy nuts idea is the more panels you add to the scripts setup, the more data the script returns for output. No displays = no data = no code execution. using collapsing logic loops. *JOYGASM* I'll post it soon, just gotta do some copy'n'paste coding.
     
  13. indigodarkwolf

    indigodarkwolf Apprentice Engineer

    Messages:
    115
    Since the devs are doing a thing to try and count our "instructions" at runtime, anyways, it would actually be useful if a successful run of a programming block wrote a DetailedInfo string that contained the number of instructions used on the last successful run, and the maximum number of instructions that the PB is allowed on a single run. Has that been suggested in somewhere official, yet?
     
  14. randomname

    randomname Apprentice Engineer

    Messages:
    103
    yah some kind of profiling string would be nice! Never seen that suggestion yet. I know..access to the Diagnostics would enable creating your own threads and crud that's probably not good hah hah. Thread bomb!!! On a more serious note, I came up with my prototype inventory counter that enables display on any number of text panels you want. I mean, within the game limits heh heh. But you can see now, I use it to display the ingot count in a different lcd. It's really interesting code, with logic loops that will do nothing if there is a problem with the config of anything in the dictionaries. Having said that... it's hard to determine what I'm doing with all those dictionaries, but it's a lookup scheme which determines where the names are displayed. It's prototype stage, so don't expect it to serve you breakfast in the morning. The problem is, the subtype names are identical, leading to a counting error if its counting different objects with the same name. I'll fix that later. After I play for a bit ;) never needed to fix that bug before since the above scenario WAS never true.
    Link:


    ok there I replaced the script in the code editor with the version that can tell the diff between subtypes with the same name. Also now, code uses fancy-er displayed data.
    Updated: Like a Code Junkie... I coded it to display % full.
     
    Last edited: Jul 4, 2016
  15. randomname

    randomname Apprentice Engineer

    Messages:
    103
    here's a pic of it in action. I added the ore panel and even got a token bit of ore to display. The display stops updating if there is no items left in a certain group, or something. Have fun with the code!
    [​IMG]
     
  16. randomname

    randomname Apprentice Engineer

    Messages:
    103
    ok! whipped up another script, this one is less tested and probably prone to some bugs! It basically gets a list of all functional blocks and posts them to an ever-expanding array of lcds.... or whatever. In patented style, I only made basic formatting and get a 1000 chunk of data per normal lcd. You can see the output formatting crap in there. It's basically just another inventory counting script, that counts blocks instead. It's no mona lisa but it works.... now if only you could get all the armor blocks too hah hah, I know it's impossible. I'll post a pic of it in action... It displays on a series of lcd panels with basically the same name... in thousand chunks until it's all displayed, then it shows the default texture on the rest of the displays with no data. Feast on the code! It was originally intended to break down every block used to build a structure so it could tell me the components that went into it. YARRRRRRRRRR impossible.
    Link:


    [​IMG]
    Edit: removed lots of garbage I had written, to pass off as code ;)
    Latest update includes more fancy output! YAY!
    Now With Block sorting by name! You can use the name of your output panels to control where the output is.
     
    Last edited: Jul 5, 2016
  17. randomname

    randomname Apprentice Engineer

    Messages:
    103
    phew I was glad to slay those formatting demons, the output is a little different now, it has padding with _. Hopefully no garbage code left. Also no ObjectBuilder strings are left either.
     
  18. randomname

    randomname Apprentice Engineer

    Messages:
    103
    ok now it's all fancy like a mcdonalds menu board bah hah hah!
    [​IMG]
     
  19. AutoMcD

    AutoMcD Senior Engineer

    Messages:
    2,369
    Do you have it shared in the steam workshop?
     
  20. randomname

    randomname Apprentice Engineer

    Messages:
    103
    naw, they are just some short scripts you can copy and paste them from here. I like to use the forums as my helper for coding! I can copy a module from one script and paste it into another. I tell my friends to just copy the latest from the forums too. It shows off my strange collapsing loops to avoid errors style of coding for world+dog to examine. The downside to this code is, if you completely configure it wrong or whatever the parts are set up wrong, the script does absolutely nothing at all, instead of alerting you to a problem ;) Of course...if nothing happens when you run it - there's a problem. Anyone can feel free to steal any of the ideas presented on the thread. I used the master sort script to create an assembly unclogger that sorts into an infinite series of ingot containers and reports the status on the sort panels. They are all works in progress I keep updating here by just pasting the latest script over top in an edit. I kept the original version of the master sort up there, in hopes it would help someone figure out the logic inside those nuts for loops. It was fun coding them!! As for my fancy ass displays, it's just a series of wide LCDs joined with regular LCDs on rotors with a hanging menu board on some pillars. Backing courtesy of catwalks. I put some graphics up there on a couple lcd panels, the green arrows placement is script/grid(LOL I "think") controlled. Haven't puzzled that one out yet.
     
  21. randomname

    randomname Apprentice Engineer

    Messages:
    103
    phew Dusting off some decade old c# knowledge...man some rusty crap. I decided I could make some classes in my master sort code. It sort of encapsulates the inventory system with some logic code using dictionaries. It slayed some of the garbage code and made things less messy. I downloaded a development environment as well, so I don't have to use the programming block and forums hah hah. I didn't want to waste 10gigs on visual stuuuuuuuudeeioeo so I got quicksharp. it's better than notepad. I'll keep improving my c# knowledge and applying it to these scripts, to make them a little easier to....understand and troubleshoot. Hopefully faster too. refactor time.
     
  22. randomname

    randomname Apprentice Engineer

    Messages:
    103
    There I cleaned up the inventory sorting script with some classes and members and crap like that. I'll refactor it again later after I read some more. Now the class tells when the inventory is full or goes to the next pod in line. Also tells you if the cargo pod doesn't exist. I pasted it on the first page so you can compare the lunacy of the first version master sort to the relative sanity of the second one. I deleted the insanity marker in the code. I will be better testing this script, to see if any naughty-ness arises.
     
  23. randomname

    randomname Apprentice Engineer

    Messages:
    103
    ooo did another sweep of the code using properties. The inventory manager class is really coming together. Hah hah hard to believe...how much the code has improved since I started reading the reference manual. If you want to see true terror, feast on the first version I had posted.... complete gobbldy gook. No wonder it came with an insanity warning.
     
  24. randomname

    randomname Apprentice Engineer

    Messages:
    103
    Ok Slapped on some Generics. I figured that was an important part of c# code that the PB lets us do! Not sure about if the result makes more sense, but it does allow the dictionary key to be a type you define, instead of my string type default. Pretty soon I'll be out of advanced and onto expert c# coding. Then I'll look back over my scripts again.
     
  25. randomname

    randomname Apprentice Engineer

    Messages:
    103
    something really strange happened!
    Caught exception during execution of script: Type 'Inventory`1' from assembly 'IngameScript_safe, Version=0.0.0.0, culture=neutral, PublicKeyToken=null' has a field of an illegal type.
    I think it's related to my introduction of generics. So I had to remove them....what?!?!
     
    Last edited by a moderator: Mar 23, 2015
  26. randomname

    randomname Apprentice Engineer

    Messages:
    103
    ok, I've done some work on the inventory counting script. I will probably refactor the thing into methods and properties of the inventory class. That'll come after I read it and think up more interesting crap. I was thinking of adding an interface so I can sort the inventories by how full/empty they are. Got to flex all coding muscles, you know, even though it's not really required... otherwise they atrophy lol! I pasted the inventory counting script overtop of the old one. Enjoy it's half-completed-glory...or whatnot. The really nuts part of the new addition is how I get the percent full to display on the right lcd panel! Almost got to slap an insanity warning on there.
     
  27. randomname

    randomname Apprentice Engineer

    Messages:
    103
    I'll describe how it calculates the free space, it can do some really unexpected/interesting things. As it counts the items, it also gathers the inventory the item is in. This is in a dictionary keyed off the component object type. Then at the end, when it's displaying the data, it gathers a list of the object types it's displaying on the screen, and also displays the percent full as calculated by adding all the max and current volumes, then dividing current by max and multiply by 100...easy highschool math. That ensures the same display across all lcds. I know it's not fancy yet ;) and the unexpected part is, it'll also gather the inventories..like the nuclear reactor the ingots are in, and add that to the percentage. So, use this script in conjunction with an inventory sorter. Also, it won't count inventories that are completely empty. Due to the fact... there's no objects inside. That's no biggie to me, because the inventory sorting script tells me if I've got too much crap in the pods so I really know if 99% full is really actually full. I'll keep an eye on it's behavior.
     
  28. qsek

    qsek Trainee Engineer

    Messages:
    29
    I use the first topic script version and if i want to put two or more kinds of items in the same Container, i get a exception when i run the script (checking is fine)
    e.g.: Ore and Ingots to the same Container
    Code:
        const string oreCargo = "Large Cargo Container"; //ore goes here
        const string ingotsCargo = "Large Cargo Container"; //ingots here
    
    Code:
    Caught exception during execution of script: An item with the same key has slready been added.
    
     
  29. randomname

    randomname Apprentice Engineer

    Messages:
    103
    make the change here:
    Code:
    switch (item[j].Content.TypeId.ToString()) //switch based on item type. unknown types do nothing.
            {
            case comType:
                    cargoPod = componentCargo;
                    break;
            case oreType: 
                    cargoPod = oreCargo;
                    break;
            case ammoType:
                    cargoPod = ammoCargo;
                    break;
            case toolType:
                    cargoPod = toolsCargo;
                    break;
            case ingotType: 
                    cargoPod = ingotsCargo;
                    break;
            default: 
                cargoPod = "";
                break;
            }//switch
    
    and just replace cargoPod = oreCargo under the "case ingotType:"
    The script builds a dictionary of lists based on the cargo pod name, so you are attempting to add the cargo pod name twice to the dictionary, resulting in the error.
     
  30. randomname

    randomname Apprentice Engineer

    Messages:
    103
    heh heh I suppose I could have added duplicate key elimination to the class. OK I added the single line of code in the class that'll prevent duplicate entries. It makes the code a lot harder to error out ;)
     
    Last edited by a moderator: Mar 30, 2015
Thread Status:
This last post in this thread was made more than 31 days old.