Skip to content

Commit

Permalink
First implementation of the Fluid Voiding cover
Browse files Browse the repository at this point in the history
  • Loading branch information
ALongStringOfNumbers committed Mar 14, 2021
1 parent 618fc29 commit 9306afe
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ public class GregtechCapabilities {
@CapabilityInject(IFuelable.class)
public static Capability<IFuelable> CAPABILITY_FUELABLE = null;

@CapabilityInject(IFluidVoiding.class)
public static Capability<IFluidVoiding> CAPABILITY_FLUID_VOIDING = null;

}
12 changes: 12 additions & 0 deletions src/main/java/gregtech/api/capability/IFluidVoiding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gregtech.api.capability;

import net.minecraftforge.fluids.FluidStack;

import java.util.function.Predicate;

public interface IFluidVoiding {

int voidingAmount();

Predicate<FluidStack> checkInputFluid();
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static void init() {
registerCapabilityWithNoDefault(ICoverable.class);
registerCapabilityWithNoDefault(IControllable.class);
registerCapabilityWithNoDefault(IFuelable.class);
registerCapabilityWithNoDefault(IFluidVoiding.class);

registerCapabilityWithNoDefault(IWrenchItem.class);
registerCapabilityWithNoDefault(IScrewdriverItem.class);
Expand Down
34 changes: 28 additions & 6 deletions src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import codechicken.lib.vec.Matrix4;
import com.google.common.base.Preconditions;
import gregtech.api.GregTechAPI;
import gregtech.api.capability.GregtechCapabilities;
import gregtech.api.capability.GregtechTileCapabilities;
import gregtech.api.capability.IEnergyContainer;
import gregtech.api.capability.IFluidVoiding;
import gregtech.api.capability.impl.FluidHandlerProxy;
import gregtech.api.capability.impl.FluidTankList;
import gregtech.api.capability.impl.ItemHandlerProxy;
Expand Down Expand Up @@ -55,6 +57,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

import static gregtech.api.util.InventoryUtils.simulateItemStackMerge;

Expand Down Expand Up @@ -843,16 +846,35 @@ public void pushFluidsIntoNearbyHandlers(EnumFacing... allowedFaces) {
for (EnumFacing nearbyFacing : allowedFaces) {
blockPos.setPos(getPos()).move(nearbyFacing);
TileEntity tileEntity = getWorld().getTileEntity(blockPos);
if (tileEntity == null) {
//Get the fluid voiding capability
IFluidVoiding fluidVoiding = getCoverCapability(GregtechCapabilities.CAPABILITY_FLUID_VOIDING, nearbyFacing);
//Allow the fluid voiding cover to take fluids, but not be a tile entity
if (tileEntity == null && fluidVoiding == null) {
continue;
}
IFluidHandler fluidHandler = tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing.getOpposite());
//Get the capability of the source machine
IFluidHandler machineFluidHandler = getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);

//Get the capability of the destination TE
IFluidHandler destinationTE = null;
if(tileEntity != null) {
destinationTE = tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing.getOpposite());
}

//use getCoverCapability so fluid tank index filtering and fluid filtering covers will work properly
IFluidHandler myFluidHandler = getCoverCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);
if (fluidHandler == null || myFluidHandler == null) {
IFluidHandler coverFluidHandler = getCoverCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);
if (destinationTE == null && coverFluidHandler == null) {
continue;
}
GTFluidUtils.transferFluids(myFluidHandler, fluidHandler, Integer.MAX_VALUE);
if(fluidVoiding != null && destinationTE != null) {
List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferList = new ArrayList<>();
transferList.add(new Tuple<>(coverFluidHandler, fluidVoiding.checkInputFluid()));
transferList.add(new Tuple<>(destinationTE, fluidStack -> true));
GTFluidUtils.transferFluidsToMultipleHandlers(machineFluidHandler, transferList, Integer.MAX_VALUE);
}
else if(destinationTE != null){
GTFluidUtils.transferFluids(coverFluidHandler, destinationTE, Integer.MAX_VALUE);
}
}
blockPos.release();
}
Expand Down Expand Up @@ -1204,4 +1226,4 @@ public float getBlockHardness() {
public float getBlockResistance() {
return 6.0f;
}
}
}
65 changes: 46 additions & 19 deletions src/main/java/gregtech/api/util/GTFluidUtils.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package gregtech.api.util;

import net.minecraft.util.Tuple;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class GTFluidUtils {
Expand All @@ -14,34 +17,58 @@ public static int transferFluids(@Nonnull IFluidHandler sourceHandler, @Nonnull
}

public static int transferFluids(@Nonnull IFluidHandler sourceHandler, @Nonnull IFluidHandler destHandler, int transferLimit, @Nonnull Predicate<FluidStack> fluidFilter) {

List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferSet = new ArrayList<>();
transferSet.add(new Tuple<>(destHandler, fluidFilter));
return transferFluidsToMultipleHandlers(sourceHandler, transferSet, transferLimit);
}

/**
Used to void fluids through the fluid voiding filter before transferring any non voided fluids into a neighboring fluid handler
destHandler is an array of fluid handlers, with the handler of the voiding fluid cover first
**/
public static int transferFluidsToMultipleHandlers(@Nonnull IFluidHandler sourceHandler, @Nonnull List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferTuple, int transferLimit) {


int fluidLeftToTransfer = transferLimit;

for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) {
FluidStack currentFluid = tankProperties.getContents();
if (currentFluid == null || currentFluid.amount == 0 || !fluidFilter.test(currentFluid)) {
continue;
}
for(Tuple<IFluidHandler, Predicate<FluidStack>> transfer : transferTuple) {

currentFluid.amount = fluidLeftToTransfer;
FluidStack fluidStack = sourceHandler.drain(currentFluid, false);
if (fluidStack == null || fluidStack.amount == 0) {
continue;
}
IFluidHandler destination = transfer.getFirst();
Predicate<FluidStack> filter = transfer.getSecond();

int canInsertAmount = destHandler.fill(fluidStack, false);
if (canInsertAmount > 0) {
fluidStack.amount = canInsertAmount;
fluidStack = sourceHandler.drain(fluidStack, true);
if (fluidStack != null && fluidStack.amount > 0) {
destHandler.fill(fluidStack, true);
//Check the contents of the source provider
for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) {
FluidStack currentFluid = tankProperties.getContents();
if (currentFluid == null || currentFluid.amount == 0 || (!filter.test(currentFluid))) {
continue;
}

//Set the amount to be drained on the fluid to the maximum amount
currentFluid.amount = fluidLeftToTransfer;
//Simulate the drain to find the resultant Fluid and amount
FluidStack fluidStack = sourceHandler.drain(currentFluid, false);
if (fluidStack == null || fluidStack.amount == 0) {
continue;
}

fluidLeftToTransfer -= fluidStack.amount;
if (fluidLeftToTransfer == 0) {
break;
int canInsertAmount = destination.fill(fluidStack, false);
if (canInsertAmount > 0) {
fluidStack.amount = canInsertAmount;
fluidStack = sourceHandler.drain(fluidStack, true);
if (fluidStack != null && fluidStack.amount > 0) {
destination.fill(fluidStack, true);

fluidLeftToTransfer -= fluidStack.amount;
if (fluidLeftToTransfer == 0) {
break;
}
}
}

}
}

return transferLimit - fluidLeftToTransfer;
}
}
2 changes: 2 additions & 0 deletions src/main/java/gregtech/common/covers/CoverBehaviors.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public static void init() {
registerBehavior(37, new ResourceLocation(GTValues.MODID, "machine_controller"), MetaItems.COVER_MACHINE_CONTROLLER, CoverMachineController::new);
registerBehavior(38, new ResourceLocation(GTValues.MODID, "smart_filter"), MetaItems.SMART_FILTER, (tile, side) -> new CoverItemFilter(tile, side, "cover.smart_item_filter.title", Textures.SMART_FILTER_FILTER_OVERLAY, new SmartItemFilter()));
registerBehavior(39, new ResourceLocation(GTValues.MODID, "facade"), MetaItems.COVER_FACADE, CoverFacade::new);

registerBehavior(40, new ResourceLocation(GTValues.MODID, "fluid_voiding"), MetaItems.COVER_FLUID_VOIDING, CoverFluidVoiding::new);
}

public static void registerBehavior(int coverNetworkId, ResourceLocation coverId, MetaValueItem placerItem, BiFunction<ICoverable, EnumFacing, CoverBehavior> behaviorCreator) {
Expand Down
148 changes: 148 additions & 0 deletions src/main/java/gregtech/common/covers/CoverFluidVoiding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package gregtech.common.covers;

import codechicken.lib.raytracer.CuboidRayTraceResult;
import codechicken.lib.render.CCRenderState;
import codechicken.lib.render.pipeline.IVertexOperation;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Matrix4;
import gregtech.api.capability.GregtechCapabilities;
import gregtech.api.capability.IFluidVoiding;
import gregtech.api.capability.impl.FluidHandlerDelegate;
import gregtech.api.cover.CoverBehavior;
import gregtech.api.cover.CoverWithUI;
import gregtech.api.cover.ICoverable;
import gregtech.api.gui.GuiTextures;
import gregtech.api.gui.ModularUI;
import gregtech.api.gui.widgets.LabelWidget;
import gregtech.api.gui.widgets.WidgetGroup;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.render.Textures;
import gregtech.common.covers.filter.FluidFilterContainer;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.*;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;

import java.util.function.Predicate;

public class CoverFluidVoiding extends CoverBehavior implements CoverWithUI, IFluidVoiding {

private FluidFilterContainer fluidFilter;
protected FluidHandlerVoiding fluidHandler;
private final int voidingAmount = Integer.MAX_VALUE;

public CoverFluidVoiding(ICoverable coverable, EnumFacing attachedSide) {
super(coverable, attachedSide);
fluidFilter = new FluidFilterContainer(this);
}

@Override
public int voidingAmount() {
return voidingAmount;
}

@Override
public boolean canAttach() {
return coverHolder.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, attachedSide) != null;
}

@Override
public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, Cuboid6 plateBox, BlockRenderLayer layer) {
Textures.PUMP_OVERLAY.renderSided(attachedSide, plateBox, renderState, pipeline, translation);
}

@Override
public void onRemoved() {
NonNullList<ItemStack> drops = NonNullList.create();
MetaTileEntity.clearInventory(drops, fluidFilter.getFilterInventory());
for (ItemStack itemStack : drops) {
Block.spawnAsEntity(coverHolder.getWorld(), coverHolder.getPos(), itemStack);
}
}

@Override
public EnumActionResult onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, CuboidRayTraceResult hitResult) {
if (!coverHolder.getWorld().isRemote) {
openUI((EntityPlayerMP) playerIn);
}
return EnumActionResult.SUCCESS;
}

@Override
public boolean shouldCoverInteractWithOutputside() {
return true;
}

@Override
public Predicate<FluidStack> checkInputFluid() {
return fluidStack -> fluidFilter.testFluidStack(fluidStack);
}

@Override
public ModularUI createUI(EntityPlayer player) {
WidgetGroup primaryGroup = new WidgetGroup();

primaryGroup.addWidget(new LabelWidget(10, 5, "cover.fluid_voiding.title"));
fluidFilter.initUI(88, primaryGroup::addWidget);

return ModularUI.builder(GuiTextures.BACKGROUND, 176, 184 + 82)
.widget(primaryGroup)
.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 8, 184)
.build(this, player);
}

@Override
public <T> T getCapability(Capability<T> capability, T defaultValue) {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
IFluidHandler delegate = (IFluidHandler) defaultValue;
if (fluidHandler == null || fluidHandler.delegate != delegate) {
this.fluidHandler = new FluidHandlerVoiding(delegate);
}
return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(fluidHandler);
}
else if (capability == GregtechCapabilities.CAPABILITY_FLUID_VOIDING) {
return GregtechCapabilities.CAPABILITY_FLUID_VOIDING.cast(this);
}
return defaultValue;
}

@Override
public void writeToNBT(NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
tagCompound.setTag("Filter", fluidFilter.serializeNBT());
}

@Override
public void readFromNBT(NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
if (tagCompound.hasKey("FluidFilter")) {
fluidFilter.deserializeNBT(tagCompound);
} else {
fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter"));
}

}

public class FluidHandlerVoiding extends FluidHandlerDelegate {

public FluidHandlerVoiding(IFluidHandler delegate) {
super(delegate);
}

@Override
public int fill(FluidStack resource, boolean doFill) {
if(!checkInputFluid().test(resource)) {
return 0;
}

return voidingAmount;
}
}

}
3 changes: 2 additions & 1 deletion src/main/java/gregtech/common/items/MetaItem1.java
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ public void registerSubItems() {
COVER_CRAFTING = addItem(744, "cover.crafting").setInvisible();
COVER_DRAIN = addItem(745, "cover.drain").setInvisible();

COVER_FLUID_VOIDING = addItem(748, "cover.fluid.voiding");
COVER_SHUTTER = addItem(749, "cover.shutter");

COVER_SOLAR_PANEL = addItem(750, "cover.solar.panel");
Expand Down Expand Up @@ -552,4 +553,4 @@ protected void addMaterialTooltip(ItemStack itemStack, OrePrefix prefix, Materia
}
}

}
}
1 change: 1 addition & 0 deletions src/main/java/gregtech/common/items/MetaItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ private MetaItems() {
public static MetaItem<?>.MetaValueItem COVER_SHUTTER;
public static MetaItem<?>.MetaValueItem COVER_MACHINE_CONTROLLER;
public static MetaItem<?>.MetaValueItem COVER_FACADE;
public static MetaItem<?>.MetaValueItem COVER_FLUID_VOIDING;

public static MetaItem<?>.MetaValueItem COVER_ACTIVITY_DETECTOR;
public static MetaItem<?>.MetaValueItem COVER_FLUID_DETECTOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,14 @@ private static void registerAssemblerRecipes() {
.EUt(16).duration(200)
.buildAndRegister();

RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder()
.input(OrePrefix.plate, Materials.Steel, 4)
.input(OrePrefix.rotor, Materials.Steel, 1)
.inputs(MetaItems.ELECTRIC_MOTOR_LV.getStackForm(1))
.outputs(COVER_FLUID_VOIDING.getStackForm(1))
.EUt(16).duration(200)
.buildAndRegister();

RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder().duration(1800).EUt(30).input(OrePrefix.dust, Materials.EnderPearl, 1).input(OrePrefix.circuit, MarkerMaterials.Tier.Basic, 4).fluidInputs(Materials.Osmium.getFluid(L * 2)).outputs(MetaItems.FIELD_GENERATOR_LV.getStackForm()).buildAndRegister();
RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder().duration(1800).EUt(120).input(OrePrefix.dust, Materials.EnderEye, 1).input(OrePrefix.circuit, MarkerMaterials.Tier.Good, 4).fluidInputs(Materials.Osmium.getFluid(576)).outputs(MetaItems.FIELD_GENERATOR_MV.getStackForm()).buildAndRegister();
RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder().duration(1800).EUt(480).inputs(MetaItems.QUANTUM_EYE.getStackForm()).input(OrePrefix.circuit, MarkerMaterials.Tier.Advanced, 4).fluidInputs(Materials.Osmium.getFluid(1152)).outputs(MetaItems.FIELD_GENERATOR_HV.getStackForm()).buildAndRegister();
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/gregtech/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ metaitem.cover.energy.detector.name=Energy Detector
metaitem.cover.energy.detector.tooltip=Gives out Energy Amount as Redstone
metaitem.cover.player.detector.name=Player Detector
metaitem.cover.player.detector.tooltip=Gives out close Players as Redstone
metaitem.cover.fluid.voiding.name=Fluid Voider
cover.fluid_voiding.title=Fluid Voider

metaitem.cover.facade.name=%s Facade
metaitem.cover.facade.tooltip=Decorative outfit
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "gregtech:items/metaitems/cover.drain"
}
}

0 comments on commit 9306afe

Please sign in to comment.