Solved Pasting schematics in 1.13.

Discussion in 'Spigot Plugin Development' started by BadBones69, Aug 9, 2018.

  1. Hey guys, I have been looking all over the place trying to figure out how to paste a schematic in 1.13. I have been trying to use NMS if possible but can't seem to get it to work. I also tried to use World Edit's 7.0.0 dev build API but seems stuff changed and can't seem to find the methods. So I decided to turn here and see if I can get some help.

    Here is the old code I used for 1.12 down as IDs used to work and this method used IDs. But since IDs are no longer a thing I can't use this.
    Code (Text):
    @SuppressWarnings("deprecation")
    public static List<Location> pasteSchematic(File f, Location loc) {
        loc = loc.subtract(2, 1, 2);
        List<Location> locations = new ArrayList<>();
        try {
            FileInputStream fis = new FileInputStream(f);
            NBTTagCompound nbt = NBTCompressedStreamTools.a(fis);
            short width = nbt.getShort("Width");
            short height = nbt.getShort("Height");
            short length = nbt.getShort("Length");
            byte[] blocks = nbt.getByteArray("Blocks");
            byte[] data = nbt.getByteArray("Data");
            fis.close();
            //paste
            for(int x = 0; x < width; ++x) {
                for(int y = 0; y < height; ++y) {
                    for(int z = 0; z < length; ++z) {
                        int index = y * width * length + z * width + x;
                        final Location l = new Location(loc.getWorld(), x + loc.getX(), y + loc.getY(), z + loc.getZ());
                        int b = blocks[index] & 0xFF;//make the block unsigned, so that blocks with an id over 127, like quartz and emerald, can be pasted
                        final Block block = l.getBlock();
                        Material m = Material.getMaterial(b);
                        block.setType(m);
                        //you can check what type the block is here, like if(m.equals(Material.BEACON)) to check if it's a beacon
                        locations.add(l);
                    }
                }
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return locations;
    }
    Was wondering if anyone had a good way to paste schematics that World Edit makes.
     
  2. I don't think any of the above is going to be helpful.

    If you want to continue to support legacy schematics in 1.13 you will have to use block ids. Someone can correct me, but I believe there's no way around it. The schematic file has ids in it, you need to translate those ids to 1.13 Material enums.

    I handle this by converting them myself:

    https://github.com/elBukkit/MagicPl...lmakers/mine/bukkit/block/Schematic.java#L101

    The getMaterial method does the bulk of the work:

    https://github.com/elBukkit/MagicPl.../bukkit/utility/CompatibilityUtils.java#L1434

    The main method of translating id to Material is in there, too, basically I just made a Map myself. The trick is I had to use reflection to do this, because if you specify "api-version: 1.13" in your plugin.yml, which you should do, the legacy materials get removed from Material.values(). But you can be sneaky and still get at them with reflection (sorry, md_5!)
     
  3. It's even worse. Schematics uses 1 byte for each ID.
    Within 1.13 there are more than 256 blocks, so a world (or a specific area within a world) can no more be represented by a schematic file format.
    This would only make sense, if you're planning to paste only schematics and don't want to create some from a 1.13 world.
     
  4. I am going 1.13 only for my plugin so ill be using newer schematics as well.
     
  5. Oh, then disregard everything I said. Probably wait for WE to make up its mind about schematic format, or use NMS structures instead.
     
  6. What are "newer" schematics? Newer than what?
     
  7. Sorry, I ment make a new schematic with World Edit since it will probably update it's format to not use IDs. Not sure if that will happen though.

    I don't mind waiting but all my plugin users are begging for the update lol. I could disable the part that uses this but it might make people upset so I am unsure atm.
     
  8. I just checked, it didn't happen yet:
    https://minecraft.gamepedia.com/Schematic_file_format
    Would you be interested in a structure library & API, which offers you the same possibilities like schematics?
    Just asking, because i'm thinking of releasing mine.
     
  9. Can you explain a bit more for me?
     
  10. You want world edit to handle schematics within 1.13.
    I say due to the definition of a schematic it can't be used in 1.13, that's why you should use structures (mojangs definition of an part of the world).

    What if you would have a API, which offers you the same like WorldEdit with schematics (just like that easy), only with mojangs structres (which can be handled as easy as structures).

    EDIT: Obviously there is less interest...
     
    #11 Michel_0, Aug 9, 2018
    Last edited: Aug 9, 2018
  11. Doesn't sound to bad. I wouldn't mind checking it out if you do make one public.
     
    • Agree Agree x 1
  12. This would be huge. After searching online for a while it seems like a Structure API would save a lot of people quite a bit of time.
     
  13. Since there seem to be at least some interest now, i'll share something i've got.
    Feel free to use it, as long as you don't do major changes i would be pleased if you don't change the package name.

    I've also done a PR on GitHub for SpongeSchematics to support tile entities, entities and make some other things more clear, but there doesn't seem to happen anything anymore (https://github.com/SpongePowered/Schematic-Specification/pulls).

    Since there is a 20000 character limit, i can't post the classes here, but as attachment you'll find a JAR with 2 classes.
    StructureService_v1_13_R2:
    This class is for 1.13.1, creates, saves, loads and pastes structures.
    Also offers a feature to "bypass" the 32x32x32 limit by using a whole array of structures instead of a single one.
    Since it hooks into the default structure mechanims to paste a structure, even entities & block entities should work, but didn't test much.
    Further description see JavaDoc comments.

    SortedStructure_v1_13_R2:
    Since a vanilla structure is unsorted, you can't just get a block at a specific coordinate to access its properties.
    That's why i've written this class, it sorts and indexes all blocks so each block can be directly get by its Location (e.g. as needed for worldgenerators).
    Doesn't support entities & tile entities yet, because it only sorts the block states.

    You can either use the import feature of your IDE or just decompress the JAR by yourself to get the source files.
     

    Attached Files:

    • Winner Winner x 2
  14. I know this is old and all but I just wanted to reply to your help and let you know this works great and I am very thankful for your help <3