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

Create the Fluid Voiding cover #1529

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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 @@ -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;

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

import net.minecraftforge.fluids.FluidStack;

import java.util.function.Predicate;

public interface IFluidVoiding {

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

registerCapabilityWithNoDefault(IWrenchItem.class);
registerCapabilityWithNoDefault(IScrewdriverItem.class);
Expand Down
32 changes: 27 additions & 5 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 @@ -868,16 +871,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
64 changes: 45 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,57 @@ 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 transfer fluids from a source to multiple destinations. Each destination can have a separate fluid filter applied.
**/
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
134 changes: 134 additions & 0 deletions src/main/java/gregtech/common/covers/CoverFluidVoiding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
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 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 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);
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return amount of resource which will be transferred and that is maximally amount that is available all maximum which can given tier of cover transfer (in case that there would be tiers).

}
}

}
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 @@ -577,6 +577,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"
}
}