Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,54 @@
package gregtech.api.items.metaitem.stats;

import gregtech.api.util.GTUtility;

import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
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.Fluid;
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.BlockWrapper;
import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper;

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

import java.util.List;

public class ItemFluidContainer implements IItemContainerItemProvider, IItemBehaviour {

public class ItemFluidContainer implements IItemContainerItemProvider {
private final boolean isBucket;

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 +57,175 @@ public ItemStack getContainerItem(ItemStack itemStack) {
}
return itemStack;
}

@Override
public void addInformation(ItemStack itemStack, List<String> lines) {
if (isBucket) {
lines.add(I18n.format("behaviour.cell_bucket.tooltip"));
}
}

@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
ItemStack stack = player.getHeldItem(hand);
if (!isBucket) return pass(stack);

ItemStack cellStack = GTUtility.copy(1, stack);

var cellHandler = FluidUtil.getFluidHandler(cellStack);
if (cellHandler == null) return pass(stack);

var result = rayTrace(world, player, true);
if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) {
return pass(stack);
}

var pos = result.getBlockPos();

// can the player modify the clicked block
if (!world.isBlockModifiable(player, pos)) {
return fail(stack);
}

// can player edit
if (!player.canPlayerEdit(pos, result.sideHit, cellStack)) {
return fail(stack);
}

// prioritize filling the cell if there's space, otherwise place fluid
if (fillCell(cellStack, world, pos, result.sideHit, player)) {
addToPlayerInventory(stack, cellHandler.getContainer(), player, hand);
return success(stack);

} else {
result = rayTrace(world, player, false);
if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) {
return pass(stack);
}
pos = result.getBlockPos();

if (tryPlace(cellHandler, world, pos.offset(result.sideHit), result.sideHit, player)) {
addToPlayerInventory(stack, cellHandler.getContainer(), player, hand);
return success(stack);
}
}

return pass(stack);
}

private static boolean tryPlace(IFluidHandlerItem cellHandler, World world, BlockPos pos, EnumFacing side,
EntityPlayer player) {
var cellFluid = cellHandler.drain(Fluid.BUCKET_VOLUME, false);
if (cellFluid == null || !cellFluid.getFluid().canBePlacedInWorld())
return false;

IFluidHandler blockHandler = getOrCreate(cellFluid, world, pos, side);

// check that we can place the fluid at the destination
IBlockState destBlockState = world.getBlockState(pos);
Material destMaterial = destBlockState.getMaterial();
boolean isDestNonSolid = !destMaterial.isSolid();
boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos);

if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable) {
// Non-air, solid, unreplacable block. We can't put fluid here.
return false;
}

// check vaporize
if (world.provider.doesWaterVaporize() && cellFluid.getFluid().doesVaporize(cellFluid)) {
cellHandler.drain(Fluid.BUCKET_VOLUME, true);
cellFluid.getFluid().vaporize(player, world, pos, cellFluid);
return true;
}

// fill block
int filled = blockHandler.fill(cellFluid, false);

if (filled != Fluid.BUCKET_VOLUME) return false;

playSound(cellFluid, true, player);
boolean consume = !player.isSpectator() && !player.isCreative();
blockHandler.fill(cellHandler.drain(Fluid.BUCKET_VOLUME, consume), true);
return true;
}

private static boolean fillCell(ItemStack cellStack, World world, BlockPos pos, EnumFacing side,
EntityPlayer player) {
IFluidHandler blockHandler = FluidUtil.getFluidHandler(world, pos, side);
if (blockHandler == null) return false;

IFluidHandlerItem cellHandler = FluidUtil.getFluidHandler(cellStack);
if (cellHandler == null) return false;

FluidStack stack = blockHandler.drain(Fluid.BUCKET_VOLUME, false);
int filled = cellHandler.fill(stack, false);

if (filled != Fluid.BUCKET_VOLUME) return false;

playSound(stack, false, player);
boolean consume = !player.isSpectator() && !player.isCreative();
cellHandler.fill(blockHandler.drain(Fluid.BUCKET_VOLUME, true), consume);
return true;
}

// copied and adapted from Item.java
@Nullable
private static RayTraceResult rayTrace(World worldIn, EntityPlayer player, boolean hitFluids) {
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),
hitFluids, !hitFluids, false);
}

@NotNull
private static IFluidHandler createHandler(FluidStack stack, World world, BlockPos pos) {
Block block = stack.getFluid().getBlock();
if (block instanceof IFluidBlock) {
return new FluidBlockWrapper((IFluidBlock) block, world, pos);
} else if (block instanceof BlockLiquid) {
return new BlockLiquidWrapper((BlockLiquid) block, world, pos);
} else {
return new BlockWrapper(block, world, pos);
}
}

private static IFluidHandler getOrCreate(FluidStack stack, World world, BlockPos pos, EnumFacing side) {
IFluidHandler handler = FluidUtil.getFluidHandler(world, pos, side);
if (handler != null) return handler;
return createHandler(stack, world, pos);
}

private static 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 static 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
1 change: 1 addition & 0 deletions src/main/resources/assets/gregtech/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -4748,6 +4748,7 @@ behaviour.softhammer=Activates and Deactivates Machines
behaviour.hammer=Turns on and off Muffling for Machines (by hitting them)
behaviour.wrench=Rotates Blocks on Rightclick
behaviour.boor.by=by %s
behaviour.cell_bucket.tooltip=Can pickup or place fluids
behaviour.paintspray.solvent.tooltip=Can remove color from things
behaviour.paintspray.white.tooltip=Can paint things in White
behaviour.paintspray.orange.tooltip=Can paint things in Orange
Expand Down