Jump to content

[1.16.5] onBlockActivated doesn't work


Dakuro

Recommended Posts

Hey guys !
I created a fluid and a fluidBlock and I had to associate it with the Water tag in order to have proper physics and it works fine.

I made exactly this

public static final ITag.INamedTag<Fluid> ASTRAAL = FluidTags.WATER;

I'm trying to make it so that, when you right-click it with a glass bottle, it gives you another item instead of the water bottle.

I'm using the onBlockActivated method even if it's deprecated because I read that it was okay to override it, but it seems that it doesn't work in the way it did it.

Here's my custom FluidBlock class :

public class ModFluidBlock extends FlowingFluidBlock {
    public ITag.INamedTag<Fluid> fluidTag;
    public ModFluidBlock(Supplier<? extends FlowingFluid> supplier, Properties properties, ITag.INamedTag<Fluid> fluidTag) {
        super(supplier, properties);
        this.fluidTag = fluidTag;
    }

    public BlockState state;
    public World worldIn;
    public BlockPos pos;
    public LivingEntity liventity;
    public PlayerEntity player;
    public Hand handIn;
    public BlockRayTraceResult hit;
    ItemStack waterBottle = PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER);

    @Override
    public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entity) {
        if(entity instanceof LivingEntity) {
            this.state = state;
            this.worldIn = worldIn;
            this.pos = pos;
            this.liventity = (LivingEntity) entity;

            if(liventity.areEyesInFluid(fluidTag)) {
                if(fluidTag == ModFluids.ASTRAAL){
                    liventity.addPotionEffect(new EffectInstance(Effects.CONDUIT_POWER, 10));
                }
            }

        }
        super.onEntityCollision(state, worldIn, pos, entity);
    }

    @Override
    public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
        this.state = state;
        this.worldIn = worldIn;
        this.pos = pos;
        this.player = player;
        this.handIn = handIn;
        this.hit = hit;

        String msg = TextFormatting.AQUA + "You clicked the water !";
        player.sendMessage(new StringTextComponent(msg), player.getUniqueID());
        if(player.getHeldItem(handIn).getItem() == Items.GLASS_BOTTLE){
            if(player.inventory.hasItemStack(waterBottle)){
                waterBottle.shrink(1);
                if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.CHAOS_SHARD.get()))){
                    player.dropItem(new ItemStack(ModItems.CHAOS_SHARD.get()), false);
                } else {
                    player.inventory.addItemStackToInventory(new ItemStack(ModItems.CHAOS_SHARD.get()));
                }
            }
            return ActionResultType.func_233537_a_(worldIn.isRemote);
        } else {
            return ActionResultType.PASS;
        }
    }

}

As you can see, I also overrided the onEntityCollision method, which works perfectly.

Link to comment
Share on other sites

Thank you for your answer !

I made an event as you recommanded but it works only when the player is in the fluid for some reason.

public class ModEvents {

    public ItemStack waterBottle = PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER);

    @SubscribeEvent
    public void onAstraalClick(PlayerInteractEvent.RightClickItem event) {
        if(event.getPlayer().getHeldItemMainhand().getItem() == Items.GLASS_BOTTLE) {
            if(event.getWorld().getFluidState(event.getPos()).getFluid() == ModFluids.ASTRAAL_FLUID.get()){
                if(!event.getPlayer().world.isRemote()){
                    String msg = TextFormatting.AQUA + "You clicked the Astraal water !";
                    event.getPlayer().sendMessage(new StringTextComponent(msg), event.getPlayer().getUniqueID());
                }
                if(event.getPlayer().inventory.hasItemStack(waterBottle)){
                    waterBottle.shrink(1);
                    event.getPlayer().inventory.addItemStackToInventory(new ItemStack(ModItems.CHAOS_SHARD.get()));
                }
            }
        }
    }

}

 

Also, the first water bottle isn't replaced, it works only when there is already a water bottle in the player inventory before right-clicking, something is definitely wrong with my if statement (I'm pretty sure the first water bottle isn't already in the inventory when the event is executed) but I don't know what I can do. Is it possible to make the event wait until the water bottle is generated ?

 

I also made some research about event cancelation in order to prevent Minecraft from giving a water bottle (which would be a lot more simplier) but I can't figure out how to use it for this case.

Link to comment
Share on other sites

On 2/16/2021 at 11:50 PM, diesieben07 said:

Your detection of the fluid is wrong, look at GlassBottleItem.

You need to cancel the event if you detect that your fluid was clicked and then add your item. Not try to detect the water bottle that was added (which would not work anyways, because it happens after the event).

 

Thanks to you, it now works !

 

Here's the code if someone wants to do the same thing :

 

public class ModEvents {

    @SubscribeEvent
    public void onAstraalClick(PlayerInteractEvent.RightClickItem event) {
        if(event.getPlayer().getHeldItemMainhand().getItem() == Items.GLASS_BOTTLE) {

            RayTraceResult raytraceresult = rayTrace(event.getWorld(), event.getPlayer(), RayTraceContext.FluidMode.SOURCE_ONLY);

            if (raytraceresult.getType() == RayTraceResult.Type.BLOCK) {
                BlockPos blockpos = ((BlockRayTraceResult)raytraceresult).getPos();
                if (event.getWorld().getFluidState(blockpos).getFluid() == ModFluids.ASTRAAL_FLUID.get()) {
                    event.setCanceled(true);
                }
            }
        }
    }

    public static BlockRayTraceResult rayTrace(World worldIn, PlayerEntity player, RayTraceContext.FluidMode fluidMode){
        float f = player.rotationPitch;
        float f1 = player.rotationYaw;
        Vector3d vector3d = player.getEyePosition(1.0F);
        float f2 = MathHelper.cos(-f1 * ((float)Math.PI / 180F) - (float)Math.PI);
        float f3 = MathHelper.sin(-f1 * ((float)Math.PI / 180F) - (float)Math.PI);
        float f4 = -MathHelper.cos(-f * ((float)Math.PI / 180F));
        float f5 = MathHelper.sin(-f * ((float)Math.PI / 180F));
        float f6 = f3 * f4;
        float f7 = f2 * f4;
        double d0 = player.getAttribute(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get()).getValue();;
        Vector3d vector3d1 = vector3d.add((double)f6 * d0, (double)f5 * d0, (double)f7 * d0);
        return worldIn.rayTraceBlocks(new RayTraceContext(vector3d, vector3d1, RayTraceContext.BlockMode.OUTLINE, fluidMode, player));
    }
    
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
    • Update your drivers: https://www.amd.com/en/support/graphics/amd-radeon-r9-series/amd-radeon-r9-200-series/amd-radeon-r9-280x
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.