Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Bucket Behavior to Cells #2660

Merged
merged 11 commits into from
Feb 3, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ default EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockP

default ActionResult<ItemStack> onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand,
EnumFacing facing, float hitX, float hitY, float hitZ) {
return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand));
return pass(player.getHeldItem(hand));
}

default void addInformation(ItemStack itemStack, List<String> lines) {}
Expand All @@ -50,8 +50,20 @@ default Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmen
}

default ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand));
return pass(player.getHeldItem(hand));
}

default void addPropertyOverride(@NotNull Item item) {}

default ActionResult<ItemStack> pass(ItemStack stack) {
return ActionResult.newResult(EnumActionResult.PASS, stack);
}

default ActionResult<ItemStack> success(ItemStack stack) {
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
}

default ActionResult<ItemStack> fail(ItemStack stack) {
return ActionResult.newResult(EnumActionResult.FAIL, stack);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,47 @@
package gregtech.api.items.metaitem.stats;

import gregtech.api.util.GTTransferUtils;
import gregtech.api.util.GTUtility;

import net.minecraft.block.BlockLiquid;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.wrappers.BlockLiquidWrapper;
import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ItemFluidContainer implements IItemContainerItemProvider, IItemBehaviour {

private final boolean isBucket;

public class ItemFluidContainer implements IItemContainerItemProvider {
public ItemFluidContainer(boolean isBucket) {
this.isBucket = isBucket;
}

public ItemFluidContainer() {
this(false);
}

@Override
public ItemStack getContainerItem(ItemStack itemStack) {
IFluidHandlerItem handler = itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null);
IFluidHandlerItem handler = FluidUtil.getFluidHandler(itemStack);
if (handler != null) {
FluidStack drained = handler.drain(1000, false);
if (drained == null || drained.amount != 1000) return ItemStack.EMPTY;
Expand All @@ -18,4 +50,97 @@ public ItemStack getContainerItem(ItemStack itemStack) {
}
return itemStack;
}

@Override
public ActionResult<ItemStack> onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand,
EnumFacing facing, float hitX, float hitY, float hitZ) {
ItemStack stack = player.getHeldItem(hand);
if (!isBucket) return pass(stack);

var result = rayTrace(world, player);
if (result == null) return pass(stack);

ItemStack cellStack = GTUtility.copy(1, stack);
var cellHandler = FluidUtil.getFluidHandler(cellStack);
if (cellHandler == null) return pass(stack);

var cellFluid = cellHandler.drain(Integer.MAX_VALUE, false);
var blockHandler = FluidUtil.getFluidHandler(world, result.getBlockPos(), result.sideHit);
FluidStack soundFluid = cellFluid;
boolean success, isFill;

if (blockHandler == null) {
if (cellFluid == null || !cellFluid.getFluid().canBePlacedInWorld())
return pass(stack);

blockHandler = createHandler(cellFluid, world, pos.offset(facing));
success = GTTransferUtils.transferFluids(cellHandler, blockHandler) > 0;
isFill = true;
ghzdude marked this conversation as resolved.
Show resolved Hide resolved
} else {
soundFluid = blockHandler.drain(Integer.MAX_VALUE, false);
success = GTTransferUtils.transferFluids(blockHandler, cellHandler) > 0;
isFill = false;
}

if (success) {
playSound(soundFluid, isFill, player);
addToPlayerInventory(stack, cellHandler.getContainer(), player, hand);
return success(stack);
}

return pass(stack);
}

// copied and adapted from Item.java
@Nullable
private static RayTraceResult rayTrace(World worldIn, EntityPlayer player) {
Vec3d lookPos = player.getPositionVector()
.add(0, player.getEyeHeight(), 0);

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

return worldIn.rayTraceBlocks(lookPos, lookPos.add(lookOffset),
true, false, false);
}

@NotNull
private IFluidHandler createHandler(FluidStack stack, World world, BlockPos pos) {
var block = stack.getFluid().getBlock();
if (block instanceof IFluidBlock fluidBlock) {
return new FluidBlockWrapper(fluidBlock, world, pos);
} else if (block instanceof BlockLiquid blockLiquid) {
return new BlockLiquidWrapper(blockLiquid, world, pos);
}
throw new IllegalArgumentException("Block must be a liquid!");
}

private void addToPlayerInventory(ItemStack playerStack, ItemStack resultStack, EntityPlayer player,
EnumHand hand) {
if (playerStack.getCount() > resultStack.getCount()) {
playerStack.shrink(resultStack.getCount());
if (!player.inventory.addItemStackToInventory(resultStack) && !player.world.isRemote) {
EntityItem dropItem = player.entityDropItem(resultStack, 0);
if (dropItem != null) dropItem.setPickupDelay(0);
}
} else {
player.setHeldItem(hand, resultStack);
}
}

/**
* Play the appropriate fluid interaction sound for the fluid. <br />
* Must be called on server to work correctly
**/
private void playSound(FluidStack fluid, boolean fill, EntityPlayer player) {
if (fluid == null || player.world.isRemote) return;
SoundEvent soundEvent;
if (fill) {
soundEvent = fluid.getFluid().getFillSound(fluid);
} else {
soundEvent = fluid.getFluid().getEmptySound(fluid);
}
player.world.playSound(null, player.posX, player.posY + 0.5, player.posZ,
soundEvent, SoundCategory.PLAYERS, 1.0F, 1.0F);
}
}
19 changes: 12 additions & 7 deletions src/main/java/gregtech/common/items/MetaItem1.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,46 +191,51 @@ public void registerSubItems() {
// Fluid Cells: ID 78-88
FLUID_CELL = addItem(78, "fluid_cell")
.addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, false),
new ItemFluidContainer())
new ItemFluidContainer(true))
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_UNIVERSAL = addItem(79, "fluid_cell.universal")
.addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, true),
new ItemFluidContainer())
new ItemFluidContainer(true))
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_LARGE_STEEL = addItem(80, "large_fluid_cell.steel")
.addComponents(new FilteredFluidStats(8000,
Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false,
false, false, true), new ItemFluidContainer())
false, false, true),
new ItemFluidContainer(true))
.setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Steel, M * 4))) // ingot * 4
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_LARGE_ALUMINIUM = addItem(81, "large_fluid_cell.aluminium")
.addComponents(new FilteredFluidStats(32000,
Materials.Aluminium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false,
false, false, true), new ItemFluidContainer())
false, false, true),
new ItemFluidContainer(true))
.setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Aluminium, M * 4))) // ingot * 4
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_LARGE_STAINLESS_STEEL = addItem(82, "large_fluid_cell.stainless_steel")
.addComponents(new FilteredFluidStats(64000,
Materials.StainlessSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true,
true, true, false, true), new ItemFluidContainer())
true, true, false, true),
new ItemFluidContainer(true))
.setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.StainlessSteel, M * 6))) // ingot * 6
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_LARGE_TITANIUM = addItem(83, "large_fluid_cell.titanium")
.addComponents(new FilteredFluidStats(128000,
Materials.Titanium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true,
false, false, true), new ItemFluidContainer())
false, false, true),
new ItemFluidContainer(true))
.setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Titanium, M * 6))) // ingot * 6
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

FLUID_CELL_LARGE_TUNGSTEN_STEEL = addItem(84, "large_fluid_cell.tungstensteel")
.addComponents(new FilteredFluidStats(512000,
Materials.TungstenSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true,
true, false, false, true), new ItemFluidContainer())
true, false, false, true),
new ItemFluidContainer(true))
.setMaxStackSize(32)
.setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 8))) // ingot * 8
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
Expand Down