Skip to content

Commit

Permalink
Merge pull request #625 from ferriarnus/fluid-rewrite
Browse files Browse the repository at this point in the history
Rewrite our Fluid handling
  • Loading branch information
ferriarnus authored Feb 29, 2024
2 parents 9808934 + bfe1fcd commit 0317177
Show file tree
Hide file tree
Showing 17 changed files with 325 additions and 312 deletions.
1 change: 1 addition & 0 deletions src/core/java/com/enderio/core/CoreNBTKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class CoreNBTKeys {
public static final String ITEMS = "Items";
public static final String FLUID = "Fluid";
public static final String FLUIDS = "Fluids";
public static final String TANKS = "Tanks";
public static final String ENERGY = "Energy";
public static final String BLOCK_ENTITY_TAG = BlockItem.BLOCK_ENTITY_TAG;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.enderio.machines.common.attachment;

import com.enderio.machines.common.MachineNBTKeys;
import com.enderio.machines.common.blockentity.base.MachineBlockEntity;
import com.enderio.machines.common.io.fluid.MachineFluidHandler;
import com.enderio.machines.common.io.fluid.MachineTankLayout;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;

public interface IFluidTankUser {

MachineTankLayout getTankLayout();
MachineFluidHandler getFluidHandler();
MachineFluidHandler createFluidHandler();

default void saveTank(CompoundTag pTag) {
pTag.put(MachineNBTKeys.FLUIDS, getFluidHandler().serializeNBT());
}

default void loadTank(CompoundTag pTag) {
getFluidHandler().deserializeNBT(pTag.getCompound(MachineNBTKeys.FLUIDS));
}

ICapabilityProvider<MachineBlockEntity, Direction, IFluidHandler> FLUID_HANDLER_PROVIDER =
(be, side) ->{
if (be instanceof IFluidTankUser user) {
return user.getFluidHandler().getForSide(side);
}
return null;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
import com.enderio.api.io.IIOConfig;
import com.enderio.api.io.IOMode;
import com.enderio.api.io.energy.EnergyIOMode;
import com.enderio.core.common.network.slot.BooleanNetworkDataSlot;
import com.enderio.core.common.network.slot.CodecNetworkDataSlot;
import com.enderio.core.common.network.slot.FluidStackNetworkDataSlot;
import com.enderio.core.common.network.slot.IntegerNetworkDataSlot;
import com.enderio.machines.common.attachment.ActionRange;
import com.enderio.machines.common.attachment.IFluidTankUser;
import com.enderio.machines.common.attachment.IRangedActor;
import com.enderio.machines.common.blockentity.base.PoweredMachineBlockEntity;
import com.enderio.machines.common.config.MachinesConfig;
Expand All @@ -30,7 +29,6 @@
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
Expand All @@ -43,10 +41,11 @@
import java.util.ArrayList;
import java.util.List;

public class DrainBlockEntity extends PoweredMachineBlockEntity implements IRangedActor {
public class DrainBlockEntity extends PoweredMachineBlockEntity implements IRangedActor, IFluidTankUser {
public static final String CONSUMED = "Consumed";
private static final QuadraticScalable ENERGY_CAPACITY = new QuadraticScalable(CapacitorModifier.ENERGY_CAPACITY, MachinesConfig.COMMON.ENERGY.DRAIN_CAPACITY);
private static final QuadraticScalable ENERGY_USAGE = new QuadraticScalable(CapacitorModifier.ENERGY_USE, MachinesConfig.COMMON.ENERGY.DRAIN_USAGE);
private final MachineFluidHandler fluidHandler;
private static final TankAccess TANK = new TankAccess();
private static final int CAPACITY = 3 * FluidType.BUCKET_VOLUME;
private static final int ENERGY_PER_BUCKET = 1_500;
Expand All @@ -60,6 +59,8 @@ public class DrainBlockEntity extends PoweredMachineBlockEntity implements IRang

public DrainBlockEntity(BlockPos worldPosition, BlockState blockState) {
super(EnergyIOMode.Input, ENERGY_CAPACITY, ENERGY_USAGE, MachineBlockEntities.DRAIN.get(), worldPosition, blockState);
fluidHandler = createFluidHandler();

addDataSlot(new FluidStackNetworkDataSlot(() -> TANK.getFluid(this), fluid -> TANK.setFluid(this, fluid)));

// TODO: rubbish way of having a default. use an interface instead?
Expand Down Expand Up @@ -112,8 +113,13 @@ public MachineFluidTank getFluidTank() {
}

@Override
protected @Nullable MachineFluidHandler createFluidHandler(MachineTankLayout layout) {
return new MachineFluidHandler(getIOConfig(), layout) {
public MachineFluidHandler getFluidHandler() {
return fluidHandler;
}

@Override
public MachineFluidHandler createFluidHandler() {
return new MachineFluidHandler(getIOConfig(), getTankLayout()) {
@Override
protected void onContentsChanged(int slot) {
super.onContentsChanged(slot);
Expand Down Expand Up @@ -235,11 +241,13 @@ public AbstractContainerMenu createMenu(int containerId, Inventory playerInvento
public void saveAdditional(CompoundTag pTag) {
super.saveAdditional(pTag);
pTag.putInt(CONSUMED, consumed);
saveTank(pTag);
}

@Override
public void load(CompoundTag pTag) {
super.load(pTag);
consumed = pTag.getInt(CONSUMED);
loadTank(pTag);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.enderio.base.common.tag.EIOTags;
import com.enderio.base.common.util.ExperienceUtil;
import com.enderio.core.common.network.slot.FluidStackNetworkDataSlot;
import com.enderio.machines.common.attachment.IFluidTankUser;
import com.enderio.machines.common.blockentity.base.MachineBlockEntity;
import com.enderio.machines.common.init.MachineBlockEntities;
import com.enderio.machines.common.init.MachineRecipes;
Expand Down Expand Up @@ -34,6 +35,7 @@
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.FluidType;
import net.neoforged.neoforge.fluids.FluidUtil;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
import org.jetbrains.annotations.Nullable;
Expand All @@ -43,9 +45,7 @@

// TODO: Rewrite this with tasks?
// Could implement a task for each thing it currently has in the If's
public abstract class FluidTankBlockEntity extends MachineBlockEntity implements IFluidItemInteractive {

private static final TankAccess TANK = new TankAccess();
public abstract class FluidTankBlockEntity extends MachineBlockEntity implements IFluidItemInteractive, IFluidTankUser {

public static class Standard extends FluidTankBlockEntity {
public static final int CAPACITY = 16 * FluidType.BUCKET_VOLUME;
Expand All @@ -55,7 +55,7 @@ public Standard(BlockPos worldPosition, BlockState blockState) {
}

@Override
public @Nullable MachineTankLayout getTankLayout() {
public MachineTankLayout getTankLayout() {
return new MachineTankLayout.Builder().tank(TANK, CAPACITY).build();
}
}
Expand All @@ -68,13 +68,15 @@ public Enhanced(BlockPos worldPosition, BlockState blockState) {
}

@Override
public @Nullable MachineTankLayout getTankLayout() {
public MachineTankLayout getTankLayout() {
return new MachineTankLayout.Builder().tank(TANK, CAPACITY).build();
}

}

private final TankRecipe.Container container;
private final MachineFluidHandler fluidHandler;
private static final TankAccess TANK = new TankAccess();

// TODO: Swap from optional to nullable?
private Optional<RecipeHolder<TankRecipe>> currentRecipe = Optional.empty();
Expand All @@ -86,6 +88,7 @@ public Enhanced(BlockPos worldPosition, BlockState blockState) {

public FluidTankBlockEntity(BlockEntityType<?> type, BlockPos worldPosition, BlockState blockState) {
super(type, worldPosition, blockState);
fluidHandler = createFluidHandler();

// Sync fluid for model
addDataSlot(new FluidStackNetworkDataSlot(() -> TANK.getFluid(this), f -> TANK.setFluid(this, f)));
Expand Down Expand Up @@ -181,14 +184,18 @@ protected void onInventoryContentsChanged(int slot) {

// endregion

// region Fluid Storage
@Override
public MachineFluidHandler getFluidHandler() {
return this.fluidHandler;
}

@Override
protected @Nullable MachineFluidHandler createFluidHandler(MachineTankLayout layout) {
return new MachineFluidHandler(getIOConfig(), layout) {
public MachineFluidHandler createFluidHandler() {
return new MachineFluidHandler(getIOConfig(), getTankLayout()) {
@Override
protected void onContentsChanged(int slot) {
onTankContentsChanged();
setChanged();
super.onContentsChanged(slot);
updateMachineState(MachineState.EMPTY_TANK, TANK.getFluidAmount(this) <= 0);
}
Expand All @@ -199,8 +206,6 @@ public MachineFluidTank getFluidTank() {
return TANK.getTank(this);
}

// endregion

//TODO: enable fluid tanks to receive stackable fluid containers
private void fillInternal() {
ItemStack inputItem = FLUID_FILL_INPUT.getItemStack(this);
Expand All @@ -216,18 +221,20 @@ private void fillInternal() {
}
}
} else {
IFluidHandlerItem fluidHandler = inputItem.getCapability(Capabilities.FluidHandler.ITEM);
if (fluidHandler != null && outputItem.isEmpty()) {
int filled = moveFluids(fluidHandler, getFluidHandlerNN(), TANK.getCapacity(this));
IFluidHandlerItem fluidHandlerItem = inputItem.getCapability(Capabilities.FluidHandler.ITEM);
if (fluidHandlerItem != null && outputItem.isEmpty()) {
int filled = FluidUtil.tryFluidTransfer(getFluidHandler(), fluidHandlerItem, TANK.getFluidAmount(this), true).getAmount();
if (filled > 0) {
FLUID_FILL_OUTPUT.setStackInSlot(this, fluidHandler.getContainer());
FLUID_FILL_OUTPUT.setStackInSlot(this, fluidHandlerItem.getContainer());
FLUID_FILL_INPUT.setStackInSlot(this, ItemStack.EMPTY);
}
}
}
}
}

// endregion

@Override
public InteractionResult onBlockEntityUsed(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
ItemStack stack = player.getItemInHand(hand);
Expand Down Expand Up @@ -258,11 +265,11 @@ private void drainInternal() {
}
}
} else {
IFluidHandlerItem fluidHandler = inputItem.getCapability(Capabilities.FluidHandler.ITEM);
if (fluidHandler != null && outputItem.isEmpty()) {
int filled = moveFluids(getFluidHandlerNN(), fluidHandler, TANK.getFluidAmount(this));
IFluidHandlerItem fluidHandlerItem = inputItem.getCapability(Capabilities.FluidHandler.ITEM);
if (fluidHandlerItem != null && outputItem.isEmpty()) {
int filled = FluidUtil.tryFluidTransfer(fluidHandlerItem, getFluidHandler(), TANK.getFluidAmount(this), true).getAmount();
if (filled > 0) {
FLUID_DRAIN_OUTPUT.setStackInSlot(this, fluidHandler.getContainer());
FLUID_DRAIN_OUTPUT.setStackInSlot(this, fluidHandlerItem.getContainer());
FLUID_DRAIN_INPUT.setStackInSlot(this, ItemStack.EMPTY);
}
}
Expand Down Expand Up @@ -352,11 +359,13 @@ public int getLightEmission() {
@Override
public void saveAdditional(CompoundTag pTag) {
super.saveAdditional(pTag);
saveTank(pTag);
}

@Override
public void load(CompoundTag pTag) {
super.load(pTag);
loadTank(pTag);
}

// endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.enderio.base.common.tag.EIOTags;
import com.enderio.base.common.util.ExperienceUtil;
import com.enderio.core.common.network.slot.IntegerNetworkDataSlot;
import com.enderio.machines.common.attachment.IFluidTankUser;
import com.enderio.machines.common.blockentity.base.PoweredMachineBlockEntity;
import com.enderio.machines.common.blockentity.task.PoweredCraftingMachineTask;
import com.enderio.machines.common.blockentity.task.host.CraftingMachineTaskHost;
Expand All @@ -33,19 +34,18 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.neoforged.fml.LogicalSide;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.fml.LogicalSide;
import org.jetbrains.annotations.Nullable;

import java.util.List;

import static com.enderio.base.common.util.ExperienceUtil.EXP_TO_FLUID;

public class SoulBinderBlockEntity extends PoweredMachineBlockEntity {
public class SoulBinderBlockEntity extends PoweredMachineBlockEntity implements IFluidTankUser {

public static final QuadraticScalable CAPACITY = new QuadraticScalable(CapacitorModifier.ENERGY_CAPACITY, MachinesConfig.COMMON.ENERGY.SOUL_BINDER_CAPACITY);
public static final QuadraticScalable USAGE = new QuadraticScalable(CapacitorModifier.ENERGY_USE, MachinesConfig.COMMON.ENERGY.SOUL_BINDER_USAGE);
Expand All @@ -54,6 +54,7 @@ public class SoulBinderBlockEntity extends PoweredMachineBlockEntity {
public static final SingleSlotAccess INPUT_OTHER = new SingleSlotAccess();
public static final MultiSlotAccess OUTPUT = new MultiSlotAccess();
private final SoulBindingRecipe.Container fakeContainer = new SoulBindingRecipe.Container(getInventoryNN(), () -> Integer.MAX_VALUE);
private final MachineFluidHandler fluidHandler;
private static final TankAccess TANK = new TankAccess();
@Nullable private RecipeHolder<SoulBindingRecipe> recipe;
@UseOnly(LogicalSide.CLIENT) private int clientExp = 0;
Expand All @@ -62,6 +63,7 @@ public class SoulBinderBlockEntity extends PoweredMachineBlockEntity {

public SoulBinderBlockEntity(BlockPos worldPosition, BlockState blockState) {
super(EnergyIOMode.Input, CAPACITY, USAGE, MachineBlockEntities.SOUL_BINDER.get(), worldPosition, blockState);
fluidHandler = createFluidHandler();

// Sync fluid amount to client.
addDataSlot(new IntegerNetworkDataSlot(() -> TANK.getFluidAmount(this), i -> TANK.setFluid(this, new FluidStack(EIOFluids.XP_JUICE.getSource(), i))
Expand Down Expand Up @@ -112,11 +114,6 @@ public MachineInventoryLayout getInventoryLayout() {
.build();
}

@Override
public @Nullable MachineTankLayout getTankLayout() {
return MachineTankLayout.builder().tank(TANK, 10000, f -> f.getFluid().is(EIOTags.Fluids.EXPERIENCE)).build();
}

private boolean isValidInput(int index, ItemStack stack) {
return RecipeCaches.SOUL_BINDING.hasRecipe(List.of(stack));
}
Expand All @@ -136,10 +133,14 @@ public int getClientExp() {
}

// region Fluid Storage
@Override
public @Nullable MachineTankLayout getTankLayout() {
return MachineTankLayout.builder().tank(TANK, 10000, f -> f.getFluid().is(EIOTags.Fluids.EXPERIENCE)).build();
}

@Override
protected @Nullable MachineFluidHandler createFluidHandler(MachineTankLayout layout) {
return new MachineFluidHandler(getIOConfig(), layout) {
public MachineFluidHandler createFluidHandler() {
return new MachineFluidHandler(getIOConfig(), getTankLayout()) {
@Override
protected void onContentsChanged(int slot) {
craftingTaskHost.newTaskAvailable();
Expand All @@ -166,6 +167,11 @@ public int fill(FluidStack resource, FluidAction action) {
};
}

@Override
public MachineFluidHandler getFluidHandler() {
return fluidHandler;
}

public MachineFluidTank getFluidTank() {
return TANK.getTank(this);
}
Expand All @@ -192,7 +198,7 @@ protected void consumeInputs(SoulBindingRecipe recipe) {
INPUT_SOUL.getItemStack(getInventory()).shrink(1);
INPUT_OTHER.getItemStack(getInventory()).shrink(1);

MachineFluidHandler handler = getFluidHandlerNN();
MachineFluidHandler handler = getFluidHandler();
int leftover = ExperienceUtil.getLevelFromFluidWithLeftover(TANK.getFluidAmount(handler), 0, recipe.getExpCost()).experience();
TANK.drain(handler, TANK.getFluidAmount(handler) - leftover * EXP_TO_FLUID, IFluidHandler.FluidAction.EXECUTE);
}
Expand All @@ -208,14 +214,15 @@ protected void consumeInputs(SoulBindingRecipe recipe) {
public void saveAdditional(CompoundTag pTag) {
super.saveAdditional(pTag);
craftingTaskHost.save(pTag);
saveTank(pTag);
}

@Override
public void load(CompoundTag pTag) {
super.load(pTag);
craftingTaskHost.load(pTag);
loadTank(pTag);
}

// endregion

}
Loading

0 comments on commit 0317177

Please sign in to comment.