Как выдать командный блок с уже написанной командой? (1.8)

271
2
0
Как выдать командный блок с уже написанной командой?
 
Up
 
Пример сохранения данных в ItemStack при сносе блока и восстановлении данных при повторной установке блока.
https://bitbucket.org/Shuleshkin/nedocomputers/annotate/5ab6ac6732fa180f775ccd9633c34ef3b9b02402/src/main/java/nedocomputers/block/BlockCPU.java?at=default&fileviewer=file-view-default
В твоем случае придется все это делать не в самом блоке, а в событиях.
 
Up
 
В 1.7.10 команда хранится в НБТ блока, не думаю что в 1.8 что-то сильно изменилось.
Попробую объяснить как это работает в 1.7.10
Основная часть логики командного блока находится в классе CommandBlockLogic, там же находится и запись в НБТ.
Видно, что данные записываются с тегами: Command, SuccessCount, CustomName, LastOutput, TrackOutput. Очевидно, что команда записывается с тегом "Command".
Теперь нужно определить, берутся ли при установке коммандного блока какие-либо данные из итемстака. Открываем класс BlockCommandBlock и видим переопределенный метод onBlockPlacedBy, в котором все это может происходить.
Код:
    public void onBlockPlacedBy(World p_149689_1_, int p_149689_2_, int p_149689_3_, int p_149689_4_, EntityLivingBase p_149689_5_, ItemStack p_149689_6_)
    {
        TileEntityCommandBlock tileentitycommandblock = (TileEntityCommandBlock)p_149689_1_.getTileEntity(p_149689_2_, p_149689_3_, p_149689_4_);

        if (p_149689_6_.hasDisplayName())
        {
            tileentitycommandblock.func_145993_a().func_145754_b(p_149689_6_.getDisplayName());
        }
    }


Но, видно что из итемстака (p_149689_6_) в тайл передается только getDisplayName() (это тоже НБТ), поле команды в любом случае окажется пустым.
Поэтому можно записать в итемстак команду с произвольным тегом, а потом в событии установки блока читать этот тег и устанавливать в соответствии с прочитанным команду в блоке. Возможно в 1.8 этот метод другой и команда все таки передается и всего этого не потребуется.

Что из этого непонятно? Я готов объяснить.
 
В майне 1.8 если посмотреть на к.б и зажать ctrl + Среднюю кнопку мыши то в инвентаре появляется кб с NBT (там так написано) в котором уже написана команда.
 
Up
 
Установил 1.8.8
Все достаточно очевидно. Все классы про которые я писал почти не изменились, но изменился класс ItemBlock, в нем появился метод:


Код:
    public static boolean setTileEntityNBT(World worldIn, EntityPlayer pos, BlockPos stack, ItemStack p_179224_3_)
    {
        MinecraftServer minecraftserver = MinecraftServer.getServer();

        if (minecraftserver == null)
        {
            return false;
        }
        else
        {
            if (p_179224_3_.hasTagCompound() && p_179224_3_.getTagCompound().hasKey("BlockEntityTag", 10))
            {
                TileEntity tileentity = worldIn.getTileEntity(stack);

                if (tileentity != null)
                {
                    if (!worldIn.isRemote && tileentity.func_183000_F() && !minecraftserver.getConfigurationManager().canSendCommands(pos.getGameProfile()))
                    {
                        return false;
                    }

                    NBTTagCompound nbttagcompound = new NBTTagCompound();
                    NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttagcompound.copy();
                    tileentity.writeToNBT(nbttagcompound);
                    NBTTagCompound nbttagcompound2 = (NBTTagCompound)p_179224_3_.getTagCompound().getTag("BlockEntityTag");
                    nbttagcompound.merge(nbttagcompound2);
                    nbttagcompound.setInteger("x", stack.getX());
                    nbttagcompound.setInteger("y", stack.getY());
                    nbttagcompound.setInteger("z", stack.getZ());

                    if (!nbttagcompound.equals(nbttagcompound1))
                    {
                        tileentity.readFromNBT(nbttagcompound);
                        tileentity.markDirty();
                        return true;
                    }
                }
            }

            return false;
        }
    }


который используется также в методе placeBlockAt (т.е. при установке блока)
Код элементарный. Из итемстака читается НБТ, из которого читается тег "BlockEntityTag" - это еще один НБТ, который уже сливается с НБТ блока.
Таким образом игроку можно выдать хоть командный блок с прописанной командой, хоть сундук с предметами.

Теперь понятно? Конечно я могу написать требуемый код, но хочется чтобы ты сам сообразил.
 
Можете дать готовый пример?
 
Ладно, но тебе стоит задуматься о изучении учебников по джаве и информатике.
Код:
ItemStack istack = new ItemStack(Blocks.command_block); // Создали итемстак с блоком.
NBTTagCompound blockEntityTag = new NBTTagCompound(); // Теперь создали пустой НБТ
blockEntityTag.setString("Command", "команда"); // Записали в него команду
NBTTagCompound nbt = new NBTTagCompound(); // Создали еще один НБТ
nbt.setTag("BlockEntityTag", blockEntityTag); // Записали во второй НБТ тег "BlockEntityTag"
istack.setTagCompound(nbt); // Записали в итемстак НБТ

Код не проверял, но не думаю что где-то ошибся.
 
Спасибо.:)
 
Назад
Сверху