11package gregtech .api .items .metaitem .stats ;
22
3- import gregtech .api .util .GTTransferUtils ;
43import gregtech .api .util .GTUtility ;
54
5+ import net .minecraft .block .Block ;
66import net .minecraft .block .BlockLiquid ;
7+ import net .minecraft .block .material .Material ;
8+ import net .minecraft .block .state .IBlockState ;
79import net .minecraft .entity .item .EntityItem ;
810import net .minecraft .entity .player .EntityPlayer ;
911import net .minecraft .item .ItemStack ;
1012import net .minecraft .util .ActionResult ;
13+ import net .minecraft .util .EnumFacing ;
1114import net .minecraft .util .EnumHand ;
1215import net .minecraft .util .SoundCategory ;
1316import net .minecraft .util .SoundEvent ;
1417import net .minecraft .util .math .BlockPos ;
1518import net .minecraft .util .math .RayTraceResult ;
1619import net .minecraft .util .math .Vec3d ;
1720import net .minecraft .world .World ;
21+ import net .minecraftforge .fluids .Fluid ;
1822import net .minecraftforge .fluids .FluidStack ;
1923import net .minecraftforge .fluids .FluidUtil ;
2024import net .minecraftforge .fluids .IFluidBlock ;
2125import net .minecraftforge .fluids .capability .IFluidHandler ;
2226import net .minecraftforge .fluids .capability .IFluidHandlerItem ;
2327import net .minecraftforge .fluids .capability .wrappers .BlockLiquidWrapper ;
28+ import net .minecraftforge .fluids .capability .wrappers .BlockWrapper ;
2429import net .minecraftforge .fluids .capability .wrappers .FluidBlockWrapper ;
2530
2631import 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