Войти или зарегистрироваться

Помогите Сохранение части мира в схематику

Я дал прямую ссылку на код github'а.
Мы говорим о разных вещах. Я дал ссылку на статью с примерами кода с комментариями, а вы мне дали страницу кода, которую я уже видел и не понял.
 
Мы говорим о разных вещах. Я дал ссылку на статью с примерами кода с комментариями, а вы мне дали страницу кода, которую я уже видел и не понял.

Код:
public void save(CuboidClipboard clipboard, File file) throws IOException, DataException {
        int width = clipboard.getWidth();
        int height = clipboard.getHeight();
        int length = clipboard.getLength();

        if (width > MAX_SIZE) {
            throw new DataException("Width of region too large for a .schematic");
        }
        if (height > MAX_SIZE) {
            throw new DataException("Height of region too large for a .schematic");
        }
        if (length > MAX_SIZE) {
            throw new DataException("Length of region too large for a .schematic");
        }

        HashMap<String, Tag> schematic = new HashMap<String, Tag>();
        schematic.put("Width", new ShortTag("Width", (short) width));
        schematic.put("Length", new ShortTag("Length", (short) length));
        schematic.put("Height", new ShortTag("Height", (short) height));
        schematic.put("Materials", new StringTag("Materials", "Alpha"));
        schematic.put("WEOriginX", new IntTag("WEOriginX", clipboard.getOrigin().getBlockX()));
        schematic.put("WEOriginY", new IntTag("WEOriginY", clipboard.getOrigin().getBlockY()));
        schematic.put("WEOriginZ", new IntTag("WEOriginZ", clipboard.getOrigin().getBlockZ()));
        schematic.put("WEOffsetX", new IntTag("WEOffsetX", clipboard.getOffset().getBlockX()));
        schematic.put("WEOffsetY", new IntTag("WEOffsetY", clipboard.getOffset().getBlockY()));
        schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", clipboard.getOffset().getBlockZ()));

        // Copy
        byte[] blocks = new byte[width * height * length];
        byte[] addBlocks = null;
        byte[] blockData = new byte[width * height * length];
        ArrayList<Tag> tileEntities = new ArrayList<Tag>();

        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;
                    BaseBlock block = clipboard.getPoint(new BlockVector(x, y, z));

                    // Save 4096 IDs in an AddBlocks section
                    if (block.getType() > 255) {
                        if (addBlocks == null) { // Lazily create section
                            addBlocks = new byte[(blocks.length >> 1) + 1];
                        }

                        addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
                                addBlocks[index >> 1] & 0xF0 | (block.getType() >> 8) & 0xF
                                : addBlocks[index >> 1] & 0xF | ((block.getType() >> 8) & 0xF) << 4);
                    }

                    blocks[index] = (byte) block.getType();
                    blockData[index] = (byte) block.getData();

                    // Store TileEntity data
                    if (block instanceof TileEntityBlock) {
                        TileEntityBlock tileEntityBlock = block;

                        // Get the list of key/values from the block
                        CompoundTag rawTag = tileEntityBlock.getNbtData();
                        if (rawTag != null) {
                            Map<String, Tag> values = new HashMap<String, Tag>();
                            for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
                                values.put(entry.getKey(), entry.getValue());
                            }
                           
                            values.put("id", new StringTag("id", tileEntityBlock.getNbtId()));
                            values.put("x", new IntTag("x", x));
                            values.put("y", new IntTag("y", y));
                            values.put("z", new IntTag("z", z));
                           
                            CompoundTag tileEntityTag = new CompoundTag("TileEntity", values);
                            tileEntities.add(tileEntityTag);
                        }
                    }
                }
            }
        }

        schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
        schematic.put("Data", new ByteArrayTag("Data", blockData));
        schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
        schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
        if (addBlocks != null) {
            schematic.put("AddBlocks", new ByteArrayTag("AddBlocks", addBlocks));
        }

        // Build and output
        CompoundTag schematicTag = new CompoundTag("Schematic", schematic);
        NBTOutputStream stream = new NBTOutputStream(new FileOutputStream(file));
        stream.writeTag(schematicTag);
        stream.close();
    }

Конкретно вывод после // Build and output.
 
Код:
public void save(CuboidClipboard clipboard, File file) throws IOException, DataException {
        int width = clipboard.getWidth();
        int height = clipboard.getHeight();
        int length = clipboard.getLength();

        if (width > MAX_SIZE) {
            throw new DataException("Width of region too large for a .schematic");
        }
        if (height > MAX_SIZE) {
            throw new DataException("Height of region too large for a .schematic");
        }
        if (length > MAX_SIZE) {
            throw new DataException("Length of region too large for a .schematic");
        }

        HashMap<String, Tag> schematic = new HashMap<String, Tag>();
        schematic.put("Width", new ShortTag("Width", (short) width));
        schematic.put("Length", new ShortTag("Length", (short) length));
        schematic.put("Height", new ShortTag("Height", (short) height));
        schematic.put("Materials", new StringTag("Materials", "Alpha"));
        schematic.put("WEOriginX", new IntTag("WEOriginX", clipboard.getOrigin().getBlockX()));
        schematic.put("WEOriginY", new IntTag("WEOriginY", clipboard.getOrigin().getBlockY()));
        schematic.put("WEOriginZ", new IntTag("WEOriginZ", clipboard.getOrigin().getBlockZ()));
        schematic.put("WEOffsetX", new IntTag("WEOffsetX", clipboard.getOffset().getBlockX()));
        schematic.put("WEOffsetY", new IntTag("WEOffsetY", clipboard.getOffset().getBlockY()));
        schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", clipboard.getOffset().getBlockZ()));

        // Copy
        byte[] blocks = new byte[width * height * length];
        byte[] addBlocks = null;
        byte[] blockData = new byte[width * height * length];
        ArrayList<Tag> tileEntities = new ArrayList<Tag>();

        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;
                    BaseBlock block = clipboard.getPoint(new BlockVector(x, y, z));

                    // Save 4096 IDs in an AddBlocks section
                    if (block.getType() > 255) {
                        if (addBlocks == null) { // Lazily create section
                            addBlocks = new byte[(blocks.length >> 1) + 1];
                        }

                        addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
                                addBlocks[index >> 1] & 0xF0 | (block.getType() >> 8) & 0xF
                                : addBlocks[index >> 1] & 0xF | ((block.getType() >> 8) & 0xF) << 4);
                    }

                    blocks[index] = (byte) block.getType();
                    blockData[index] = (byte) block.getData();

                    // Store TileEntity data
                    if (block instanceof TileEntityBlock) {
                        TileEntityBlock tileEntityBlock = block;

                        // Get the list of key/values from the block
                        CompoundTag rawTag = tileEntityBlock.getNbtData();
                        if (rawTag != null) {
                            Map<String, Tag> values = new HashMap<String, Tag>();
                            for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
                                values.put(entry.getKey(), entry.getValue());
                            }
                          
                            values.put("id", new StringTag("id", tileEntityBlock.getNbtId()));
                            values.put("x", new IntTag("x", x));
                            values.put("y", new IntTag("y", y));
                            values.put("z", new IntTag("z", z));
                          
                            CompoundTag tileEntityTag = new CompoundTag("TileEntity", values);
                            tileEntities.add(tileEntityTag);
                        }
                    }
                }
            }
        }

        schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
        schematic.put("Data", new ByteArrayTag("Data", blockData));
        schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
        schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
        if (addBlocks != null) {
            schematic.put("AddBlocks", new ByteArrayTag("AddBlocks", addBlocks));
        }

        // Build and output
        CompoundTag schematicTag = new CompoundTag("Schematic", schematic);
        NBTOutputStream stream = new NBTOutputStream(new FileOutputStream(file));
        stream.writeTag(schematicTag);
        stream.close();
    }

Конкретно вывод после // Build and output.
А вот это уже что-то. Попробую.
 
Я вот такое наугад сделал:
Код:
    public static void save(Location from, Location to, File file) throws IOException, DataException{
        Location ll = from.subtract(to);
        Vector lv = new Vector(ll.getBlockX(), ll.getBlockY(), ll.getBlockZ());
        new CuboidClipboard(lv,
                new Vector(from.getBlockX(), from.getBlockY(), from.getBlockZ()),
                new Vector(to.getBlockX(), to.getBlockY(), to.getBlockZ()))
        .saveSchematic(file);
    }
Размер схематики тот, но внутри ничего нет. Схематика пустая. from по всем параметрам больше to, если что.
@kirill2011s, всё равно не понятно, что такое size, offset и origin.
 
Я вот такое наугад сделал:
Код:
    public static void save(Location from, Location to, File file) throws IOException, DataException{
        Location ll = from.subtract(to);
        Vector lv = new Vector(ll.getBlockX(), ll.getBlockY(), ll.getBlockZ());
        new CuboidClipboard(lv,
                new Vector(from.getBlockX(), from.getBlockY(), from.getBlockZ()),
                new Vector(to.getBlockX(), to.getBlockY(), to.getBlockZ()))
        .saveSchematic(file);
    }
Размер схематики тот, но внутри ничего нет. Схематика пустая. from по всем параметрам больше to, если что.
@kirill2011s, всё равно не понятно, что такое size, offset и origin.

Где написаны size offset и origin? Чет не могу найти)
 
Честно говоря я уже мало помню ;)
Вообще же, насколько помню сотвторить CuboidClipboard должно быть не сложно. У меня правда была обратная операция - https://github.com/fromgate/ScLoad/blob/master/src/me/fromgate/scload/SLQueue.java я всё же загружал из файла и готовил очередь на установку блоков
 
Честно говоря я уже мало помню ;)
Вообще же, насколько помню сотвторить CuboidClipboard должно быть не сложно. У меня правда была обратная операция - https://github.com/fromgate/ScLoad/blob/master/src/me/fromgate/scload/SLQueue.java я всё же загружал из файла и готовил очередь на установку блоков
Я смотрел ваши исходники, но мне не нужна загрузка. Сложность в том, что я не знаю, как делать CuboidClipboard. Что означают все эти size, offset и origin.
 
Последнее редактирование:
В конструкторе CuboidClipboard.

Вообщем, долго искал, и судя по этому:
Код:
        Region region = session.getSelection(player.getWorld());
        Vector min = region.getMinimumPoint();
        Vector max = region.getMaximumPoint();
        Vector pos = session.getPlacementPosition(player);

        CuboidClipboard clipboard = new CuboidClipboard(
                max.subtract(min).add(Vector.ONE),
                min, min.subtract(pos));

Третий тип конструктора, самое то. Ну в общем, дальше думаю разберетесь.
 
Вообщем, долго искал, и судя по этому:
Код:
        Region region = session.getSelection(player.getWorld());
        Vector min = region.getMinimumPoint();
        Vector max = region.getMaximumPoint();
        Vector pos = session.getPlacementPosition(player);

        CuboidClipboard clipboard = new CuboidClipboard(
                max.subtract(min).add(Vector.ONE),
                min, min.subtract(pos));

Третий тип конструктора, самое то. Ну в общем, дальше думаю разберетесь.
Спасибо за помощь.
Вообщем, долго искал, и судя по этому:
Код:
        Region region = session.getSelection(player.getWorld());
        Vector min = region.getMinimumPoint();
        Vector max = region.getMaximumPoint();
        Vector pos = session.getPlacementPosition(player);

        CuboidClipboard clipboard = new CuboidClipboard(
                max.subtract(min).add(Vector.ONE),
                min, min.subtract(pos));

Третий тип конструктора, самое то. Ну в общем, дальше думаю разберетесь.
Вот ещё, а что означает pos?
 
Судя по всему это позиция игрока относительно которой начинается формирование клипборда. Чтобы потом точно также вставлять.
 
Судя по всему это позиция игрока относительно которой начинается формирование клипборда. Чтобы потом точно также вставлять.
Тогда буду использовать минимальную точку, но min.subtract(pos) - это будет 0?
 
Ну а когда там отрицательные значения - Вас это не смущает? По идее должно быть всё нормально
 
Ну а когд. там отрицательные значения - Вас это не смущает? По идее должно быть всё нормально
Это относительный 0?
Сделал вот так:
Код:
        Location[] c = arena.getCorners();
        Vector min = vector(c[1]);
        Vector max = vector(c[0]);
        Vector offset = new Vector(0, 0, 0);
        try {
            SchematicFormat.MCEDIT.save(new CuboidClipboard(
                    max.subtract(min).add(Vector.ONE),
                    min, offset), new File(TheBridges.instance.getDataFolder(), "arena.schematic"));
        } catch (IOException | DataException e) {
            e.printStackTrace();
        }
Но схематика создается в два раза больше, чем надо, и пустая.
Изменил на
new CuboidClipboard( max, min, new Vector(0,0,0))
размер, вроде, нормальный, но схематика пустая.
 
Последнее редактирование:
А кто в клипбоард блоки то скопирует, магия?

Вот тебе кусок рабочего кода, работай
https://github.com/Shevchik/AutoSav...reads/worldregen/SchematicOperations.java#L43
Спасибо, посмотрю.
Я сделал вот такой класс:
Код:
public class Schematic {
  
    public static void save(File file, Location from, Location to){
        try {
            BukkitWorld bw = new BukkitWorld(from.getWorld());
            EditSession es = new EditSession(bw, Integer.MAX_VALUE);
            CuboidClipboard clipboard = new CuboidClipboard(
                vector(to.subtract(from).add(1, 1, 1)),
                vector(from),
                vector(from.subtract(to))
            );
            Region region = new CuboidRegion(bw, vector(from), vector(to));
            es.setFastMode(true);
            clipboard.copy(es);
            LocalEntity[] entities = bw.getEntities(region);
            for (LocalEntity entity : entities) {
                clipboard.storeEntity(entity);
            }
            SchematicFormat.MCEDIT.save(clipboard, file);
        } catch (IOException | DataException e) {
            e.printStackTrace();
        }
    }
  
    public static void loadAndPaste(File file, Location loc) throws IOException, DataException{
        final CuboidClipboard clipboard = SchematicFormat.MCEDIT.load(file);
      
        final Vector size = clipboard.getSize();
        final Vector origin = clipboard.getOrigin();
        for (int x = -16*3; x < size.getBlockX() + 16*3; x+=16) {
            for (int z = -16*3; z < size.getBlockZ() + 16*3; z+=16) {
                loc.getWorld().getChunkAt(origin.getBlockX()+x, origin.getBlockZ()+z).load();
            }
        }
      
        EditSession es = new EditSession(new BukkitWorld(loc.getWorld()), Integer.MAX_VALUE);
        es.setFastMode(true);
        es.enableQueue();
        for (int x = 0; x < size.getBlockX(); ++x) {
            for (int y = 0; y < size.getBlockY(); ++y) {
                for (int z = 0; z < size.getBlockZ(); ++z) {
                    Vector blockpos = new Vector(x, y, z);
                    final BaseBlock block = clipboard.getBlock(blockpos);

                    if (block == null) {
                        continue;
                    }

                    Bukkit.getScheduler().runTask(TheBridges.instance, new PasteRunnable(blockpos.add(origin), block, es));
                }
            }
        }
        try {
            es.flushQueue();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        try {
            clipboard.pasteEntities(origin);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
  
    private static Vector vector(Location loc){
        return new Vector(loc.getX(), loc.getY(), loc.getX());
    }
  
}

class PasteRunnable implements Runnable {
  
    Vector pos;
    BaseBlock block;
    EditSession es;
  
    public PasteRunnable(Vector pos, BaseBlock block, EditSession es){
        this.pos = pos;
        this.block = block;
        this.es = es;
    }

    @Override
    public void run() {
        try {
            es.smartSetBlock(pos, block);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
  
}
Он делает схематику, но не загружает её обратно. На карте ничего не меняется.
 
Назад
Верх