Вода в RightClickBlock event

Версия Minecraft
1.18.2
API
Forge
75
1
2
У меня есть предмет, который при использовании на воде, должен превращаться в другой предмет. Пробовал через PlayerInteractEvent.RightClickBlock получать блок воды, на который наведён игрок, однако так не работает, т.к. на жидкость навестись нельзя. Так как можно "увидеть" жидкость?
 
Решение
попробовал сделать как в f3 гуишке, но через ивент(не хочу специально для одного предмета отдельный класс делать), но теперь проблема такая, что предмет превращается сразу по 2, а не по 1. Попробовал дебажить - увидел, что код выполняется аж 4 раза подряд, 2 на сервере и 2 на клиенте. Как сделать так, чтоб осталась лишь серверная сторона выполнения?

Java:
if (player.getItemInHand(InteractionHand.MAIN_HAND).getItem() == ModItems.DRY_MORTAR.get())
    {
      HitResult liquid;
      liquid = player.pick(20.0D, 0.0F, true);
      if (liquid.getType() == HitResult.Type.BLOCK)
      {
        BlockPos blockpos1 = ((BlockHitResult)liquid).getBlockPos();
        if (world.getBlockState(blockpos1).is(Blocks.WATER) ||...
129
6
18
Пробовал через PlayerInteractEvent.RightClickBlock
В предмете должна быть функция обрабатывающая нажатие, а дальше тебе уже надо через ванильные методы проверять, на какой блок смотрит игрок.
 
129
6
18
А каким методом можно проверить на какой блок игрок смотрит?
Найди в сурсах майна гуишку с отладкой и там отыщи метод, через ктр парсится блок при наведении.

В крайнем случае, что то может быть в классе мира, но это не точно.
 
1,369
112
241
Глянь код пузырька, там всё наглядно (код для 1.16.5, но можешь переделать под 1.18.2 либо этот, либо взяв код с ваниллы):

GlassBottleItem:
         ItemStack itemstack = player.getItemInHand(hand);
         RayTraceResult raytraceresult = getPlayerPOVHitResult(world, player, RayTraceContext.FluidMode.SOURCE_ONLY);
         if (raytraceresult.getType() == RayTraceResult.Type.MISS) {
            return ActionResult.pass(itemstack);
         } else {
            if (raytraceresult.getType() == RayTraceResult.Type.BLOCK) {
               BlockPos blockpos = ((BlockRayTraceResult)raytraceresult).getBlockPos();
               if (!world.mayInteract(player, blockpos)) {
                  return ActionResult.pass(itemstack);
               }

               if (world.getFluidState(blockpos).is(FluidTags.WATER)) {
                  world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundCategory.NEUTRAL, 1.0F, 1.0F);
                  return ActionResult.sidedSuccess(this.turnBottleIntoItem(itemstack, player, PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)), world.isClientSide());
               }
            }
            return ActionResult.pass(itemstack);
         }
 
75
1
2
попробовал сделать как в f3 гуишке, но через ивент(не хочу специально для одного предмета отдельный класс делать), но теперь проблема такая, что предмет превращается сразу по 2, а не по 1. Попробовал дебажить - увидел, что код выполняется аж 4 раза подряд, 2 на сервере и 2 на клиенте. Как сделать так, чтоб осталась лишь серверная сторона выполнения?

Java:
if (player.getItemInHand(InteractionHand.MAIN_HAND).getItem() == ModItems.DRY_MORTAR.get())
    {
      HitResult liquid;
      liquid = player.pick(20.0D, 0.0F, true);
      if (liquid.getType() == HitResult.Type.BLOCK)
      {
        BlockPos blockpos1 = ((BlockHitResult)liquid).getBlockPos();
        if (world.getBlockState(blockpos1).is(Blocks.WATER) || world.getBlockState(blockPos).is(Blocks.WATER_CAULDRON))
        {
          world.playSound(null, blockPos, SoundEvents.GRAVEL_STEP, SoundSource.AMBIENT, 0.25F, 1);
          stack.setCount(stack.getCount()-1);
          ItemStack mortar = new ItemStack(ModItems.MORTAR.get(), 1);
          player.getInventory().add(mortar);
        }
      }
    }
 
345
25
94
предмет превращается сразу по 2, а не по 1
Проверки на сервер не хватает, не знаю как там это делается с нынешними маппингами, но попробуй поискать что-то по типу world#isRemote() world#isClient()
 
1,369
112
241
попробовал сделать как в f3 гуишке, но через ивент(не хочу специально для одного предмета отдельный класс делать), но теперь проблема такая, что предмет превращается сразу по 2, а не по 1. Попробовал дебажить - увидел, что код выполняется аж 4 раза подряд, 2 на сервере и 2 на клиенте. Как сделать так, чтоб осталась лишь серверная сторона выполнения?

Java:
if (player.getItemInHand(InteractionHand.MAIN_HAND).getItem() == ModItems.DRY_MORTAR.get())
    {
      HitResult liquid;
      liquid = player.pick(20.0D, 0.0F, true);
      if (liquid.getType() == HitResult.Type.BLOCK)
      {
        BlockPos blockpos1 = ((BlockHitResult)liquid).getBlockPos();
        if (world.getBlockState(blockpos1).is(Blocks.WATER) || world.getBlockState(blockPos).is(Blocks.WATER_CAULDRON))
        {
          world.playSound(null, blockPos, SoundEvents.GRAVEL_STEP, SoundSource.AMBIENT, 0.25F, 1);
          stack.setCount(stack.getCount()-1);
          ItemStack mortar = new ItemStack(ModItems.MORTAR.get(), 1);
          player.getInventory().add(mortar);
        }
      }
    }
Код выполняется 4 раза: левая рука - сервер, правая рука - сервер, левая рука - клиент, правая рука - сервер.
Просто введи проверку на основную руку и серверную часть майна, всё будет ок.
 
Последнее редактирование:

necauqua

когда-то был anti344
Администратор
1,216
27
172
не хочу специально для одного предмета отдельный класс делать
Логика гениальная, от бога, не могу просто.
Ивенты нужны для того чтобы отловить какое-то взаимодействие, где написанные тобою вещи (итемы, блоки, сущности и прочее) не участвуют, точка, они медленные (относительно того как если бы у тебя был свой класс, конечно, но вот так двести модов делают по ивент-хэндлеру вместо каждого класса и игра тормозит).

Буквально идут уровни, в каком порядке надо опускаться на дно, типа если не получается первое, обращаемся к следующему - свой код своих штук > ивенты > миксины > вообще свой трансформер (ну это уже Коцит конечно).

Если ты хочешь меньше классов просто для того чтобы было меньше классов (а ты хочешь) то, ммммм, не хоти?. Какой смысл делать меньше классов-то, лол
 
Сверху