Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.5] onBlockActivated doesn't work


Dakuro
 Share

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

14 minutes ago, Dakuro said:

waterBottle.shrink(1);

You can't do this. The waterBottle variable is shared across the whole game, there is only one instance of your ModEvents class.

 

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).

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.

Guest
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.

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • Hello. When i tried making another server but for another version i cant seem to find a mods folder. and making one doesn't help.
    • public abstract class NitroglycerinFluid extends ForgeFlowingFluid { // Directly reference a log4j logger. private static final Logger LOGGER = LogManager.getLogger(); protected NitroglycerinFluid(Properties properties) { super(properties); } public static Properties createProperties() { return new Properties(() -> ModFluids.NITROGLYCERIN, () -> ModFluids.FLOWING_NITROGLYCERIN, FluidAttributes.builder(new ResourceLocation("sussybakaplus:block/nitroglycerin_still"), new ResourceLocation("sussybakaplus:block/nitroglycerin_flow")).overlay(new ResourceLocation("sussybakaplus:block/nitroglycerin_overlay")).density(3000).viscosity(1000).luminosity(15).temperature(1300)).tickRate(1).canMultiply().bucket(() -> ModItems.NITROGLYCERIN_BUCKET).block(() -> ModBlocks.NITROGLYCERIN); } @Override public boolean isSource(FluidState state) { return false; } @Override public int getAmount(FluidState state) { return state.getValue(LEVEL); } public void animateTick(Level p_76445_, BlockPos p_76446_, FluidState p_76447_, Random p_76448_) { LOGGER.info("animate"); if (!p_76447_.isSource() && !p_76447_.getValue(FALLING)) { if (p_76448_.nextInt(64) == 0) { p_76445_.playLocalSound((double)p_76446_.getX() + 0.5D, (double)p_76446_.getY() + 0.5D, (double)p_76446_.getZ() + 0.5D, SoundEvents.WATER_AMBIENT, SoundSource.BLOCKS, p_76448_.nextFloat() * 0.25F + 0.75F, p_76448_.nextFloat() + 0.5F, false); } } else if (p_76448_.nextInt(10) == 0) { p_76445_.addParticle(ParticleTypes.UNDERWATER, (double)p_76446_.getX() + p_76448_.nextDouble(), (double)p_76446_.getY() + p_76448_.nextDouble(), (double)p_76446_.getZ() + p_76448_.nextDouble(), 0.0D, 0.0D, 0.0D); } } @Nullable public ParticleOptions getDripParticle() { return ParticleTypes.DRIPPING_WATER; } @Override protected void beforeDestroyingBlock(LevelAccessor accessor, BlockPos pos, BlockState state) { BlockEntity blockentity = state.hasBlockEntity() ? accessor.getBlockEntity(pos) : null; LOGGER.info("spread to " + state.getBlock().getRegistryName().toString()); if (state.getBlock().getRegistryName().getPath().equals("fire")) { float f = 4.0F; Minecraft.getInstance().level.explode(null, pos.getX(), pos.getY(), pos.getZ(), f, Explosion.BlockInteraction.BREAK); } //Block.dropResources(state, accessor, pos, blockentity); } @Override public void tick(Level level, BlockPos pos, FluidState state) { //super.tick(level, pos, state); LOGGER.info("tick"); if (this.hasBurningNeighbors(level, pos)) { LOGGER.info("EXPLODING!!!"); float f = 4.0F; level.explode(null, pos.getX(), pos.getY(), pos.getZ(), f, Explosion.BlockInteraction.BREAK); } else { LOGGER.info(pos.toShortString() + " doesn't have any buring neighbors"); } } private boolean hasBurningNeighbors(LevelReader levelReader, BlockPos pos) { for(Direction direction : Direction.values()) { if (this.isBurning(levelReader, pos.relative(direction))) { return true; } } return false; } private boolean isBurning(LevelReader levelReader, BlockPos pos) { return (pos.getY() < levelReader.getMinBuildHeight() || pos.getY() >= levelReader.getMaxBuildHeight() || levelReader.hasChunkAt(pos)) && levelReader.getBlockState(pos).isBurning(levelReader, pos); } protected float getExplosionResistance() { return 0.0F; } public int getTickDelay(LevelReader p_76226_) { return p_76226_.dimensionType().ultraWarm() ? 1 : 1; } protected boolean isRandomlyTicking() { return true; } public Optional<SoundEvent> getPickupSound() { return Optional.of(SoundEvents.BUCKET_FILL); } } My Fluid Class
    • So how do I get the container? It doesn't need to be a event btw.
    • It says it in the log. It's 16. You need to use Java 8 instead of Java 16 for versions before 1.17.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.