Posted February 16, 20214 yr 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.
February 16, 20214 yr Author 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.
February 16, 20214 yr Author Okay thanks again for your guidance. I'll come back when I have done my best to apply your advices ^^
February 18, 20214 yr Author 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)); } }
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.