BlockState /

  • Автор темы Автор темы molor
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

molor

Активный участник
Пользователь
Баллы
66
Ну такое. Игрок может сломать сундук с вещами внутри. Перед разрушением блока я отменяю это событие, получаю BlockState блока сундука и сохраняю его в HashMap<Location, BlockState>, где Location - его координаты на сервере. Через несколько минут этот блок восстанавливается по этим данным. Всё бы хорошо, но.. все вещи в инвентаре сундука просто исчезают. Подскажите, какого чёрта? Чего я не знаю или что делаю неправильно?

Добавление:
Java:
Location location = block.getLocation();

if (hashMap.containsKey(location)) {
  return;
}

hashMap.put(location, block.getState());

Восстановление:
Java:
((InventoryHolder) block.getState()).getInventory().setContents(((InventoryHolder) hashMap.get(location)).getInventory().getContents());
 
Сохраняй в мапу не BlockState, а сразу лист\массив айтемстаков из содержимого сундука
 
Сохраняй в мапу не BlockState, а сразу лист\массив айтемстаков из содержимого сундука
Проблема в том, что я планирую расширить код, добавив поддержку других блоков. Например, табличек. Насколько я понял, у всех этих блоков используется BlockState. И сейчас мне больше интересно, почему такой вариант не работает. Часа два убил на это, меняя по строчке, но ни к чему так и не пришёл.
 
Забавно, что в событии разрушения блока ((InventoryHolder) blockState).getInventory().getContents(); возвращает всё правильно, однако если вызвать этот же код позже через scheduler, то getContents() возвращает одни null'ы..

Может потому что у блока нету контейнра. Тебе нужно снять с него тайлентити.
Не врубаюсь, это как?
 
Может, блока на месте нет, когда нуллы идут?
Да, его там нет. Я взял с него BlockState (который, как пишут в доках, represents a captured state of a block, which will not change automatically), после чего Material у блока заменил на AIR. Спустя некоторое время я хочу восстановить этот блок со всеми его данными из BlockState, который просто хранится в HashMap, но получается вот такое.
 
Да, его там нет. Я взял с него BlockState (который, как пишут в доках, represents a captured state of a block, which will not change automatically), после чего Material у блока заменил на AIR. Спустя некоторое время я хочу восстановить этот блок со всеми его данными из BlockState, который просто хранится в HashMap, но получается вот такое.
дело в том что у блока не может быть контейнера т.е. инвентаря и т.д, НО у ентити - может. поэтому вместо того, чтобы получать блок тебе нужно получить TileEntity (TileEntityChest), как @alexandrage сказал уже выше
 
Я правильно понимаю, что это уже NMS и универсальности для любого типа блока и версии ядра не выйдет..? Или, как получить TileEntity иначе?
 
Последнее редактирование:
Так получать-то хоть?
Java:
CraftWorld craftWorld = (CraftWorld) location.getWorld();
TileEntity tileEntity = craftWorld.getTileEntityAt(location.getBlockX(), location.getBlockY(), location.getBlockZ());

if (tileEntity != null) {
  NBTTagCompound nbt = new NBTTagCompound();
  tileEntity.save(nbt);
}

А вот как записать эти данные в блок, я не пойму. Напишите пример кода, пожалуйста.
 
Ору с нубов. Через ведроапи же можно получить контейнер обычного сундука.
 
Ору с нубов. Через ведроапи же можно получить контейнер обычного сундука.
Так Вы хоть намёк дайте, в сторону какого метода рыть. Нубы ведь после прочтения Ваших мыслей нубами быть не перестанут. Наверное.

Да и теперь уже нужен способ сохранения любого блока в память, а не только контейнер сундука. Но до меня вот не доходит, как это сделать лучше всего, поэтому я пробую всё подряд.
 
Так Вы хоть намёк дайте, в сторону какого метода рыть. Нубы ведь после прочтения Ваших мыслей нубами быть не перестанут. Наверное.

Да и теперь уже нужен способ сохранения любого блока в память, а не только контейнер сундука. Но до меня вот не доходит, как это сделать лучше всего, поэтому я пробую всё подряд.
а точн Chest chest = (Chest) state;
 
Так Вы хоть намёк дайте, в сторону какого метода рыть. Нубы ведь после прочтения Ваших мыслей нубами быть не перестанут. Наверное.

Да и теперь уже нужен способ сохранения любого блока в память, а не только контейнер сундука. Но до меня вот не доходит, как это сделать лучше всего, поэтому я пробую всё подряд.

Java:
        BlockState state = block.getState();
        if(!(state instanceof InventoryHolder)) return;
        InventoryHolder chest = (InventoryHolder)state;
        if(chest instanceof Chest) {
            ItemStack[] stacks = chest.getInventory().getContents().clone();
        }
 
Нет, save.
Да и теперь уже нужен способ сохранения любого блока в память, а не только контейнер сундука. Но до меня вот не доходит, как это сделать лучше всего, поэтому я пробую всё подряд.
Просто клонируй BlockState/его содержимое себе и все дела.
 
Просто клонируй BlockState себе и все дела.
Как? У BlockState нет clone(). Хотя этот метод и не должен быть, так как BlockState хранит в себе состояние блока в конкретный момент времени, и это сохранение не должно меняться. Однако, оно таки меняется.
 
Как? У BlockState нет clone(). Хотя этот метод и не должен быть, так как BlockState хранит в себе состояние блока в конкретный момент времени, и это сохранение не должно меняться. Однако, оно таки меняется.
https://github.com/kostaskougios/cloning/
Только не используй метод deepClone - склонируешь весь сервер.
Забей, ответ постом выше.
Твой ответ корректен только для уникальных классов. molor же хочет одну реализацию для всего, что реализует BlockState. И хочет он это красиво, а не как обычно.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх