Skip to content

Commit 7115b6c

Browse files
committed
rework behavior to properly mimic bucket behavior
1 parent a78fbfc commit 7115b6c

File tree

1 file changed

+124
-32
lines changed

1 file changed

+124
-32
lines changed

src/main/java/gregtech/api/items/metaitem/stats/ItemFluidContainer.java

Lines changed: 124 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
package gregtech.api.items.metaitem.stats;
22

3-
import gregtech.api.util.GTTransferUtils;
43
import gregtech.api.util.GTUtility;
54

5+
import net.minecraft.block.Block;
66
import net.minecraft.block.BlockLiquid;
7+
import net.minecraft.block.material.Material;
8+
import net.minecraft.block.state.IBlockState;
79
import net.minecraft.entity.item.EntityItem;
810
import net.minecraft.entity.player.EntityPlayer;
911
import net.minecraft.item.ItemStack;
1012
import net.minecraft.util.ActionResult;
13+
import net.minecraft.util.EnumFacing;
1114
import net.minecraft.util.EnumHand;
1215
import net.minecraft.util.SoundCategory;
1316
import net.minecraft.util.SoundEvent;
1417
import net.minecraft.util.math.BlockPos;
1518
import net.minecraft.util.math.RayTraceResult;
1619
import net.minecraft.util.math.Vec3d;
1720
import net.minecraft.world.World;
21+
import net.minecraftforge.fluids.Fluid;
1822
import net.minecraftforge.fluids.FluidStack;
1923
import net.minecraftforge.fluids.FluidUtil;
2024
import net.minecraftforge.fluids.IFluidBlock;
2125
import net.minecraftforge.fluids.capability.IFluidHandler;
2226
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
2327
import net.minecraftforge.fluids.capability.wrappers.BlockLiquidWrapper;
28+
import net.minecraftforge.fluids.capability.wrappers.BlockWrapper;
2429
import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper;
2530

2631
import org.jetbrains.annotations.NotNull;
@@ -55,68 +60,155 @@ public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player
5560
ItemStack stack = player.getHeldItem(hand);
5661
if (!isBucket) return pass(stack);
5762

58-
var result = rayTrace(world, player);
59-
if (result == null) return pass(stack);
60-
var pos = result.getBlockPos();
61-
var facing = result.sideHit;
62-
63+
// can the player modify the clicked block
6364
ItemStack cellStack = GTUtility.copy(1, stack);
65+
6466
var cellHandler = FluidUtil.getFluidHandler(cellStack);
6567
if (cellHandler == null) return pass(stack);
6668

67-
var cellFluid = cellHandler.drain(Integer.MAX_VALUE, false);
68-
var blockHandler = FluidUtil.getFluidHandler(world, result.getBlockPos(), result.sideHit);
69-
FluidStack soundFluid = cellFluid;
70-
boolean success, isFill;
69+
var cellFluid = cellHandler.drain(Fluid.BUCKET_VOLUME, false);
70+
71+
var result = rayTrace(world, player, false);
72+
if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) {
73+
return pass(stack);
74+
}
7175

72-
if (blockHandler == null) {
73-
if (cellFluid == null || !cellFluid.getFluid().canBePlacedInWorld())
76+
var blockHandler = FluidUtil.getFluidHandler(world, result.getBlockPos().offset(result.sideHit),
77+
result.sideHit);
78+
int freeSpace = cellHandler.getTankProperties()[0].getCapacity() - (cellFluid == null ? 0 : cellFluid.amount);
79+
boolean pickup = blockHandler != null && blockHandler.drain(Fluid.BUCKET_VOLUME, false) != null &&
80+
freeSpace > 0;
81+
if (pickup) {
82+
result = rayTrace(world, player, true);
83+
if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) {
7484
return pass(stack);
85+
}
86+
}
87+
88+
var pos = result.getBlockPos();
7589

76-
blockHandler = createHandler(cellFluid, world, pos.offset(facing));
77-
success = GTTransferUtils.transferFluids(cellHandler, blockHandler) > 0;
78-
isFill = true;
90+
if (!world.isBlockModifiable(player, pos)) {
91+
return fail(stack);
92+
}
93+
94+
// can player edit
95+
if (!player.canPlayerEdit(pos, result.sideHit, cellStack)) {
96+
return fail(stack);
97+
}
98+
99+
FluidStack soundFluid;
100+
if (blockHandler != null && cellFluid == null) {
101+
soundFluid = blockHandler.drain(Fluid.BUCKET_VOLUME, false);
102+
if (soundFluid == null) return pass(stack);
103+
soundFluid = soundFluid.copy();
104+
} else if (cellFluid != null) {
105+
soundFluid = cellFluid.copy();
79106
} else {
80-
soundFluid = blockHandler.drain(Integer.MAX_VALUE, false);
81-
success = GTTransferUtils.transferFluids(blockHandler, cellHandler) > 0;
82-
isFill = false;
107+
return pass(stack);
83108
}
84109

85-
if (success) {
86-
playSound(soundFluid, isFill, player);
110+
// the defualt assumption is placing fluid, then picking up fluid
111+
if (!pickup && tryPlace(cellHandler, world, pos.offset(result.sideHit), result.sideHit, player)) {
112+
playSound(soundFluid, true, player);
113+
addToPlayerInventory(stack, cellHandler.getContainer(), player, hand);
114+
return success(stack);
115+
116+
} else if (fillCell(cellStack, world, pos, result.sideHit, player)) {
117+
playSound(soundFluid, false, player);
87118
addToPlayerInventory(stack, cellHandler.getContainer(), player, hand);
88119
return success(stack);
89120
}
90121

91122
return pass(stack);
92123
}
93124

125+
private static boolean tryPlace(IFluidHandlerItem cellHandler, World world, BlockPos pos, EnumFacing side,
126+
EntityPlayer player) {
127+
var cellFluid = cellHandler.drain(Fluid.BUCKET_VOLUME, false);
128+
if (cellFluid == null || !cellFluid.getFluid().canBePlacedInWorld())
129+
return false;
130+
131+
IFluidHandler blockHandler = getOrCreate(cellFluid, world, pos, side);
132+
133+
// check that we can place the fluid at the destination
134+
IBlockState destBlockState = world.getBlockState(pos);
135+
Material destMaterial = destBlockState.getMaterial();
136+
boolean isDestNonSolid = !destMaterial.isSolid();
137+
boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos);
138+
139+
if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable) {
140+
// Non-air, solid, unreplacable block. We can't put fluid here.
141+
return false;
142+
}
143+
144+
// check vaporize
145+
if (world.provider.doesWaterVaporize() && cellFluid.getFluid().doesVaporize(cellFluid)) {
146+
cellHandler.drain(Fluid.BUCKET_VOLUME, true);
147+
cellFluid.getFluid().vaporize(player, world, pos, cellFluid);
148+
return true;
149+
}
150+
151+
// fill block
152+
int filled = blockHandler.fill(cellFluid, false);
153+
154+
if (filled != Fluid.BUCKET_VOLUME) return false;
155+
156+
boolean consume = !player.isSpectator() && !player.isCreative();
157+
blockHandler.fill(cellHandler.drain(Fluid.BUCKET_VOLUME, consume), true);
158+
return true;
159+
}
160+
161+
private static boolean fillCell(ItemStack cellStack, World world, BlockPos pos, EnumFacing side,
162+
EntityPlayer player) {
163+
IFluidHandler blockHandler = FluidUtil.getFluidHandler(world, pos, side);
164+
if (blockHandler == null) return false;
165+
166+
IFluidHandlerItem cellHandler = FluidUtil.getFluidHandler(cellStack);
167+
if (cellHandler == null) return false;
168+
169+
FluidStack stack = blockHandler.drain(Fluid.BUCKET_VOLUME, false);
170+
int filled = cellHandler.fill(stack, false);
171+
172+
if (filled != Fluid.BUCKET_VOLUME) return false;
173+
174+
boolean consume = !player.isSpectator() && !player.isCreative();
175+
cellHandler.fill(blockHandler.drain(Fluid.BUCKET_VOLUME, true), consume);
176+
return true;
177+
}
178+
94179
// copied and adapted from Item.java
95180
@Nullable
96-
private static RayTraceResult rayTrace(World worldIn, EntityPlayer player) {
181+
private static RayTraceResult rayTrace(World worldIn, EntityPlayer player, boolean hitFluids) {
97182
Vec3d lookPos = player.getPositionVector()
98183
.add(0, player.getEyeHeight(), 0);
99184

100185
Vec3d lookOffset = player.getLookVec()
101186
.scale(player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue());
102187

103188
return worldIn.rayTraceBlocks(lookPos, lookPos.add(lookOffset),
104-
true, false, false);
189+
hitFluids, !hitFluids, false);
105190
}
106191

107192
@NotNull
108-
private IFluidHandler createHandler(FluidStack stack, World world, BlockPos pos) {
109-
var block = stack.getFluid().getBlock();
110-
if (block instanceof IFluidBlock fluidBlock) {
111-
return new FluidBlockWrapper(fluidBlock, world, pos);
112-
} else if (block instanceof BlockLiquid blockLiquid) {
113-
return new BlockLiquidWrapper(blockLiquid, world, pos);
193+
private static IFluidHandler createHandler(FluidStack stack, World world, BlockPos pos) {
194+
Block block = stack.getFluid().getBlock();
195+
if (block instanceof IFluidBlock) {
196+
return new FluidBlockWrapper((IFluidBlock) block, world, pos);
197+
} else if (block instanceof BlockLiquid) {
198+
return new BlockLiquidWrapper((BlockLiquid) block, world, pos);
199+
} else {
200+
return new BlockWrapper(block, world, pos);
114201
}
115-
throw new IllegalArgumentException("Block must be a liquid!");
116202
}
117203

118-
private void addToPlayerInventory(ItemStack playerStack, ItemStack resultStack, EntityPlayer player,
119-
EnumHand hand) {
204+
private static IFluidHandler getOrCreate(FluidStack stack, World world, BlockPos pos, EnumFacing side) {
205+
IFluidHandler handler = FluidUtil.getFluidHandler(world, pos, side);
206+
if (handler != null) return handler;
207+
return createHandler(stack, world, pos);
208+
}
209+
210+
private static void addToPlayerInventory(ItemStack playerStack, ItemStack resultStack, EntityPlayer player,
211+
EnumHand hand) {
120212
if (playerStack.getCount() > resultStack.getCount()) {
121213
playerStack.shrink(resultStack.getCount());
122214
if (!player.inventory.addItemStackToInventory(resultStack) && !player.world.isRemote) {
@@ -132,7 +224,7 @@ private void addToPlayerInventory(ItemStack playerStack, ItemStack resultStack,
132224
* Play the appropriate fluid interaction sound for the fluid. <br />
133225
* Must be called on server to work correctly
134226
**/
135-
private void playSound(FluidStack fluid, boolean fill, EntityPlayer player) {
227+
private static void playSound(FluidStack fluid, boolean fill, EntityPlayer player) {
136228
if (fluid == null || player.world.isRemote) return;
137229
SoundEvent soundEvent;
138230
if (fill) {

0 commit comments

Comments
 (0)