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

How can I read a block's SubType ID

Discussion in 'Programming Questions and Suggestions' started by Cromodus, Jan 18, 2015.

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

    Cromodus Trainee Engineer

    Messages:
    13
    The official programming guide references the SubTypeID of certain blocks. How can I access it, or verify it throughout my script?


    <div>Same block class for different SubTypeID
    Some blocks have same parent (e.g. &lt;TypeId> in cubeblocks.sbc) and differs only by subtype (e.g. &lt;SubtypeId&amp;gt;). This means there is no distinction between these block in code.
    Example of these blocks is the Cargo Container: there are 3 types of cargo containers in the game: small, medium and large. These three types differ only by subtype and Type is same for them e.g. large cargo container id is:
    &lt;Id>
    &lt;TypeId>CargoContainer&lt;/TypeId>
    &lt;SubtypeId>LargeBlockLargeContainer&lt;/SubtypeId>
    &lt;/Id>


    </div>
     
    Last edited by a moderator: Jan 18, 2015
  2. Volfram

    Volfram Senior Engineer

    Messages:
    1,564
    Copy your text to Notepad if you're bringing it from Steam to strip out formatting, or at least manually fix the formatting.
    [edit]
    Or see Cuber's post below for an even better option.
     
    Last edited by a moderator: Jan 19, 2015
  3. Cuber

    Cuber Apprentice Engineer

    Messages:
    262
    Actually, you can just click on this button on the editor to remove all styling

    [​IMG]

    Cromodus, are you talking about verifying inventory item blocks or blocks on the grid?
     
    Last edited by a moderator: Jan 18, 2015
  4. Digi

    Digi Senior Engineer

    Messages:
    2,393
    Well there's this: block.BlockDefinition.SubtypeId, but it seems that it's not allowed in the in-game programming, I'm also curious if there's any alternative.
     
  5. Cromodus

    Cromodus Trainee Engineer

    Messages:
    13
    I'm working on a renaming script. It's essentially complete. All that's missing is the subtype and the Thruster directions although I'm not sure I'll ever get around to that.

    As the official guide says, IMyCargo (And Reactor, Thrust, Refinery, etc...) doesn't differentiate between Small, Medium and Large. It then goes on by saying that the SubTypeID is what separates the blocks with the same parent, TypeID.

    The quote in the OP is a section from the guide about this. Now I'm looking for a way to read this property off a block to tell if IMyCargo is grabbing small, medium or large containers, etc.
     
  6. swixel

    swixel Trainee Engineer

    Messages:
    42
    The good news is we don't actually need it because the BlockDefinition string has everything you need.

    Code:
    void Main()
    {
        for (int block = 0; block &lt; GridTerminalSystem.Blocks.Count; block++)
        {
            if (GridTerminalSystem.Blocks[block] is IMyTerminalBlock)
            {
                IMyTerminalBlock Block = GridTerminalSystem.Blocks[block];
    
                // Get the definition string (which has all we need and more)
                String Definition = Block.BlockDefinition.ToString();
    
                // Start by splitting the definition by /
                String[] DefinitionFragments = Definition.Split('/');
    
                // MyObjectBuilder_MyProgrammableBlock/LargeProgrammableBlock
    
                // Get our block (base) type
                // (Use the index of the first _ in the event they add more underscores later)
                String BlockType = DefinitionFragments[0].Substring(
                    DefinitionFragments[0].IndexOf("_") + 1);
    
                // Get the position of the word "Block"
                int BlockStrPos = DefinitionFragments[1].IndexOf("Block");
    
                // Get our size (before block)
                String BlockSize = DefinitionFragments[1].Substring(0, BlockStrPos);
    
                // Get our subtype
                String SubType = DefinitionFragments[1].Substring(BlockStrPos+5);
    
                // Don't write the block definition, instead we'll format our own version
                //Block.SetCustomName(Block.BlockDefinition.ToString());
    
                // We'll format it so it looks nice
                Block.SetCustomName(
                    "Type: " + BlockType +
                    "; SubType: " + SubType +
                    "; Grid Size: " + BlockSize
                );
            }
        }
    }
    
    To explain, for a cargo container we'd get: MyObjectBuilder_CargoContainer/LargeBlockLargeContainer
    OR MyObjectBuilder_CargoContainer/LargeBlockSmallContainer

    Looking at that we can decompose it pretty quickly and easily, as in the script above.
     
  7. Cromodus

    Cromodus Trainee Engineer

    Messages:
    13
    That's genius, I'll try it out tonight.

    Thanks a lot!
     
  8. Malware

    Malware Master Engineer

    Messages:
    9,867
    I see by the coding standards that there maybe are some VB people in here? To each his or her own obviously but it breaks my C# heart :D

    (i'm talking about coding standards not language preferences ;))
     
    Last edited by a moderator: Jan 20, 2015
  9. Cromodus

    Cromodus Trainee Engineer

    Messages:
    13
    What do you mean? What's different?
     
  10. Me 10 Jin

    Me 10 Jin Apprentice Engineer

    Messages:
    463
    LordDevious is probably referring to using "block" and "Block" as variable names and checking whether each member of a List&lt;IMyTerminalBlock> is actually IMyTerminalBlock
     
  11. Cromodus

    Cromodus Trainee Engineer

    Messages:
    13
    Yeah, I thought that was confusing.

    What about this line:

    Code:
    if (GridTerminalSystem.Blocks[block] is IMyTerminalBlock)
    
    Is it just me or this will always return True? Therefor, there's no poing in having it in there.
     
  12. swixel

    swixel Trainee Engineer

    Messages:
    42
    You can blame MSDN for that. I use a variant of that script to create generic named components for another script to use to rename after being "autoprinted" from a starport. For some reason I got a common runtime error and adding that line fixed it. While not pretty, or, honestly, needed in my view, the fact it fixed it (and the fact the script executed on every functional block?) indicates something weird happened there. I never hunted it down (probably something to do with string splitting), I just hit MSDN up for how C# is meant to check for a type (apparently "Obj is Type"), and ran with it.

    As for the "block", it was originally "i" but I had to rename it to explain the script to a friend (who is learning C# and wanted to help with the script this is in). (And I use 64bit SE, so foreach is out; and for wider compatibility, foreach is out.)

    Disclaimer: I use C++ and functional languages (mostly Erlang), but I do know (and use) scripting (mostly Python, Perl, JavaScript, Lua, R, bash, sh). VB is something I understand (because we're in a world where we'll never escape Microsoft Office for generic business use), but that's not where the "Obj is Type" came from.

    ---

    It's probably worth noting you can do a lot more with the information. Naturally you don't need to rename, so this is just an extraction script. The actual code breaks the information up slightly differently (everything after defining Block is actually in another function), it's then fed into another function which determines what it is (in terms of 'value' to the ship, block order, etc.), and the entries are renamed in a sensible way (sometimes with the grid positions included, if it's something like a cargo container).

    Another version is used with an auto-docking script (a couple of sensors, one code block, an interior light (for my binary switch accessible to both grids), and a connector) to update the storage space of each container before the autonomous vessel leaves (syntax: "&lt;Size> Container [X,Y,Z] &lt;N>% full"). Naturally it requires rename/object information data for other reasons :)
     
  13. Phoera

    Phoera Senior Engineer

    Messages:
    1,713
    GridTerminalSystem returns you only terminal blocks.
    so dont need to recheck.
     
    Last edited by a moderator: Jan 20, 2015
  14. swixel

    swixel Trainee Engineer

    Messages:
    42
    I also knew this when I put it in, yet it still solved the issue... but the C++ background tells me to validate any data I get externally. C# may be safer (in that it seems you can't just arbitrary cast and break things), but I still don't trust data sources ;)
     
Thread Status:
This last post in this thread was made more than 31 days old.