diff --git a/src/core/java/com/enderio/core/CoreNBTKeys.java b/src/core/java/com/enderio/core/CoreNBTKeys.java index 2529f90c64..ed34130843 100644 --- a/src/core/java/com/enderio/core/CoreNBTKeys.java +++ b/src/core/java/com/enderio/core/CoreNBTKeys.java @@ -10,6 +10,7 @@ public class CoreNBTKeys { public static final String ITEM = "Item"; public static final String ITEMS = "Items"; public static final String FLUID = "Fluid"; + public static final String FLUIDS = "Fluids"; public static final String ENERGY = "Energy"; public static final String BLOCK_ENTITY_TAG = BlockItem.BLOCK_ENTITY_TAG; diff --git a/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java b/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java index 933c3e30de..c006b814be 100644 --- a/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java +++ b/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java @@ -18,6 +18,7 @@ import com.enderio.machines.common.block.MachineBlock; import com.enderio.machines.common.io.IOConfig; import com.enderio.machines.common.io.fluid.MachineFluidHandler; +import com.enderio.machines.common.io.fluid.MachineTankLayout; import com.enderio.machines.common.io.item.MachineInventory; import com.enderio.machines.common.io.item.MachineInventoryLayout; import net.minecraft.core.BlockPos; @@ -47,7 +48,6 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; @@ -95,9 +95,6 @@ public abstract class MachineBlockEntity extends EnderBlockEntity implements Men @Nullable private final MachineInventory inventory; - @Nullable - private final FluidTank fluidTank; - @Nullable private final MachineFluidHandler fluidHandler; @@ -133,9 +130,9 @@ public MachineBlockEntity(BlockEntityType type, BlockPos worldPosition, Block } // Create fluid storage - fluidTank = createFluidTank(); - if (fluidTank != null) { - fluidHandler = createFluidHandler(fluidTank); + MachineTankLayout tankLayout = getTankLayout(); + if (tankLayout != null) { + fluidHandler = createFluidHandler(tankLayout); if (fluidHandler != null) { addCapabilityProvider(fluidHandler); } @@ -381,30 +378,40 @@ protected void onInventoryContentsChanged(int slot) { } // endregion // region Fluid Storage - @Nullable - protected FluidTank createFluidTank() { + public MachineTankLayout getTankLayout() { return null; } @Nullable - public final FluidTank getFluidTank() { - return fluidTank; + public final MachineFluidHandler getFluidHandler() { + return fluidHandler; } /** - * Only call this if you're sure your machine has a fluid tank. + * Only call this if you're sure your machine has an tank. */ - protected final FluidTank getFluidTankNN() { - return Objects.requireNonNull(fluidTank); + protected final MachineFluidHandler getFluidHandlerNN() { + return Objects.requireNonNull(fluidHandler); } @Nullable - protected MachineFluidHandler createFluidHandler(FluidTank fluidTank) { - // We can have a default here, as if createFluidTank returns null, this is never called. - return new MachineFluidHandler(getIOConfig(), fluidTank); + protected MachineFluidHandler createFluidHandler(MachineTankLayout layout) { + return new MachineFluidHandler(getIOConfig(), layout) { + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + onTankContentsChanged(slot); + setChanged(); + } + }; } + /** + * @apiNote Must call this on custom MachineFluid handlers! + */ + protected void onTankContentsChanged(int slot) {} + // endregion // region Block Entity ticking @@ -652,8 +659,8 @@ public void saveAdditional(CompoundTag pTag) { pTag.put(MachineNBTKeys.ITEMS, inventory.serializeNBT()); } - if (fluidTank != null) { - pTag.put(MachineNBTKeys.FLUID, fluidTank.writeToNBT(new CompoundTag())); + if (this.fluidHandler != null) { + pTag.put(MachineNBTKeys.FLUID, fluidHandler.serializeNBT()); } if (getMaxRange() > 0) { @@ -675,8 +682,8 @@ public void load(CompoundTag pTag) { inventory.deserializeNBT(pTag.getCompound(MachineNBTKeys.ITEMS)); } - if (fluidTank != null) { - fluidTank.readFromNBT(pTag.getCompound(MachineNBTKeys.FLUID)); + if (this.fluidHandler != null) { + fluidHandler.deserializeNBT(pTag.getCompound(MachineNBTKeys.FLUIDS)); } // For rendering io overlays after placed by an nbt filled block item diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java index 3d2e6945c8..ade914aca7 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java @@ -3,8 +3,13 @@ import com.enderio.api.capability.IEnderCapabilityProvider; import com.enderio.api.io.IIOConfig; import net.minecraft.core.Direction; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; @@ -18,10 +23,10 @@ /** * MachineFluidStorage takes a list of fluid tanks and handles IO for them all. */ -public class MachineFluidHandler implements IFluidHandler, IEnderCapabilityProvider { +public class MachineFluidHandler implements IFluidHandler, IEnderCapabilityProvider, INBTSerializable { private final IIOConfig config; private final MachineTankLayout layout; - private final List tanks; + private List tanks; private final EnumMap> sideCache = new EnumMap<>(Direction.class); private LazyOptional selfCache = LazyOptional.empty(); @@ -69,7 +74,7 @@ public int getTankCapacity(int tank) { @Override public boolean isFluidValid(int tank, FluidStack stack) { - return tanks.get(tank).isFluidValid(stack); + return layout.isFluidValid(tank, stack); } @Override @@ -163,6 +168,35 @@ public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; } + protected void onContentsChanged(int slot) {} + + @Override + public CompoundTag serializeNBT() { + ListTag nbtTagList = new ListTag(); + for (int i = 0; i < tanks.size(); i++) { + CompoundTag tankTag = new CompoundTag(); + tankTag.putInt("Index", i); + tanks.get(i).save(tankTag); + nbtTagList.add(tankTag); + } + CompoundTag nbt = new CompoundTag(); + nbt.put("Tanks", nbtTagList); + nbt.putInt("Size", tanks.size()); + return nbt; + } + + @Override + public void deserializeNBT(CompoundTag nbt) { + int size = nbt.contains("Size", Tag.TAG_INT) ? nbt.getInt("Size") : tanks.size(); + tanks = NonNullList.withSize(size, MachineTank.EMPTY); + ListTag tagList = nbt.getList("Tanks", Tag.TAG_COMPOUND); + for (int i = 0; i < tagList.size(); i++) { + CompoundTag tankTag = tagList.getCompound(i); + int index = tankTag.getInt("Index"); + tanks.set(index, MachineTank.from(tankTag)); + } + } + // Sided capability access private static class Sided implements IFluidHandler { diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java index 24cf522c25..4d3bb9ff89 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java @@ -1,30 +1,39 @@ package com.enderio.machines.common.io.fluid; +import net.minecraft.nbt.CompoundTag; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.IFluidHandler; import org.jetbrains.annotations.NotNull; -import java.util.function.Predicate; - //Replace MachineFluidTank public class MachineTank implements IFluidTank { private final int capacity; - private final Predicate validator; - private boolean canInsert; - private boolean canExtract; @NotNull private FluidStack fluid = FluidStack.EMPTY; + public static final MachineTank EMPTY = new MachineTank(0, true, true); - public MachineTank(int capacity, Predicate validator, boolean canInsert, boolean canExtract) { + public MachineTank(int capacity, boolean canInsert, boolean canExtract) { this.capacity = capacity; - this.validator = validator; this.canInsert = canInsert; this.canExtract = canExtract; } + public MachineTank(FluidStack stack, int capacity, boolean canInsert, boolean canExtract) { + this(capacity, canInsert, canExtract); + this.fluid = stack.copy(); + } + + public static MachineTank from(CompoundTag tag) { + FluidStack stack = FluidStack.loadFluidStackFromNBT(tag); + int capacity = tag.getInt("Capacity"); + boolean canInsert = tag.getBoolean("CanInsert"); + boolean canExtract = tag.getBoolean("CanExtract"); + return new MachineTank(stack, capacity, canInsert, canExtract); + } + @Override public int getCapacity() { return capacity; @@ -42,11 +51,11 @@ public int getFluidAmount() { @Override public boolean isFluidValid(FluidStack stack) { - return validator.test(stack); + return true; } public int fill(FluidStack resource, IFluidHandler.FluidAction action) { - if (!canInsert || resource.isEmpty() || !isFluidValid(resource)) { + if (!canInsert || resource.isEmpty()) { return 0; } if (action.simulate()) { @@ -103,8 +112,14 @@ public FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) { return stack; } - protected void onContentsChanged() { + protected void onContentsChanged() {} + public CompoundTag save(CompoundTag compoundTag) { + getFluid().writeToNBT(compoundTag); + compoundTag.putInt("Capacity", getCapacity()); + compoundTag.putBoolean("CanInsert", canInsert); + compoundTag.putBoolean("CanExtract", canExtract); + return compoundTag; } } diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java index e30792693f..a75ea7a759 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java @@ -47,7 +47,7 @@ public boolean isFluidValid(int slot, FluidStack stack) { public List createTanks() { List tankList = new ArrayList<>(); tanks.forEach((config -> { - tankList.add(new MachineTank(config.capacity, config.filter, config.insert, config.extract)); + tankList.add(new MachineTank(config.capacity, config.insert, config.extract)); })); return tankList; } diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/TankAccess.java b/src/machines/java/com/enderio/machines/common/io/fluid/TankAccess.java index 86256c00d8..74c4b02577 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/TankAccess.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/TankAccess.java @@ -1,9 +1,53 @@ package com.enderio.machines.common.io.fluid; +import com.enderio.machines.common.blockentity.base.MachineBlockEntity; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; + public class TankAccess { private int index = Integer.MIN_VALUE; + public FluidStack getFluid(MachineBlockEntity blockEntity) { + return getFluid(blockEntity.getFluidHandler()); + } + + public FluidStack getFluid(MachineFluidHandler handler) { + return handler.getFluidInTank(index); + } + + public int fill(MachineFluidHandler handler, FluidStack stack, IFluidHandler.FluidAction action) { + return handler.fill(stack, action); + } + + public int fill(MachineBlockEntity machine, FluidStack stack, IFluidHandler.FluidAction action) { + return fill(machine.getFluidHandler(), stack, action); + } + + public FluidStack drain(MachineFluidHandler handler, FluidStack resource, IFluidHandler.FluidAction action) { + return handler.drain(resource, action); + } + + public FluidStack drain(MachineBlockEntity machine, FluidStack resource, IFluidHandler.FluidAction action) { + return drain(machine.getFluidHandler(), resource, action); + } + + public FluidStack drain(MachineFluidHandler handler, int maxDrain, IFluidHandler.FluidAction action) { + return handler.drain(maxDrain, action); + } + + public FluidStack drain(MachineBlockEntity machine, int maxDrain, IFluidHandler.FluidAction action) { + return drain(machine.getFluidHandler(), maxDrain, action); + } + + public boolean isSlot(int slot) { + return this.index == slot; + } + + public int getIndex() { + return index; + } + void init(int i) { if (index == Integer.MIN_VALUE) { index = i;