Skip to content

Commit 9306afe

Browse files
First implementation of the Fluid Voiding cover
1 parent 618fc29 commit 9306afe

12 files changed

Lines changed: 259 additions & 26 deletions

File tree

src/main/java/gregtech/api/capability/GregtechCapabilities.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ public class GregtechCapabilities {
2626
@CapabilityInject(IFuelable.class)
2727
public static Capability<IFuelable> CAPABILITY_FUELABLE = null;
2828

29+
@CapabilityInject(IFluidVoiding.class)
30+
public static Capability<IFluidVoiding> CAPABILITY_FLUID_VOIDING = null;
31+
2932
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package gregtech.api.capability;
2+
3+
import net.minecraftforge.fluids.FluidStack;
4+
5+
import java.util.function.Predicate;
6+
7+
public interface IFluidVoiding {
8+
9+
int voidingAmount();
10+
11+
Predicate<FluidStack> checkInputFluid();
12+
}

src/main/java/gregtech/api/capability/SimpleCapabilityManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public static void init() {
3939
registerCapabilityWithNoDefault(ICoverable.class);
4040
registerCapabilityWithNoDefault(IControllable.class);
4141
registerCapabilityWithNoDefault(IFuelable.class);
42+
registerCapabilityWithNoDefault(IFluidVoiding.class);
4243

4344
registerCapabilityWithNoDefault(IWrenchItem.class);
4445
registerCapabilityWithNoDefault(IScrewdriverItem.class);

src/main/java/gregtech/api/metatileentity/MetaTileEntity.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
import codechicken.lib.vec.Matrix4;
1111
import com.google.common.base.Preconditions;
1212
import gregtech.api.GregTechAPI;
13+
import gregtech.api.capability.GregtechCapabilities;
1314
import gregtech.api.capability.GregtechTileCapabilities;
1415
import gregtech.api.capability.IEnergyContainer;
16+
import gregtech.api.capability.IFluidVoiding;
1517
import gregtech.api.capability.impl.FluidHandlerProxy;
1618
import gregtech.api.capability.impl.FluidTankList;
1719
import gregtech.api.capability.impl.ItemHandlerProxy;
@@ -55,6 +57,7 @@
5557
import java.util.ArrayList;
5658
import java.util.List;
5759
import java.util.function.Consumer;
60+
import java.util.function.Predicate;
5861

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

@@ -843,16 +846,35 @@ public void pushFluidsIntoNearbyHandlers(EnumFacing... allowedFaces) {
843846
for (EnumFacing nearbyFacing : allowedFaces) {
844847
blockPos.setPos(getPos()).move(nearbyFacing);
845848
TileEntity tileEntity = getWorld().getTileEntity(blockPos);
846-
if (tileEntity == null) {
849+
//Get the fluid voiding capability
850+
IFluidVoiding fluidVoiding = getCoverCapability(GregtechCapabilities.CAPABILITY_FLUID_VOIDING, nearbyFacing);
851+
//Allow the fluid voiding cover to take fluids, but not be a tile entity
852+
if (tileEntity == null && fluidVoiding == null) {
847853
continue;
848854
}
849-
IFluidHandler fluidHandler = tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing.getOpposite());
855+
//Get the capability of the source machine
856+
IFluidHandler machineFluidHandler = getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);
857+
858+
//Get the capability of the destination TE
859+
IFluidHandler destinationTE = null;
860+
if(tileEntity != null) {
861+
destinationTE = tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing.getOpposite());
862+
}
863+
850864
//use getCoverCapability so fluid tank index filtering and fluid filtering covers will work properly
851-
IFluidHandler myFluidHandler = getCoverCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);
852-
if (fluidHandler == null || myFluidHandler == null) {
865+
IFluidHandler coverFluidHandler = getCoverCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, nearbyFacing);
866+
if (destinationTE == null && coverFluidHandler == null) {
853867
continue;
854868
}
855-
GTFluidUtils.transferFluids(myFluidHandler, fluidHandler, Integer.MAX_VALUE);
869+
if(fluidVoiding != null && destinationTE != null) {
870+
List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferList = new ArrayList<>();
871+
transferList.add(new Tuple<>(coverFluidHandler, fluidVoiding.checkInputFluid()));
872+
transferList.add(new Tuple<>(destinationTE, fluidStack -> true));
873+
GTFluidUtils.transferFluidsToMultipleHandlers(machineFluidHandler, transferList, Integer.MAX_VALUE);
874+
}
875+
else if(destinationTE != null){
876+
GTFluidUtils.transferFluids(coverFluidHandler, destinationTE, Integer.MAX_VALUE);
877+
}
856878
}
857879
blockPos.release();
858880
}
@@ -1204,4 +1226,4 @@ public float getBlockHardness() {
12041226
public float getBlockResistance() {
12051227
return 6.0f;
12061228
}
1207-
}
1229+
}
Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package gregtech.api.util;
22

3+
import net.minecraft.util.Tuple;
34
import net.minecraftforge.fluids.FluidStack;
45
import net.minecraftforge.fluids.capability.IFluidHandler;
56
import net.minecraftforge.fluids.capability.IFluidTankProperties;
67

78
import javax.annotation.Nonnull;
9+
import java.util.ArrayList;
10+
import java.util.List;
811
import java.util.function.Predicate;
912

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

1619
public static int transferFluids(@Nonnull IFluidHandler sourceHandler, @Nonnull IFluidHandler destHandler, int transferLimit, @Nonnull Predicate<FluidStack> fluidFilter) {
20+
21+
List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferSet = new ArrayList<>();
22+
transferSet.add(new Tuple<>(destHandler, fluidFilter));
23+
return transferFluidsToMultipleHandlers(sourceHandler, transferSet, transferLimit);
24+
}
25+
26+
/**
27+
Used to void fluids through the fluid voiding filter before transferring any non voided fluids into a neighboring fluid handler
28+
destHandler is an array of fluid handlers, with the handler of the voiding fluid cover first
29+
**/
30+
public static int transferFluidsToMultipleHandlers(@Nonnull IFluidHandler sourceHandler, @Nonnull List<Tuple<IFluidHandler, Predicate<FluidStack>>> transferTuple, int transferLimit) {
31+
32+
1733
int fluidLeftToTransfer = transferLimit;
1834

19-
for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) {
20-
FluidStack currentFluid = tankProperties.getContents();
21-
if (currentFluid == null || currentFluid.amount == 0 || !fluidFilter.test(currentFluid)) {
22-
continue;
23-
}
35+
for(Tuple<IFluidHandler, Predicate<FluidStack>> transfer : transferTuple) {
2436

25-
currentFluid.amount = fluidLeftToTransfer;
26-
FluidStack fluidStack = sourceHandler.drain(currentFluid, false);
27-
if (fluidStack == null || fluidStack.amount == 0) {
28-
continue;
29-
}
37+
IFluidHandler destination = transfer.getFirst();
38+
Predicate<FluidStack> filter = transfer.getSecond();
3039

31-
int canInsertAmount = destHandler.fill(fluidStack, false);
32-
if (canInsertAmount > 0) {
33-
fluidStack.amount = canInsertAmount;
34-
fluidStack = sourceHandler.drain(fluidStack, true);
35-
if (fluidStack != null && fluidStack.amount > 0) {
36-
destHandler.fill(fluidStack, true);
40+
//Check the contents of the source provider
41+
for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) {
42+
FluidStack currentFluid = tankProperties.getContents();
43+
if (currentFluid == null || currentFluid.amount == 0 || (!filter.test(currentFluid))) {
44+
continue;
45+
}
46+
47+
//Set the amount to be drained on the fluid to the maximum amount
48+
currentFluid.amount = fluidLeftToTransfer;
49+
//Simulate the drain to find the resultant Fluid and amount
50+
FluidStack fluidStack = sourceHandler.drain(currentFluid, false);
51+
if (fluidStack == null || fluidStack.amount == 0) {
52+
continue;
53+
}
3754

38-
fluidLeftToTransfer -= fluidStack.amount;
39-
if (fluidLeftToTransfer == 0) {
40-
break;
55+
int canInsertAmount = destination.fill(fluidStack, false);
56+
if (canInsertAmount > 0) {
57+
fluidStack.amount = canInsertAmount;
58+
fluidStack = sourceHandler.drain(fluidStack, true);
59+
if (fluidStack != null && fluidStack.amount > 0) {
60+
destination.fill(fluidStack, true);
61+
62+
fluidLeftToTransfer -= fluidStack.amount;
63+
if (fluidLeftToTransfer == 0) {
64+
break;
65+
}
4166
}
4267
}
68+
4369
}
4470
}
71+
4572
return transferLimit - fluidLeftToTransfer;
4673
}
4774
}

src/main/java/gregtech/common/covers/CoverBehaviors.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public static void init() {
6161
registerBehavior(37, new ResourceLocation(GTValues.MODID, "machine_controller"), MetaItems.COVER_MACHINE_CONTROLLER, CoverMachineController::new);
6262
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()));
6363
registerBehavior(39, new ResourceLocation(GTValues.MODID, "facade"), MetaItems.COVER_FACADE, CoverFacade::new);
64+
65+
registerBehavior(40, new ResourceLocation(GTValues.MODID, "fluid_voiding"), MetaItems.COVER_FLUID_VOIDING, CoverFluidVoiding::new);
6466
}
6567

6668
public static void registerBehavior(int coverNetworkId, ResourceLocation coverId, MetaValueItem placerItem, BiFunction<ICoverable, EnumFacing, CoverBehavior> behaviorCreator) {
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package gregtech.common.covers;
2+
3+
import codechicken.lib.raytracer.CuboidRayTraceResult;
4+
import codechicken.lib.render.CCRenderState;
5+
import codechicken.lib.render.pipeline.IVertexOperation;
6+
import codechicken.lib.vec.Cuboid6;
7+
import codechicken.lib.vec.Matrix4;
8+
import gregtech.api.capability.GregtechCapabilities;
9+
import gregtech.api.capability.IFluidVoiding;
10+
import gregtech.api.capability.impl.FluidHandlerDelegate;
11+
import gregtech.api.cover.CoverBehavior;
12+
import gregtech.api.cover.CoverWithUI;
13+
import gregtech.api.cover.ICoverable;
14+
import gregtech.api.gui.GuiTextures;
15+
import gregtech.api.gui.ModularUI;
16+
import gregtech.api.gui.widgets.LabelWidget;
17+
import gregtech.api.gui.widgets.WidgetGroup;
18+
import gregtech.api.metatileentity.MetaTileEntity;
19+
import gregtech.api.render.Textures;
20+
import gregtech.common.covers.filter.FluidFilterContainer;
21+
import net.minecraft.block.Block;
22+
import net.minecraft.entity.player.EntityPlayer;
23+
import net.minecraft.entity.player.EntityPlayerMP;
24+
import net.minecraft.item.ItemStack;
25+
import net.minecraft.nbt.NBTTagCompound;
26+
import net.minecraft.util.*;
27+
import net.minecraftforge.common.capabilities.Capability;
28+
import net.minecraftforge.fluids.FluidStack;
29+
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
30+
import net.minecraftforge.fluids.capability.IFluidHandler;
31+
32+
import java.util.function.Predicate;
33+
34+
public class CoverFluidVoiding extends CoverBehavior implements CoverWithUI, IFluidVoiding {
35+
36+
private FluidFilterContainer fluidFilter;
37+
protected FluidHandlerVoiding fluidHandler;
38+
private final int voidingAmount = Integer.MAX_VALUE;
39+
40+
public CoverFluidVoiding(ICoverable coverable, EnumFacing attachedSide) {
41+
super(coverable, attachedSide);
42+
fluidFilter = new FluidFilterContainer(this);
43+
}
44+
45+
@Override
46+
public int voidingAmount() {
47+
return voidingAmount;
48+
}
49+
50+
@Override
51+
public boolean canAttach() {
52+
return coverHolder.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, attachedSide) != null;
53+
}
54+
55+
@Override
56+
public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, Cuboid6 plateBox, BlockRenderLayer layer) {
57+
Textures.PUMP_OVERLAY.renderSided(attachedSide, plateBox, renderState, pipeline, translation);
58+
}
59+
60+
@Override
61+
public void onRemoved() {
62+
NonNullList<ItemStack> drops = NonNullList.create();
63+
MetaTileEntity.clearInventory(drops, fluidFilter.getFilterInventory());
64+
for (ItemStack itemStack : drops) {
65+
Block.spawnAsEntity(coverHolder.getWorld(), coverHolder.getPos(), itemStack);
66+
}
67+
}
68+
69+
@Override
70+
public EnumActionResult onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, CuboidRayTraceResult hitResult) {
71+
if (!coverHolder.getWorld().isRemote) {
72+
openUI((EntityPlayerMP) playerIn);
73+
}
74+
return EnumActionResult.SUCCESS;
75+
}
76+
77+
@Override
78+
public boolean shouldCoverInteractWithOutputside() {
79+
return true;
80+
}
81+
82+
@Override
83+
public Predicate<FluidStack> checkInputFluid() {
84+
return fluidStack -> fluidFilter.testFluidStack(fluidStack);
85+
}
86+
87+
@Override
88+
public ModularUI createUI(EntityPlayer player) {
89+
WidgetGroup primaryGroup = new WidgetGroup();
90+
91+
primaryGroup.addWidget(new LabelWidget(10, 5, "cover.fluid_voiding.title"));
92+
fluidFilter.initUI(88, primaryGroup::addWidget);
93+
94+
return ModularUI.builder(GuiTextures.BACKGROUND, 176, 184 + 82)
95+
.widget(primaryGroup)
96+
.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 8, 184)
97+
.build(this, player);
98+
}
99+
100+
@Override
101+
public <T> T getCapability(Capability<T> capability, T defaultValue) {
102+
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
103+
IFluidHandler delegate = (IFluidHandler) defaultValue;
104+
if (fluidHandler == null || fluidHandler.delegate != delegate) {
105+
this.fluidHandler = new FluidHandlerVoiding(delegate);
106+
}
107+
return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(fluidHandler);
108+
}
109+
else if (capability == GregtechCapabilities.CAPABILITY_FLUID_VOIDING) {
110+
return GregtechCapabilities.CAPABILITY_FLUID_VOIDING.cast(this);
111+
}
112+
return defaultValue;
113+
}
114+
115+
@Override
116+
public void writeToNBT(NBTTagCompound tagCompound) {
117+
super.writeToNBT(tagCompound);
118+
tagCompound.setTag("Filter", fluidFilter.serializeNBT());
119+
}
120+
121+
@Override
122+
public void readFromNBT(NBTTagCompound tagCompound) {
123+
super.readFromNBT(tagCompound);
124+
if (tagCompound.hasKey("FluidFilter")) {
125+
fluidFilter.deserializeNBT(tagCompound);
126+
} else {
127+
fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter"));
128+
}
129+
130+
}
131+
132+
public class FluidHandlerVoiding extends FluidHandlerDelegate {
133+
134+
public FluidHandlerVoiding(IFluidHandler delegate) {
135+
super(delegate);
136+
}
137+
138+
@Override
139+
public int fill(FluidStack resource, boolean doFill) {
140+
if(!checkInputFluid().test(resource)) {
141+
return 0;
142+
}
143+
144+
return voidingAmount;
145+
}
146+
}
147+
148+
}

src/main/java/gregtech/common/items/MetaItem1.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ public void registerSubItems() {
279279
COVER_CRAFTING = addItem(744, "cover.crafting").setInvisible();
280280
COVER_DRAIN = addItem(745, "cover.drain").setInvisible();
281281

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

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

555-
}
556+
}

src/main/java/gregtech/common/items/MetaItems.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ private MetaItems() {
306306
public static MetaItem<?>.MetaValueItem COVER_SHUTTER;
307307
public static MetaItem<?>.MetaValueItem COVER_MACHINE_CONTROLLER;
308308
public static MetaItem<?>.MetaValueItem COVER_FACADE;
309+
public static MetaItem<?>.MetaValueItem COVER_FLUID_VOIDING;
309310

310311
public static MetaItem<?>.MetaValueItem COVER_ACTIVITY_DETECTOR;
311312
public static MetaItem<?>.MetaValueItem COVER_FLUID_DETECTOR;

src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,14 @@ private static void registerAssemblerRecipes() {
609609
.EUt(16).duration(200)
610610
.buildAndRegister();
611611

612+
RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder()
613+
.input(OrePrefix.plate, Materials.Steel, 4)
614+
.input(OrePrefix.rotor, Materials.Steel, 1)
615+
.inputs(MetaItems.ELECTRIC_MOTOR_LV.getStackForm(1))
616+
.outputs(COVER_FLUID_VOIDING.getStackForm(1))
617+
.EUt(16).duration(200)
618+
.buildAndRegister();
619+
612620
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();
613621
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();
614622
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();

0 commit comments

Comments
 (0)