1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите как сохранить схематик?

Тема в разделе "Разработка плагинов для новичков", создана пользователем InterVi, 13 июн 2015.

  1. Автор темы
    InterVi

    InterVi Старожил Пользователь

    Баллы:
    173
    Нужно сохранить регион из WG в схематик WE. Можно код для примера, пожалуйста. А то нифига не понятно, особенно что за size принимает CuboidClipboard и где его взять.
     
  2. _EnderWorld_

    _EnderWorld_ Активный участник Пользователь

    Баллы:
    78
    1. Находишь постройку.
    2. Выделяешь топором или чем-то другим из WE.
    3. Пишешь //copy
    4. Пишешь //schematic save *Имя Схемы*
    5. Чтобы вставить пишешь //schematic load *Имя Схемы*
     
  3. Автор темы
    InterVi

    InterVi Старожил Пользователь

    Баллы:
    173
    Это тут причем вообще? Я плагин пишу. Не понятно как мне в коде CuboidClipboard получить, взяв данные у ProtectedRegion в WorldGuard.
     
  4. _EnderWorld_

    _EnderWorld_ Активный участник Пользователь

    Баллы:
    78
    А ну тогда ясно.
     
  5. iServak

    iServak Активный участник Пользователь

    Баллы:
    68
    Взял из WorldEdit 6.1
    Код:
     
      public void save(CuboidClipboard clipboard, File file)
        throws IOException, DataException
      {
        int width = clipboard.getWidth();
        int height = clipboard.getHeight();
        int length = clipboard.getLength();
        if (width > 65535) {
          throw new DataException("Width of region too large for a .schematic");
        }
        if (height > 65535) {
          throw new DataException("Height of region too large for a .schematic");
        }
        if (length > 65535) {
          throw new DataException("Length of region too large for a .schematic");
        }
        HashMap<String, Tag> schematic = new HashMap();
        schematic.put("Width", new ShortTag((short)width));
        schematic.put("Length", new ShortTag((short)length));
        schematic.put("Height", new ShortTag((short)height));
        schematic.put("Materials", new StringTag("Alpha"));
        schematic.put("WEOriginX", new IntTag(clipboard.getOrigin().getBlockX()));
        schematic.put("WEOriginY", new IntTag(clipboard.getOrigin().getBlockY()));
        schematic.put("WEOriginZ", new IntTag(clipboard.getOrigin().getBlockZ()));
        schematic.put("WEOffsetX", new IntTag(clipboard.getOffset().getBlockX()));
        schematic.put("WEOffsetY", new IntTag(clipboard.getOffset().getBlockY()));
        schematic.put("WEOffsetZ", new IntTag(clipboard.getOffset().getBlockZ()));
      
        byte[] blocks = new byte[width * height * length];
        byte[] addBlocks = null;
        byte[] blockData = new byte[width * height * length];
        ArrayList<Tag> tileEntities = new ArrayList();
        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));
              if (block.getType() > 255)
              {
                if (addBlocks == null) {
                  addBlocks = new byte[(blocks.length >> 1) + 1];
                }
                addBlocks[(index >> 1)] = ((byte)((index & 0x1) == 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());
            
              CompoundTag rawTag = block.getNbtData();
              if (rawTag != null)
              {
                Map<String, Tag> values = new HashMap();
                for (Map.Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
                  values.put(entry.getKey(), entry.getValue());
                }
                values.put("id", new StringTag(block.getNbtId()));
                values.put("x", new IntTag(x));
                values.put("y", new IntTag(y));
                values.put("z", new IntTag(z));
              
                CompoundTag tileEntityTag = new CompoundTag(values);
                tileEntities.add(tileEntityTag);
              }
            }
          }
        }
        schematic.put("Blocks", new ByteArrayTag(blocks));
        schematic.put("Data", new ByteArrayTag(blockData));
        schematic.put("Entities", new ListTag(CompoundTag.class, new ArrayList()));
        schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
        if (addBlocks != null) {
          schematic.put("AddBlocks", new ByteArrayTag(addBlocks));
        }
        CompoundTag schematicTag = new CompoundTag(schematic);
        NBTOutputStream stream = new NBTOutputStream(new GZIPOutputStream(new FileOutputStream(file)));
        stream.writeNamedTag("Schematic", schematicTag);
        stream.close();
      }
     
    Последнее редактирование: 13 июн 2015
  6. Автор темы
    InterVi

    InterVi Старожил Пользователь

    Баллы:
    173
    А про CuboidClipboard можно подробнее, как его получить? Его не от игрока взять нужно, а от региона WorldGuard. Нигде не нашел как можно его собрать искусственно.
     
  7. iServak

    iServak Активный участник Пользователь

    Баллы:
    68
    Короче, вот метод, который выделяет заданный регион
    Код:
    protected static void setPlayerSelection(Player player, ProtectedRegion region) throws CommandException {
    WorldEditPlugin worldEdit = WorldGuardPlugin.inst().getWorldEdit();
    World world = player.getWorld();
    // Set selection
    if (region instanceof ProtectedCuboidRegion) {
    ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
    Vector pt1 = cuboid.getMinimumPoint();
    Vector pt2 = cuboid.getMaximumPoint();
    CuboidSelection selection = new CuboidSelection(world, pt1, pt2);
    worldEdit.setSelection(player, selection);
    player.sendMessage(ChatColor.YELLOW + "Region selected as a cuboid.");
    } else if (region instanceof ProtectedPolygonalRegion) {
    ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
    Polygonal2DSelection selection = new Polygonal2DSelection(
    world, poly2d.getPoints(),
    poly2d.getMinimumPoint().getBlockY(),
    poly2d.getMaximumPoint().getBlockY() );
    worldEdit.setSelection(player, selection);
    player.sendMessage(ChatColor.YELLOW + "Region selected as a polygon.");
    } else if (region instanceof GlobalProtectedRegion) {
    throw new CommandException(
    "Can't select global regions! " +
    "That would cover the entire world.");
    } else {
    throw new CommandException("Unknown region type: " +
    region.getClass().getCanonicalName());
    }
    }
    
    
    Дальше сам сможешь?
    Нужно будет получить то, что "выделил" игрок
     
  8. Автор темы
    InterVi

    InterVi Старожил Пользователь

    Баллы:
    173
    Ну вроде понятно, придется все-таки возится с игроком. Спасибо.
     
  9. D_ART

    D_ART Старожил Девелопер Пользователь

    Баллы:
    173
    Имя в Minecraft:
    Artarious
    Тоже была необходимость сохранить схематик в файл без участия игрока. В итоге, удалось собрать только вот такой вот велосипед:

    Код:
    RegionManager rg = WGBukkit.getRegionManager( world );
    Map< String, ProtectedRegion > regions = rg.getRegions();
    
    saveToSchematic( protectedregion );
    Код:
        private void saveToSchematic( ProtectedRegion region) {   
            Vector minimumPoint = region.getMinimumPoint();
            Vector maximumPoint = region.getMaximumPoint();
    
            Vector regionSize = maximumPoint.subtract(minimumPoint).add(1, 1, 1);
            int regionVolume = regionSize.getBlockX() * regionSize.getBlockY() * regionSize.getBlockZ();
           
            File schematicsFolder = new File(plugin.getDataFolder(), "hash/schematics/");
            File schematicFile = new File(schematicsFolder, worldName + File.separator + region.getId() + ".schematic");
            schematicFile.getParentFile().mkdirs();
        
            CuboidClipboard clipboard = new CuboidClipboard(regionSize, minimumPoint);
            EditSession editSession = new EditSession(new BukkitWorld(world), regionVolume);
            clipboard.copy(editSession);
               
            try {
                SchematicFormat.MCEDIT.save( clipboard, schematicFile );
                //format.save(clipboard, schematicFile);
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }

    Только есть один минус данного "костыля" - он не сохраняет NBT.
     
  10. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Сохраняет при наличии правильной версии WE на сервере.
     
  11. Автор темы
    InterVi

    InterVi Старожил Пользователь

    Баллы:
    173
    спасибо, займусь проверкой как будет время
    из последних?
     
  12. D_ART

    D_ART Старожил Девелопер Пользователь

    Баллы:
    173
    Имя в Minecraft:
    Artarious
    Нет, как было выявлено опытным путём, только при наличии конкретной версии WE под конкретную версию Bukkit.
    К счастью, в WE/WG 6+ добавили, так называемые, "адаптеры" в виде Forge-мода. В итоге, проблема решается установкой нужной версии мода-адаптера. Минусом является только то, что адаптеры будут только под Bukkit для 1.7.* и старше.
     
  13. Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Не схематик, а чертёж объекта!
     
  14. saharin94

    saharin94 Старожил Пользователь Заблокирован

    Баллы:
    173
    WE очень долгое время уже поддерживает блоки из модов, есть у него такая вещь как NMS.
     
  15. Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Да, но в последнее время он не умеет переносить тайлы, для этого вместе с плагином нужно устанавливать мод
    Адаптер на 1.6.4 существует, я видел только его, когда искал на 1.7.10 и не находил, а уже только потом нашёл где скачать под 1.7.10.
     
  16. amorphine

    amorphine Новичок

    Баллы:
    16
    У кого-то получилось сохранять tileEntities? Мои велосипеды так же их не сохраняют, хотя нативный WE сохраняет. Forge-версия установлена.
     
  17. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Потом ещё намучаешься их обратно вставлять.
    Лучше режь чанки.

    А если по сути, то надо выгрузить нбт тэг из тайла, сериализовать его в поток, а при вставке сделать обратный трюк. Но множетсво тайлов, особенно из модов крайне плохо реагируют на загрузку данных из тэга после загрузки чанка.
     

Поделиться этой страницей