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

Помогите Поблочное копирование (с использованием API WorldEdit и без)

Тема в разделе "Разработка плагинов для новичков", создана пользователем AndreyF, 25 фев 2013.

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

    AndreyF Активный участник

    Баллы:
    63
    Извините, что пишу сюда, просто некуда было еще написать.
    Обнаружил, что WE справляется с копированием блоков из модов, даже с копированием компьютеров.
    Мне нужно сделать поблочное копирование, поэтому WE API не вполне подходит. Пытался найти копирование в исходниках WE, но ничего там не понял.
     
    zuma2 нравится это.
  2. fromgate

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

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    @AndreyF, вынесу Ваше сообщение в отдельную тему.

    Насколько я помню WorldEdit (я давно в его исходники не заглядывал) в нем как раз реализовано поблочное копирование. Просто там используется массив для "переноса", поэтому возможно выглядит коряво. Зато работает быстрее.

    Если же нужно поблочное копирование, то в принципе все просто.
    Перебирайте блоки области в цикле, определяете куда нужно копировать блок, выполняете target.setTypeIdAndData(source.getType(),source.getData(),false); (где target - куда копируем, source - откуда).
     
    ВремяПриключений и MrRazull нравится это.
  3. VaNnOrus

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

    Баллы:
    123
    На самом деле не совсем понятно что требуется.
    AndreyF, быть может расскажете в чем заключается изначальная задача?
     
  4. ql_Nik_lp

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

    Баллы:
    173
    Skype:
    q-nik-p
    Имя в Minecraft:
    ql_Nik_lp
    Как я понял человек хочет реализовать что то типа copy-paste для одного блока, а ответ уже дал fromgate
     
    MineMan910 нравится это.
  5. Автор темы
    AndreyF

    AndreyF Активный участник

    Баллы:
    63
    Спасибо конечно за помощь, но до того что предложил @fromgate я додумался сразу. Такой способ не скопирует, например, надпись на табличке, память компьютера (из мода) и т.д.
    Мне нужно скопировать не только id и data блока, но и данные Tile entity.
    Сейчас использую WE примерно так:
    Код:
    import com.sk89q.worldedit.LocalWorld;
    import com.sk89q.worldedit.Vector;
    import com.sk89q.worldedit.WorldEdit;
    import com.sk89q.worldedit.blocks.BaseBlock;
    import com.sk89q.worldedit.bukkit.WorldEditPlugin;
    и т.д.
     
    WorldEdit we = ((WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit")).getWorldEdit();
    LocalWorld world = we.getServer().getWorlds().get(0);
    Vector v1 = new Vector(координаты копируемого блока);
    Vector v2 = new Vector(координаты куда копируем);
    BaseBlock block1 = world.getBlock(v1);
    world.setBlock(v2, block1, true);
    Все копируется, но хотелось бы обойтись без WE.
     
  6. DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    Кроме информации id:data, в игре имеются также дополнительные объекты - TileEntity. Они содержат всю дополнительную информацию о блоке, например текст с таблички, инвентарь сундука и т.д. Данные о каждом TileEntity легко преобразовываются в NBT формат
    Я думаю, подойдет такой способ копирования:
    * Сначала выполнить set id and data
    * Затем прочитать все NBT теги из оригинального блока
    * Применить эти теги к только что созданному блоку. НО! кроме тегов x, y, z. Их нельзя заменять!
    Потребуется использование CraftBukkit API, который зависит от версии сборки.
     
  7. fromgate

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

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    @DPOH-VAR, слушай, получается, что у блока тоже есть NBT-теги, куда можно писать все что угодно?
     
  8. DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    На самом деле не так. NBTесть не у блоков, а у TileEntity. Можно сказать, что это "особые" блоки.
    И еще одно: стандартные методы взять/установить тег вводят ограничение на его содержимое. Например, у блоков нельзя поменять тег id, и всем стандартным блокам нельзя приписать дополнительные неизвестные теги (не знаю насчет модов) т.к. данные хранятся внутри уже не в виде нбт, а в виде значений полей объекта.
    Насчет "писать что угодно" - можно писать что угодно в предметы. И еще как-то странно ведет себя SpawnPotentials.Properties у спавнеров - принимает все что угодно, но делает проверку каких-то значений входящего тега. В случае несоответствия шаблону - крашит карту или сервер.

    Я забыл уточнить, что если блок не является TileEntity, то можно остановиться на копировании id и data. Но думаю, что это уточнение было бы лишним ;-)
     
  9. fromgate

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

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    @DPOH-VAR, я просто мыслю в таком направлении. Мне нужно сохранять дополнительные данные по карте применительно к блоку. Точнее даже к координатам x,z. Сохранять отдельно - не очень хотелось бы. Я думал, если можно задавать NBT для любых блоков, то меня как раз бы устроил слой бедрока при y=0 :) Но раз это только для TileEntity, то не подходит.
     
  10. yar1k

    yar1k Активный участник

    Баллы:
    63
    Имя в Minecraft:
    yar1k
    Спасибо, но я не понимаю, как обратно выгрузить из yaml? Мне никогда не приходилось с ним работать, так как в .net с ним не работают. Помогите пожалуйста еще чуток :)
     
  11. fromgate

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

    Баллы:
    173
    Имя в Minecraft:
    fromgate
  12. ql_Nik_lp

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

    Баллы:
    173
    Skype:
    q-nik-p
    Имя в Minecraft:
    ql_Nik_lp
    Слушайте, может кто скинуть пример кода с редактированием этих самых NBT-тегов?
     
    DavidShabaev нравится это.
  13. DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    @ql_Nik_lp,
    Прочитать теги:
    TileEntity tile1 = craftWorld.getTileEntityAt(x1,y1,z1); // берем плитку
    NBTTagCompound compound = new NBTTagCompound(); // создаем пустой NBT тег
    if (tile1 == null) return; // проверка обязательна, но можно структурировать по другому
    tile1.b(compound); // загружем в тег все данные с плитки
    Записать теги:
    TileEntity tile2 = craftWorld.getTileEntityAt(x2,y2,z2); // берем другую плитку
    if (tile2 == null) return; // опять же проверка
    tile2.a(compound); // загружаем в плитку данные с тега.
    Замечания:
    - Нельзя заменять теги x,y,z. Это приведет к неработоспособности самого блока.
    - Игрок просто так не увидит изменения блока. Для этого нужно сгенерировать новый сетевой пакет и отправить ему в принудительном порядке:
    EntityPlayer.playerConnection.sendPacket(tile2.getUpdatePacket());
    - CraftWorld мы получаем простым приведением от World
    CraftWorld craftWorld = (CraftWorld) world;
    - EntityPlayer мы получаем из craftPlayer.getHandle(); а самого СraftPlayer - приведением от Player

    Могу поделиться своими исходниками, но я там делал все другим методом, через рефлексии.
     
  14. Автор темы
    AndreyF

    AndreyF Активный участник

    Баллы:
    63
    @DPOH-VAR, спасибо.
    Возникла проблема – при замене блока сундука или другого контейнера на другой блок, из него вылетают все предметы. Получается, что написанная вами последовательность действий не совсем правильна.
    Как правильно заменить блок, имеющий TileEntity, на другой блок?
     
  15. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    Знакомя проблема, в своё время так и не решил, @DPOH-VAR тоже сразу не смог помочь. Так и не закончили плагин общими "усилиями". Тег у блока как-бы изменяется, но все предметы почему-то вылетают рядом с сундуком...
     
  16. VaNnOrus

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

    Баллы:
    123
    Быть может имеет смысл покопаться в исходниках WE и посмотреть как он копирует все?
     
  17. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    Гиблое дело копать такую тонну чужого кода. В таких больших плагинах искать что-то одно - это как собирать лего из миллиона деталей)

    Дождемся знающего человека, возможно он нашел решение ;)
     
  18. DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    Да, при замене полного сундука другим блоком, его содержимое выпадает. Но я не думал, что это проблема.
    Добавим тогда еще один пункт, в начале:
    Перед заменой, если BlockState целевого блока является InventoryHolder'ом - почистить его инвентарь.
    Или более хардкорный способ: полностью очистить его NBT (т.е. установить пустой) - метод может быть полезен для модов с нестандартными блоками.
    UPD:
    Там черт ногу сломит. Код WE хорошо структурирован, но автор явно не задумывался о том, что его код кто-то будет читать.
     
    fromgate нравится это.
  19. fromgate

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

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    Вот это уж точно :)
     
  20. VaNnOrus

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

    Баллы:
    123
    Ну что есть, то есть :D
    Однако если б я его не изучал, то до сих пор бы сидел без плагина "почанкового" выделения :)
     

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