mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-16 07:53:42 +01:00
Workstation transfer, Part II
- Intermediate changes, probably doesn't even compile
This commit is contained in:
parent
d9d5e60606
commit
2d6d360da4
6 changed files with 473 additions and 114 deletions
|
@ -3,9 +3,9 @@ package com.simibubi.create.content.contraptions.fluids.actors;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.foundation.fluid.FluidRenderer;
|
import com.simibubi.create.foundation.fluid.FluidRenderer;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.LerpedFloat;
|
|
||||||
import com.simibubi.create.foundation.utility.Pair;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
@ -27,9 +27,13 @@ public class SpoutRenderer extends SafeTileEntityRenderer<SpoutTileEntity> {
|
||||||
protected void renderSafe(SpoutTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(SpoutTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
|
|
||||||
Pair<FluidStack, LerpedFloat> fluid = te.getFluid();
|
SmartFluidTankBehaviour tank = te.tank;
|
||||||
FluidStack fluidStack = fluid.getFirst();
|
if (tank == null)
|
||||||
float level = fluid.getSecond()
|
return;
|
||||||
|
|
||||||
|
TankSegment primaryTank = tank.getPrimaryTank();
|
||||||
|
FluidStack fluidStack = primaryTank.getRenderedFluid();
|
||||||
|
float level = primaryTank.getFluidLevel()
|
||||||
.getValue(partialTicks);
|
.getValue(partialTicks);
|
||||||
|
|
||||||
if (!fluidStack.isEmpty() && level != 0) {
|
if (!fluidStack.isEmpty() && level != 0) {
|
||||||
|
|
|
@ -7,16 +7,13 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
import com.simibubi.create.foundation.fluid.SmartFluidTank;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||||
import com.simibubi.create.foundation.utility.LerpedFloat;
|
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.LerpedFloat.Chaser;
|
|
||||||
import com.simibubi.create.foundation.utility.Pair;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -32,58 +29,22 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
|
||||||
|
|
||||||
// FIXME: Quite similar to FluidTankTileEntity, create a behaviour
|
|
||||||
|
|
||||||
public class SpoutTileEntity extends SmartTileEntity {
|
public class SpoutTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
protected FluidTank tank;
|
|
||||||
protected LazyOptional<IFluidHandler> capability;
|
|
||||||
protected LerpedFloat fluidLevel;
|
|
||||||
protected FluidStack renderedFluid;
|
|
||||||
|
|
||||||
public static final int FILLING_TIME = 20;
|
public static final int FILLING_TIME = 20;
|
||||||
protected int processingTicks;
|
|
||||||
|
|
||||||
private static final int SYNC_RATE = 8;
|
|
||||||
protected int syncCooldown;
|
|
||||||
protected boolean queuedSync;
|
|
||||||
|
|
||||||
protected boolean sendSplash;
|
|
||||||
protected BeltProcessingBehaviour beltProcessing;
|
protected BeltProcessingBehaviour beltProcessing;
|
||||||
|
protected int processingTicks;
|
||||||
|
protected boolean sendSplash;
|
||||||
|
|
||||||
|
SmartFluidTankBehaviour tank;
|
||||||
|
|
||||||
public SpoutTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
public SpoutTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||||
super(tileEntityTypeIn);
|
super(tileEntityTypeIn);
|
||||||
tank = new SmartFluidTank(1000, this::onFluidStackChanged);
|
|
||||||
capability = LazyOptional.of(() -> tank);
|
|
||||||
fluidLevel = LerpedFloat.linear()
|
|
||||||
.startWithValue(0)
|
|
||||||
.chase(0, .25, Chaser.EXP);
|
|
||||||
renderedFluid = FluidStack.EMPTY;
|
|
||||||
processingTicks = -1;
|
processingTicks = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onFluidStackChanged(FluidStack newFluidStack) {
|
|
||||||
if (!hasWorld())
|
|
||||||
return;
|
|
||||||
fluidLevel.chase(tank.getFluidAmount() / (float) tank.getCapacity(), .25, Chaser.EXP);
|
|
||||||
if (!world.isRemote) {
|
|
||||||
markDirty();
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize() {
|
|
||||||
super.initialize();
|
|
||||||
if (!world.isRemote) {
|
|
||||||
fluidLevel.forceNextSync();
|
|
||||||
onFluidStackChanged(tank.getFluid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AxisAlignedBB getRenderBoundingBox() {
|
public AxisAlignedBB getRenderBoundingBox() {
|
||||||
return super.getRenderBoundingBox().expand(0, -2, 0);
|
return super.getRenderBoundingBox().expand(0, -2, 0);
|
||||||
|
@ -91,9 +52,13 @@ public class SpoutTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
tank = SmartFluidTankBehaviour.single(this, 1000);
|
||||||
|
behaviours.add(tank);
|
||||||
|
|
||||||
beltProcessing = new BeltProcessingBehaviour(this).whenItemEnters(this::onItemReceived)
|
beltProcessing = new BeltProcessingBehaviour(this).whenItemEnters(this::onItemReceived)
|
||||||
.whileItemHeld(this::whenItemHeld);
|
.whileItemHeld(this::whenItemHeld);
|
||||||
behaviours.add(beltProcessing);
|
behaviours.add(beltProcessing);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ProcessingResult onItemReceived(TransportedItemStack transported,
|
protected ProcessingResult onItemReceived(TransportedItemStack transported,
|
||||||
|
@ -102,7 +67,7 @@ public class SpoutTileEntity extends SmartTileEntity {
|
||||||
return PASS;
|
return PASS;
|
||||||
if (tank.isEmpty())
|
if (tank.isEmpty())
|
||||||
return HOLD;
|
return HOLD;
|
||||||
if (FillingBySpout.getRequiredAmountForItem(world, transported.stack, tank.getFluid()) == -1)
|
if (FillingBySpout.getRequiredAmountForItem(world, transported.stack, getCurrentFluidInTank()) == -1)
|
||||||
return PASS;
|
return PASS;
|
||||||
return HOLD;
|
return HOLD;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +80,7 @@ public class SpoutTileEntity extends SmartTileEntity {
|
||||||
return PASS;
|
return PASS;
|
||||||
if (tank.isEmpty())
|
if (tank.isEmpty())
|
||||||
return HOLD;
|
return HOLD;
|
||||||
FluidStack fluid = tank.getFluid();
|
FluidStack fluid = getCurrentFluidInTank();
|
||||||
int requiredAmountForItem = FillingBySpout.getRequiredAmountForItem(world, transported.stack, fluid.copy());
|
int requiredAmountForItem = FillingBySpout.getRequiredAmountForItem(world, transported.stack, fluid.copy());
|
||||||
if (requiredAmountForItem == -1)
|
if (requiredAmountForItem == -1)
|
||||||
return PASS;
|
return PASS;
|
||||||
|
@ -142,24 +107,21 @@ public class SpoutTileEntity extends SmartTileEntity {
|
||||||
handler.handleProcessingOnItem(transported, TransportedResult.convertToAndLeaveHeld(outList, held));
|
handler.handleProcessingOnItem(transported, TransportedResult.convertToAndLeaveHeld(outList, held));
|
||||||
}
|
}
|
||||||
|
|
||||||
tank.setFluid(fluid);
|
tank.getPrimaryHandler().setFluid(fluid);
|
||||||
sendSplash = true;
|
sendSplash = true;
|
||||||
markDirty();
|
markDirty();
|
||||||
sendData();
|
sendData();
|
||||||
return PASS;
|
return PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private FluidStack getCurrentFluidInTank() {
|
||||||
public void remove() {
|
return tank.getPrimaryHandler().getFluid();
|
||||||
capability.invalidate();
|
|
||||||
super.remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void write(CompoundNBT compound, boolean clientPacket) {
|
protected void write(CompoundNBT compound, boolean clientPacket) {
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
compound.put("TankContent", tank.writeToNBT(new CompoundNBT()));
|
|
||||||
compound.put("Level", fluidLevel.writeNBT());
|
|
||||||
compound.putInt("ProcessingTicks", processingTicks);
|
compound.putInt("ProcessingTicks", processingTicks);
|
||||||
if (sendSplash && clientPacket) {
|
if (sendSplash && clientPacket) {
|
||||||
compound.putBoolean("Splash", true);
|
compound.putBoolean("Splash", true);
|
||||||
|
@ -170,61 +132,27 @@ public class SpoutTileEntity extends SmartTileEntity {
|
||||||
@Override
|
@Override
|
||||||
protected void read(CompoundNBT compound, boolean clientPacket) {
|
protected void read(CompoundNBT compound, boolean clientPacket) {
|
||||||
super.read(compound, clientPacket);
|
super.read(compound, clientPacket);
|
||||||
tank.readFromNBT(compound.getCompound("TankContent"));
|
|
||||||
fluidLevel.readNBT(compound.getCompound("Level"), clientPacket);
|
|
||||||
processingTicks = compound.getInt("ProcessingTicks");
|
processingTicks = compound.getInt("ProcessingTicks");
|
||||||
if (!tank.getFluid()
|
|
||||||
.isEmpty())
|
|
||||||
renderedFluid = tank.getFluid();
|
|
||||||
|
|
||||||
if (!clientPacket)
|
if (!clientPacket)
|
||||||
return;
|
return;
|
||||||
if (compound.contains("Splash"))
|
if (compound.contains("Splash"))
|
||||||
spawnSplash(renderedFluid);
|
spawnSplash(tank.getPrimaryTank().getRenderedFluid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||||
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY && side != Direction.DOWN)
|
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY && side != Direction.DOWN)
|
||||||
return capability.cast();
|
return tank.getCapability().cast();
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<FluidStack, LerpedFloat> getFluid() {
|
|
||||||
return Pair.of(renderedFluid, fluidLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendDataImmediately() {
|
|
||||||
syncCooldown = 0;
|
|
||||||
queuedSync = false;
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
if (processingTicks >= 0)
|
if (processingTicks >= 0)
|
||||||
processingTicks--;
|
processingTicks--;
|
||||||
if (processingTicks >= 8 && world.isRemote)
|
if (processingTicks >= 8 && world.isRemote)
|
||||||
spawnProcessingParticles(renderedFluid);
|
spawnProcessingParticles(tank.getPrimaryTank().getRenderedFluid());
|
||||||
if (syncCooldown > 0) {
|
|
||||||
syncCooldown--;
|
|
||||||
if (syncCooldown == 0 && queuedSync)
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
if (fluidLevel != null)
|
|
||||||
fluidLevel.tickChaser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendData() {
|
|
||||||
if (syncCooldown > 0) {
|
|
||||||
queuedSync = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
super.sendData();
|
|
||||||
queuedSync = false;
|
|
||||||
syncCooldown = SYNC_RATE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void spawnProcessingParticles(FluidStack fluid) {
|
protected void spawnProcessingParticles(FluidStack fluid) {
|
||||||
|
|
|
@ -5,18 +5,18 @@ import java.util.Optional;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.fluids.CombinedFluidHandler;
|
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||||
import com.simibubi.create.foundation.item.SmartInventory;
|
import com.simibubi.create.foundation.item.SmartInventory;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
@ -27,6 +27,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
|
@ -34,20 +35,25 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
public BasinInputInventory inputInventory;
|
public BasinInputInventory inputInventory;
|
||||||
protected SmartInventory outputInventory;
|
public SmartFluidTankBehaviour inputTank;
|
||||||
protected LazyOptional<IItemHandlerModifiable> itemCapability;
|
|
||||||
protected LazyOptional<CombinedFluidHandler> fluidCapability;
|
protected SmartInventory outputInventory;
|
||||||
|
protected SmartFluidTankBehaviour outputTank;
|
||||||
|
|
||||||
|
protected LazyOptional<IItemHandlerModifiable> itemCapability;
|
||||||
|
protected LazyOptional<IFluidHandler> fluidCapability;
|
||||||
|
|
||||||
private boolean contentsChanged;
|
|
||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
|
private boolean contentsChanged;
|
||||||
|
|
||||||
public BasinTileEntity(TileEntityType<? extends BasinTileEntity> type) {
|
public BasinTileEntity(TileEntityType<? extends BasinTileEntity> type) {
|
||||||
super(type);
|
super(type);
|
||||||
inputInventory = new BasinInputInventory(9, this);
|
inputInventory = new BasinInputInventory(9, this);
|
||||||
inputInventory.withMaxStackSize(8).forbidExtraction();
|
inputInventory.withMaxStackSize(8)
|
||||||
|
.forbidExtraction();
|
||||||
outputInventory = new SmartInventory(9, this).forbidInsertion();
|
outputInventory = new SmartInventory(9, this).forbidInsertion();
|
||||||
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory));
|
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory));
|
||||||
fluidCapability = LazyOptional.of(() -> new CombinedFluidHandler(9, 1000));
|
|
||||||
contentsChanged = true;
|
contentsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +64,16 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
||||||
.withCallback(newFilter -> contentsChanged = true)
|
.withCallback(newFilter -> contentsChanged = true)
|
||||||
.forRecipes();
|
.forRecipes();
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
|
|
||||||
|
inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true).forbidExtraction();
|
||||||
|
outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true).forbidInsertion();
|
||||||
|
behaviours.add(inputTank);
|
||||||
|
behaviours.add(outputTank);
|
||||||
|
fluidCapability = LazyOptional.of(() -> {
|
||||||
|
LazyOptional<? extends IFluidHandler> inputCap = inputTank.getCapability();
|
||||||
|
LazyOptional<? extends IFluidHandler> outputCap = outputTank.getCapability();
|
||||||
|
return new CombinedTankWrapper(inputCap.orElse(null), outputCap.orElse(null));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,9 +81,6 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
||||||
super.read(compound, clientPacket);
|
super.read(compound, clientPacket);
|
||||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||||
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
|
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
|
||||||
if (compound.contains("fluids"))
|
|
||||||
fluidCapability
|
|
||||||
.ifPresent(combinedFluidHandler -> combinedFluidHandler.readFromNBT(compound.getList("fluids", 10)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -75,10 +88,6 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
compound.put("InputItems", inputInventory.serializeNBT());
|
compound.put("InputItems", inputInventory.serializeNBT());
|
||||||
compound.put("OutputItems", outputInventory.serializeNBT());
|
compound.put("OutputItems", outputInventory.serializeNBT());
|
||||||
fluidCapability.ifPresent(combinedFuidHandler -> {
|
|
||||||
ListNBT nbt = combinedFuidHandler.getListNBT();
|
|
||||||
compound.put("fluids", nbt);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEmptied() {
|
public void onEmptied() {
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
package com.simibubi.create.foundation.fluid;
|
||||||
|
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
|
import net.minecraftforge.items.wrapper.EmptyHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines multiple IFluidHandlers into one interface (See CombinedInvWrapper
|
||||||
|
* for items)
|
||||||
|
*/
|
||||||
|
public class CombinedTankWrapper implements IFluidHandler {
|
||||||
|
|
||||||
|
protected final IFluidHandler[] itemHandler;
|
||||||
|
protected final int[] baseIndex;
|
||||||
|
protected final int tankCount;
|
||||||
|
protected boolean enforceVariety;
|
||||||
|
|
||||||
|
public CombinedTankWrapper(IFluidHandler... fluidHandlers) {
|
||||||
|
this.itemHandler = fluidHandlers;
|
||||||
|
this.baseIndex = new int[fluidHandlers.length];
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < fluidHandlers.length; i++) {
|
||||||
|
index += fluidHandlers[i].getTanks();
|
||||||
|
baseIndex[i] = index;
|
||||||
|
}
|
||||||
|
this.tankCount = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombinedTankWrapper enforceVariety() {
|
||||||
|
enforceVariety = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTanks() {
|
||||||
|
return tankCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack getFluidInTank(int tank) {
|
||||||
|
int index = getIndexForSlot(tank);
|
||||||
|
IFluidHandler handler = getHandlerFromIndex(index);
|
||||||
|
tank = getSlotFromIndex(tank, index);
|
||||||
|
return handler.getFluidInTank(tank);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTankCapacity(int tank) {
|
||||||
|
int index = getIndexForSlot(tank);
|
||||||
|
IFluidHandler handler = getHandlerFromIndex(index);
|
||||||
|
int localSlot = getSlotFromIndex(tank, index);
|
||||||
|
return handler.getTankCapacity(localSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFluidValid(int tank, FluidStack stack) {
|
||||||
|
int index = getIndexForSlot(tank);
|
||||||
|
IFluidHandler handler = getHandlerFromIndex(index);
|
||||||
|
int localSlot = getSlotFromIndex(tank, index);
|
||||||
|
return handler.isFluidValid(localSlot, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fill(FluidStack resource, FluidAction action) {
|
||||||
|
int filled = 0;
|
||||||
|
resource = resource.copy();
|
||||||
|
|
||||||
|
for (IFluidHandler iFluidHandler : itemHandler) {
|
||||||
|
boolean skipRest = false;
|
||||||
|
int filledIntoCurrent = iFluidHandler.fill(resource, action);
|
||||||
|
|
||||||
|
for (int i = 0; i < iFluidHandler.getTanks(); i++)
|
||||||
|
if (iFluidHandler.getFluidInTank(i).isFluidEqual(resource) && enforceVariety)
|
||||||
|
skipRest = true;
|
||||||
|
|
||||||
|
resource.shrink(filledIntoCurrent);
|
||||||
|
filled += filledIntoCurrent;
|
||||||
|
|
||||||
|
if (resource.isEmpty() || skipRest)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||||
|
FluidStack drained = FluidStack.EMPTY;
|
||||||
|
resource = resource.copy();
|
||||||
|
|
||||||
|
for (IFluidHandler iFluidHandler : itemHandler) {
|
||||||
|
FluidStack drainedFromCurrent = iFluidHandler.drain(resource, action);
|
||||||
|
int amount = drainedFromCurrent.getAmount();
|
||||||
|
resource.shrink(amount);
|
||||||
|
|
||||||
|
if (!drainedFromCurrent.isEmpty())
|
||||||
|
drained = new FluidStack(drainedFromCurrent.getFluid(), amount + drained.getAmount());
|
||||||
|
if (resource.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drained;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||||
|
FluidStack drained = FluidStack.EMPTY;
|
||||||
|
|
||||||
|
for (IFluidHandler iFluidHandler : itemHandler) {
|
||||||
|
FluidStack drainedFromCurrent = iFluidHandler.drain(maxDrain, action);
|
||||||
|
int amount = drainedFromCurrent.getAmount();
|
||||||
|
maxDrain -= amount;
|
||||||
|
|
||||||
|
if (!drainedFromCurrent.isEmpty())
|
||||||
|
drained = new FluidStack(drainedFromCurrent.getFluid(), amount + drained.getAmount());
|
||||||
|
if (maxDrain == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drained;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getIndexForSlot(int slot) {
|
||||||
|
if (slot < 0)
|
||||||
|
return -1;
|
||||||
|
for (int i = 0; i < baseIndex.length; i++)
|
||||||
|
if (slot - baseIndex[i] < 0)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IFluidHandler getHandlerFromIndex(int index) {
|
||||||
|
if (index < 0 || index >= itemHandler.length)
|
||||||
|
return (IFluidHandler) EmptyHandler.INSTANCE;
|
||||||
|
return itemHandler[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getSlotFromIndex(int slot, int index) {
|
||||||
|
if (index <= 0 || index >= baseIndex.length)
|
||||||
|
return slot;
|
||||||
|
return slot - baseIndex[index - 1];
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,4 +4,18 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
|
||||||
public class BehaviourType<T extends TileEntityBehaviour> {
|
public class BehaviourType<T extends TileEntityBehaviour> {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public BehaviourType(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BehaviourType() {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
package com.simibubi.create.foundation.tileEntity.behaviour.fluid;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||||
|
import com.simibubi.create.foundation.fluid.SmartFluidTank;
|
||||||
|
import com.simibubi.create.foundation.item.SmartInventory;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
import com.simibubi.create.foundation.utility.LerpedFloat;
|
||||||
|
import com.simibubi.create.foundation.utility.LerpedFloat.Chaser;
|
||||||
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
|
|
||||||
|
public class SmartFluidTankBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
|
public static BehaviourType<SmartFluidTankBehaviour>
|
||||||
|
|
||||||
|
TYPE = new BehaviourType<>(), INPUT = new BehaviourType<>("Input"), OUTPUT = new BehaviourType<>("Output");
|
||||||
|
|
||||||
|
private static final int SYNC_RATE = 8;
|
||||||
|
|
||||||
|
protected int syncCooldown;
|
||||||
|
protected boolean queuedSync;
|
||||||
|
protected TankSegment[] tanks;
|
||||||
|
protected LazyOptional<? extends IFluidHandler> capability;
|
||||||
|
protected boolean extractionAllowed;
|
||||||
|
protected boolean insertionAllowed;
|
||||||
|
|
||||||
|
private BehaviourType<SmartFluidTankBehaviour> behaviourType;
|
||||||
|
|
||||||
|
public static SmartFluidTankBehaviour single(SmartTileEntity te, int capacity) {
|
||||||
|
return new SmartFluidTankBehaviour(TYPE, te, 1, capacity, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTankBehaviour(BehaviourType<SmartFluidTankBehaviour> type, SmartTileEntity te, int tanks,
|
||||||
|
int tankCapacity, boolean enforceVariety) {
|
||||||
|
super(te);
|
||||||
|
insertionAllowed = true;
|
||||||
|
extractionAllowed = true;
|
||||||
|
behaviourType = type;
|
||||||
|
this.tanks = new TankSegment[tanks];
|
||||||
|
IFluidHandler[] handlers = new IFluidHandler[tanks];
|
||||||
|
for (int i = 0; i < tanks; i++) {
|
||||||
|
TankSegment tankSegment = new TankSegment(tankCapacity);
|
||||||
|
this.tanks[i] = tankSegment;
|
||||||
|
handlers[i] = tankSegment.tank;
|
||||||
|
}
|
||||||
|
capability = LazyOptional.of(() -> new InternalFluidHandler(handlers));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTankBehaviour allowInsertion() {
|
||||||
|
insertionAllowed = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTankBehaviour allowExtraction() {
|
||||||
|
extractionAllowed = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTankBehaviour forbidInsertion() {
|
||||||
|
insertionAllowed = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTankBehaviour forbidExtraction() {
|
||||||
|
extractionAllowed = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
super.initialize();
|
||||||
|
if (getWorld().isRemote)
|
||||||
|
return;
|
||||||
|
foreach(ts -> {
|
||||||
|
ts.fluidLevel.forceNextSync();
|
||||||
|
ts.onFluidStackChanged(ts.tank.getFluid());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
|
||||||
|
if (syncCooldown > 0) {
|
||||||
|
syncCooldown--;
|
||||||
|
if (syncCooldown == 0 && queuedSync)
|
||||||
|
tileEntity.sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(te -> {
|
||||||
|
LerpedFloat fluidLevel = te.getFluidLevel();
|
||||||
|
if (fluidLevel != null)
|
||||||
|
fluidLevel.tickChaser();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendDataImmediately() {
|
||||||
|
syncCooldown = 0;
|
||||||
|
queuedSync = false;
|
||||||
|
tileEntity.sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendDataLazily() {
|
||||||
|
if (syncCooldown > 0) {
|
||||||
|
queuedSync = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tileEntity.sendData();
|
||||||
|
queuedSync = false;
|
||||||
|
syncCooldown = SYNC_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
super.remove();
|
||||||
|
capability.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartFluidTank getPrimaryHandler() {
|
||||||
|
return getPrimaryTank().tank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TankSegment getPrimaryTank() {
|
||||||
|
return tanks[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public TankSegment[] getTanks() {
|
||||||
|
return tanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
for (TankSegment tankSegment : tanks)
|
||||||
|
if (!tankSegment.tank.isEmpty())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void foreach(Consumer<TankSegment> action) {
|
||||||
|
for (TankSegment tankSegment : tanks)
|
||||||
|
action.accept(tankSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LazyOptional<? extends IFluidHandler> getCapability() {
|
||||||
|
return capability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
|
super.write(nbt, clientPacket);
|
||||||
|
ListNBT tanksNBT = new ListNBT();
|
||||||
|
foreach(ts -> tanksNBT.add(ts.writeNBT()));
|
||||||
|
nbt.put(getType().getName() + "Tanks", tanksNBT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT nbt, boolean clientPacket) {
|
||||||
|
super.read(nbt, clientPacket);
|
||||||
|
MutableInt index = new MutableInt(0);
|
||||||
|
NBTHelper.iterateCompoundList(nbt.getList(getType().getName() + "Tanks", NBT.TAG_COMPOUND), c -> {
|
||||||
|
if (index.intValue() >= tanks.length)
|
||||||
|
return;
|
||||||
|
tanks[index.intValue()].readNBT(c, clientPacket);
|
||||||
|
index.increment();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class InternalFluidHandler extends CombinedTankWrapper {
|
||||||
|
|
||||||
|
public InternalFluidHandler(IFluidHandler[] handlers) {
|
||||||
|
super(handlers);
|
||||||
|
if (enforceVariety)
|
||||||
|
enforceVariety();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fill(FluidStack resource, FluidAction action) {
|
||||||
|
if (!insertionAllowed)
|
||||||
|
return 0;
|
||||||
|
return super.fill(resource, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||||
|
if (!extractionAllowed)
|
||||||
|
return FluidStack.EMPTY;
|
||||||
|
return super.drain(resource, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||||
|
if (!extractionAllowed)
|
||||||
|
return FluidStack.EMPTY;
|
||||||
|
return super.drain(maxDrain, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TankSegment {
|
||||||
|
|
||||||
|
protected SmartFluidTank tank;
|
||||||
|
protected LerpedFloat fluidLevel;
|
||||||
|
protected FluidStack renderedFluid;
|
||||||
|
|
||||||
|
public TankSegment(int capacity) {
|
||||||
|
tank = new SmartFluidTank(1000, f -> onFluidStackChanged(f));
|
||||||
|
fluidLevel = LerpedFloat.linear()
|
||||||
|
.startWithValue(0)
|
||||||
|
.chase(0, .25, Chaser.EXP);
|
||||||
|
renderedFluid = FluidStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onFluidStackChanged(FluidStack newFluidStack) {
|
||||||
|
if (!tileEntity.hasWorld())
|
||||||
|
return;
|
||||||
|
fluidLevel.chase(tank.getFluidAmount() / (float) tank.getCapacity(), .25, Chaser.EXP);
|
||||||
|
if (!getWorld().isRemote)
|
||||||
|
sendDataLazily();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidStack getRenderedFluid() {
|
||||||
|
return renderedFluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LerpedFloat getFluidLevel() {
|
||||||
|
return fluidLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundNBT writeNBT() {
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
compound.put("TankContent", tank.writeToNBT(new CompoundNBT()));
|
||||||
|
compound.put("Level", fluidLevel.writeNBT());
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readNBT(CompoundNBT compound, boolean clientPacket) {
|
||||||
|
tank.readFromNBT(compound.getCompound("TankContent"));
|
||||||
|
fluidLevel.readNBT(compound.getCompound("Level"), clientPacket);
|
||||||
|
if (!tank.getFluid()
|
||||||
|
.isEmpty())
|
||||||
|
renderedFluid = tank.getFluid();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BehaviourType<?> getType() {
|
||||||
|
return behaviourType;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue