diff --git a/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/AccessibleMetaValueItem.java b/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/AccessibleMetaValueItem.java new file mode 100644 index 0000000..21f8670 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/AccessibleMetaValueItem.java @@ -0,0 +1,6 @@ +package com.nomiceu.nomilabs.gregtech.mixinhelper; + +public interface AccessibleMetaValueItem { + + void labs$clearStats(); +} diff --git a/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/BucketItemFluidContainer.java b/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/BucketItemFluidContainer.java new file mode 100644 index 0000000..5f71110 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/gregtech/mixinhelper/BucketItemFluidContainer.java @@ -0,0 +1,132 @@ +package com.nomiceu.nomilabs.gregtech.mixinhelper; + +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.*; +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.FluidUtil; +import net.minecraftforge.fluids.IFluidBlock; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.wrappers.BlockLiquidWrapper; +import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.items.metaitem.stats.ItemFluidContainer; +import gregtech.api.util.GTTransferUtils; +import gregtech.api.util.GTUtility; + +/** + * Implements GTCEu #2660. + */ +public class BucketItemFluidContainer extends ItemFluidContainer implements IItemBehaviour { + + @Override + public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, + EnumFacing facing, float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + + 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; + } 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.
+ * 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); + } + + /* Util */ + private ActionResult pass(ItemStack stack) { + return ActionResult.newResult(EnumActionResult.PASS, stack); + } + + private ActionResult success(ItemStack stack) { + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + } +} diff --git a/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaItem1Mixin.java b/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaItem1Mixin.java new file mode 100644 index 0000000..b895746 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaItem1Mixin.java @@ -0,0 +1,54 @@ +package com.nomiceu.nomilabs.mixin.gregtech; + +import static gregtech.common.items.MetaItems.*; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.nomiceu.nomilabs.gregtech.mixinhelper.AccessibleMetaValueItem; +import com.nomiceu.nomilabs.gregtech.mixinhelper.BucketItemFluidContainer; + +import gregtech.api.items.metaitem.FilteredFluidStats; +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.unification.material.Materials; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.common.items.MetaItem1; + +/** + * Implements GTCEu #2660. + *

+ * Also doubles the steel cell's capacity + */ +@Mixin(value = MetaItem1.class, remap = false) +public class MetaItem1Mixin { + + @Inject(method = "registerSubItems", at = @At("RETURN")) + private void changeCellBehaviour(CallbackInfo ci) { + labs$editCell(FLUID_CELL); + labs$editCell(FLUID_CELL_UNIVERSAL); + + // Steel: Buff Capacity to 16000. + ((AccessibleMetaValueItem) FLUID_CELL_LARGE_STEEL).labs$clearStats(); + FLUID_CELL_LARGE_STEEL.addComponents( + new FilteredFluidStats(16000, + Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, + false, false, true), + new BucketItemFluidContainer()); + + labs$editCell(FLUID_CELL_LARGE_ALUMINIUM); + labs$editCell(FLUID_CELL_LARGE_STAINLESS_STEEL); + labs$editCell(FLUID_CELL_LARGE_TITANIUM); + labs$editCell(FLUID_CELL_LARGE_TUNGSTEN_STEEL); + } + + @Unique + private void labs$editCell(MetaItem.MetaValueItem cell) { + var filtered = cell.getAllStats().get(0); + + ((AccessibleMetaValueItem) cell).labs$clearStats(); + cell.addComponents(filtered, new BucketItemFluidContainer()); + } +} diff --git a/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaValueItemMixin.java b/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaValueItemMixin.java new file mode 100644 index 0000000..1acdabe --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/mixin/gregtech/MetaValueItemMixin.java @@ -0,0 +1,28 @@ +package com.nomiceu.nomilabs.mixin.gregtech; + +import java.util.List; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import com.nomiceu.nomilabs.gregtech.mixinhelper.AccessibleMetaValueItem; + +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.stats.IItemComponent; + +/** + * Allows Implementation of GTCEu #2660. + */ +@Mixin(value = MetaItem.MetaValueItem.class, remap = false) +public class MetaValueItemMixin implements AccessibleMetaValueItem { + + @Shadow + @Final + private List allStats; + + @Override + public void labs$clearStats() { + allStats.clear(); + } +} diff --git a/src/main/resources/mixins.nomilabs.gregtech.json b/src/main/resources/mixins.nomilabs.gregtech.json index 1e429a1..f190d8a 100644 --- a/src/main/resources/mixins.nomilabs.gregtech.json +++ b/src/main/resources/mixins.nomilabs.gregtech.json @@ -19,10 +19,12 @@ "MaterialMixin", "MaterialRecipeHandlerMixin", "MaterialStackMixin", + "MetaItem1Mixin", "MetaItemsMixin", "MetaTileEntityMEStockingBusMixin", "MetaTileEntityMEStockingHatchMixin", "MetaTileEntityProcessingArrayMixin", + "MetaValueItemMixin", "MultiblockDisplayTextBuilderMixin", "MultiblockInfoCategoryMixin", "MultiblockRecipeLogicMixin",