Обновление блоков из Vanilla Minecraft

Версия Minecraft
1.12.2
205
12
103
Приветствую. Столкнулся с очередной дилеммой: не знаю как выполнять какие-либо действия при обновлении ванильных блоков без создания тайла.
Дабы было понятнее, представлю абстрактную задачу: Нужно случайным образом при обновлении блока бедрока спавнить на нем овцу.
Т.е.подошел я к блоку бедрока, стою около него, и через случайное время в рамках определенного диапазона на нем спавнится овца.

Хотелось бы узнать:
Возможно ли это, и если да, то:
  • Где это делать;
  • Как это делать.
 
205
12
103
Ванильный бэдрок не обновляется.
Предлагаю сделать в эвенте тика игрока. Просто рандомно чекай вокруг игрока блоки и если это бэдрок, спавни овцу.
Так-с... Проверка блоков вокруг, как мне кажется, дело не из приятных, в плане производительности. Если говорить не об абстрактной задаче, а о реальной, то все получается следующим образом:
Есть у меня тыква и энтить, которая уподобляется блоку(полностью наследует все его свойства, по ней можно ходить, она вписывается в сетку блока и вот это вот всё (кроме звука передвижения по ней, этого пока не осилил)). Мне нужно чтоб обычная тыква с небольшим шансом(даже если он будет неточным - неважно) превращалась в энтить, которую сделал я. Я где-то уже видел похожую механику, но точно не помню где (EnderZoo и DivineRPG, кажется). Если выходов, кроме как чекать окружение игрока, не остается, то придется использовать его. Но пока я надеюсь на менее суровый подход, вернее на то, что он существует.
 
7,099
324
1,510
Есть выход: при генерации мира или при регистрации блоков заменяй целевой блок на свой, в котором добавлены нужное поведение. С тыквами крайне просто: при генерации можно с некоторым шансом заменять ванильные тыквы на свои, которые при добыче спаунят нужную энтити. В бедроком сложнее, могут сломаться механики из других модов(например, enderio - получение кусочка бесконечности) и тут больше подойдет замена блоков при регистрации
 
205
12
103
Тебе нужно перерегать свой объект блока для дефолтного бедрока

при регистрации блоков заменяй целевой блок на свой
Уже больше похоже на подходящий вариант, однако я совершенно не представляю как это можно сделать (на форуме пока что тоже не нашел). Кроме того назревает вопрос - блок будет обозначен как minecraft: pumpkin, или как мой modid:id? Интересуюсь на случай, если какой-то из других модов захочет получить именно ванильную тыкву, а обнаружит там мою. Логично предположить что там будет первый вариант и всё нормально, но мало ли...
 

tox1cozZ

aka Agravaine
8,456
598
2,893
Кто-нибудь поставит мод, затем удалит и всё
Хей, мы просто заменяем объект в регистрации на свой, айдишник остается таким же. Поэтому после удаления мода мир не сломается.
 
205
12
103
Что имеется на данный момент:

Java:
public class BlockCustomPumpkin extends BlockPumpkin {
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        this.teleport(worldIn, pos);
        return true;
    }

    public void onBlockClicked(World worldIn, BlockPos pos, EntityPlayer playerIn)
    {
        this.teleport(worldIn, pos);
    }

    private void teleport(World worldIn, BlockPos pos)
    {
        IBlockState iblockstate = worldIn.getBlockState(pos);

        if (iblockstate.getBlock() == this)
        {
            for (int i = 0; i < 1000; ++i)
            {
                BlockPos blockpos = pos.add(worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16), worldIn.rand.nextInt(8) - worldIn.rand.nextInt(8), worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16));

                if (worldIn.isAirBlock(blockpos))
                {
                    if (worldIn.isRemote)
                    {
                        for (int j = 0; j < 128; ++j)
                        {
                            double d0 = worldIn.rand.nextDouble();
                            float f = (worldIn.rand.nextFloat() - 0.5F) * 0.2F;
                            float f1 = (worldIn.rand.nextFloat() - 0.5F) * 0.2F;
                            float f2 = (worldIn.rand.nextFloat() - 0.5F) * 0.2F;
                            double d1 = (double)blockpos.getX() + (double)(pos.getX() - blockpos.getX()) * d0 + (worldIn.rand.nextDouble() - 0.5D) + 0.5D;
                            double d2 = (double)blockpos.getY() + (double)(pos.getY() - blockpos.getY()) * d0 + worldIn.rand.nextDouble() - 0.5D;
                            double d3 = (double)blockpos.getZ() + (double)(pos.getZ() - blockpos.getZ()) * d0 + (worldIn.rand.nextDouble() - 0.5D) + 0.5D;
                            worldIn.spawnParticle(EnumParticleTypes.PORTAL, d1, d2, d3, (double)f, (double)f1, (double)f2);
                        }
                    }
                    else
                    {
                        worldIn.setBlockState(blockpos, iblockstate, 2);
                        worldIn.setBlockToAir(pos);
                    }

                    return;
                }
            }
        }
    }
}
P.S - Для теста блока взял код телепортации яйца дракона.

Java:
@Mod.EventBusSubscriber
public class RegistryHandler {

    @SubscribeEvent
    public void onBlockRegistry(final RegistryEvent.Register<Block> event) {
        event.getRegistry().register(new BlockCustomPumpkin().setRegistryName(new ResourceLocation("minecraft", "pumpkin")));
    }
}

Блок заменился, наследует все, что мне нужно, однако... Почти весь егованильный функционал отошел в мир иной. При выращивании тыкв получается вот такая штука:
1580396870329.png
P.S. Win7 retard detected :3

Где я косякнул (Делал наугад, ибо вообще не представляю как такое должно реализоваться)?
 
205
12
103
Куда именно инжектил то? Опиши решение подробнее, плиз
Java:
@Mixin(Block.class)
public abstract class MixinBlock {
    @Inject(method = "updateTick", at = @At("HEAD"))
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) {
        Block block = (Block) (Object) this;
        if (block instanceof BlockPumpkin) {
            if (rand.nextInt(15) == 0) {
                worldIn.setBlockState(pos, Blocks.FIRE.getDefaultState());
            }
        }
    }
}
Внутри метода пример кода.

Как заинжектиться напрямую в класс тыквы с добавлением нового метода - пока не нашел. Потому и изменяю существующий метод суперкласса.
 
Сверху