pipes (not done for fabric) and tank (maybe for fabric?)
This commit is contained in:
@@ -7,6 +7,7 @@ import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.item.ModCreativeTabs;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.networking.ModPackets;
|
||||
import net.cmr.jurassicrevived.platform.Services;
|
||||
import net.cmr.jurassicrevived.recipe.ModRecipes;
|
||||
import net.cmr.jurassicrevived.screen.ModMenuTypes;
|
||||
@@ -68,5 +69,6 @@ public class CommonClass
|
||||
ModEvents.init();
|
||||
|
||||
ModSounds.register();
|
||||
ModPackets.register();
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.block.entity.custom.PipeBlockEntity;
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyUtil;
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.platform.Services;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
@@ -198,6 +199,15 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
};
|
||||
}
|
||||
|
||||
if (level instanceof Level lvl) {
|
||||
boolean platformHasHandler = switch (this.transport) {
|
||||
case ITEMS -> Services.TRANSFER.getItemHandler(lvl, neighborPos, dir.getOpposite()).isPresent();
|
||||
case FLUIDS -> Services.TRANSFER.getFluidHandler(lvl, neighborPos, dir.getOpposite()).isPresent();
|
||||
case ENERGY -> Services.TRANSFER.getEnergyHandler(lvl, neighborPos, dir.getOpposite()).isPresent();
|
||||
};
|
||||
hasCommonConnection = hasCommonConnection || platformHasHandler;
|
||||
}
|
||||
|
||||
if (hasCommonConnection) {
|
||||
if (existing == ConnectionType.CONNECTOR_PULL) {
|
||||
return ConnectionType.CONNECTOR_PULL;
|
||||
@@ -352,14 +362,14 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
}
|
||||
|
||||
public int getMaxItemsPerTick() {
|
||||
return Math.max(0, JRConfigManager.get().itemsPerSecond / 20);
|
||||
return Math.max(1, JRConfigManager.get().itemsPerSecond / 20);
|
||||
}
|
||||
|
||||
public int getMaxFluidPerTick() {
|
||||
return Math.max(0, JRConfigManager.get().milliBucketsPerSecond / 20);
|
||||
return Math.max(1, JRConfigManager.get().milliBucketsPerSecond / 20);
|
||||
}
|
||||
|
||||
public int getMaxEnergyPerTick() {
|
||||
return Math.max(0, JRConfigManager.get().fePerSecond / 20);
|
||||
return Math.max(1, JRConfigManager.get().fePerSecond / 20);
|
||||
}
|
||||
}
|
||||
+176
-53
@@ -1,11 +1,16 @@
|
||||
package net.cmr.jurassicrevived.block.entity.custom;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.block.custom.PipeBlock;
|
||||
import net.cmr.jurassicrevived.block.custom.PipeBlock.ConnectionType;
|
||||
import net.cmr.jurassicrevived.block.custom.PipeBlock.Transport;
|
||||
import net.cmr.jurassicrevived.block.entity.ModBlockEntities;
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyStorage;
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyUtil;
|
||||
import net.cmr.jurassicrevived.platform.Services;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformEnergyHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformFluidHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformItemHandler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.Container;
|
||||
@@ -16,7 +21,8 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PipeBlockEntity extends BlockEntity {
|
||||
public class PipeBlockEntity extends BlockEntity
|
||||
{
|
||||
|
||||
private final Transport transport;
|
||||
|
||||
@@ -39,9 +45,8 @@ public class PipeBlockEntity extends BlockEntity {
|
||||
|
||||
PipeBlock block = (PipeBlock) state.getBlock();
|
||||
int itemCap = block.getMaxItemsPerTick();
|
||||
// Fallback caps if Config is not ready
|
||||
int fluidCap = 1000;
|
||||
int energyCap = 1000;
|
||||
int fluidCap = block.getMaxFluidPerTick();
|
||||
int energyCap = block.getMaxEnergyPerTick();
|
||||
|
||||
switch (be.transport) {
|
||||
case ITEMS -> transferItems(level, pos, state, itemCap);
|
||||
@@ -52,9 +57,12 @@ public class PipeBlockEntity extends BlockEntity {
|
||||
|
||||
// ===== Network discovery =====
|
||||
|
||||
private record PipeEndpoint(BlockPos pipePos, Direction side) {}
|
||||
private record PipeEndpoint(BlockPos pipePos, Direction side)
|
||||
{
|
||||
}
|
||||
|
||||
private static class Network {
|
||||
private static class Network
|
||||
{
|
||||
final List<PipeEndpoint> sources = new ArrayList<>();
|
||||
final List<PipeEndpoint> sinks = new ArrayList<>();
|
||||
}
|
||||
@@ -99,73 +107,188 @@ public class PipeBlockEntity extends BlockEntity {
|
||||
|
||||
private static void transferItems(Level level, BlockPos pos, BlockState state, int perTickLimit) {
|
||||
Network net = discoverNetwork(level, pos, Transport.ITEMS);
|
||||
List<Container> outputs = new ArrayList<>();
|
||||
for (PipeEndpoint ep : net.sinks) {
|
||||
BlockEntity be = level.getBlockEntity(ep.pipePos.relative(ep.side));
|
||||
if (be instanceof Container c) outputs.add(c);
|
||||
}
|
||||
if (outputs.isEmpty()) return;
|
||||
if (net.sources.isEmpty() || net.sinks.isEmpty()) return;
|
||||
|
||||
Map<BlockPos, List<PipeEndpoint>> sinksByPipe = indexSinksByPipe(net.sinks);
|
||||
|
||||
int remaining = perTickLimit;
|
||||
for (PipeEndpoint ep : net.sources) {
|
||||
for (PipeEndpoint srcEp : net.sources) {
|
||||
if (remaining <= 0) break;
|
||||
BlockEntity be = level.getBlockEntity(ep.pipePos.relative(ep.side));
|
||||
if (!(be instanceof Container src)) continue;
|
||||
|
||||
for (int i = 0; i < src.getContainerSize() && remaining > 0; i++) {
|
||||
ItemStack stack = src.getItem(i);
|
||||
if (stack.isEmpty()) continue;
|
||||
BlockPos srcPos = srcEp.pipePos.relative(srcEp.side);
|
||||
Direction srcSide = srcEp.side.getOpposite();
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
toMove.setCount(Math.min(stack.getCount(), remaining));
|
||||
PlatformItemHandler src = Services.TRANSFER
|
||||
.getItemHandler(level, srcPos, srcSide)
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
for (Container out : outputs) {
|
||||
// Logic to insert into vanilla container (simplified)
|
||||
// You might want a helper for this
|
||||
}
|
||||
}
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.ITEMS);
|
||||
if (sinkEp == null) continue;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformItemHandler dst = Services.TRANSFER
|
||||
.getItemHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
remaining = moveFromSourceToSingleTarget(src, dst, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Energy Transfer (Using Custom Energy System) =====
|
||||
private static PipeEndpoint findNearestSink(
|
||||
Level level,
|
||||
BlockPos startPipe,
|
||||
Map<BlockPos, List<PipeEndpoint>> sinksByPipe,
|
||||
Transport transport
|
||||
) {
|
||||
ArrayDeque<BlockPos> q = new ArrayDeque<>();
|
||||
HashSet<BlockPos> seen = new HashSet<>();
|
||||
q.add(startPipe);
|
||||
seen.add(startPipe);
|
||||
|
||||
while (!q.isEmpty()) {
|
||||
BlockPos p = q.removeFirst();
|
||||
|
||||
List<PipeEndpoint> sinksHere = sinksByPipe.get(p);
|
||||
if (sinksHere != null && !sinksHere.isEmpty()) {
|
||||
return sinksHere.get(0);
|
||||
}
|
||||
|
||||
BlockState st = level.getBlockState(p);
|
||||
if (!(st.getBlock() instanceof PipeBlock pb) || pb.getTransport() != transport) continue;
|
||||
|
||||
for (Direction d : Direction.values()) {
|
||||
if (st.getValue(PipeBlock.getProp(d)) == ConnectionType.PIPE) {
|
||||
BlockPos np = p.relative(d);
|
||||
if (seen.add(np)) q.add(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void transferEnergy(Level level, BlockPos pos, BlockState state, int perTickLimit) {
|
||||
Network net = discoverNetwork(level, pos, Transport.ENERGY);
|
||||
List<ModEnergyStorage> outputs = new ArrayList<>();
|
||||
for (PipeEndpoint ep : net.sinks) {
|
||||
BlockEntity be = level.getBlockEntity(ep.pipePos.relative(ep.side));
|
||||
if (be instanceof ModEnergyUtil.EnergyProvider provider) {
|
||||
ModEnergyStorage storage = provider.getEnergyStorage(ep.side.getOpposite());
|
||||
if (storage != null && storage.canReceive()) outputs.add(storage);
|
||||
}
|
||||
}
|
||||
if (outputs.isEmpty()) return;
|
||||
if (net.sources.isEmpty() || net.sinks.isEmpty()) return;
|
||||
|
||||
Map<BlockPos, List<PipeEndpoint>> sinksByPipe = indexSinksByPipe(net.sinks);
|
||||
|
||||
int remaining = perTickLimit;
|
||||
for (PipeEndpoint ep : net.sources) {
|
||||
for (PipeEndpoint srcEp : net.sources) {
|
||||
if (remaining <= 0) break;
|
||||
BlockEntity be = level.getBlockEntity(ep.pipePos.relative(ep.side));
|
||||
if (be instanceof ModEnergyUtil.EnergyProvider provider) {
|
||||
ModEnergyStorage src = provider.getEnergyStorage(ep.side.getOpposite());
|
||||
if (src == null || !src.canExtract()) continue;
|
||||
|
||||
int canExtract = src.extractEnergy(remaining, true);
|
||||
if (canExtract <= 0) continue;
|
||||
BlockPos srcPos = srcEp.pipePos.relative(srcEp.side);
|
||||
Direction srcSide = srcEp.side.getOpposite();
|
||||
|
||||
for (ModEnergyStorage out : outputs) {
|
||||
int accepted = out.receiveEnergy(canExtract, true);
|
||||
if (accepted > 0) {
|
||||
int actuallyExtracted = src.extractEnergy(accepted, false);
|
||||
out.receiveEnergy(actuallyExtracted, false);
|
||||
remaining -= actuallyExtracted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PlatformEnergyHandler src = Services.TRANSFER
|
||||
.getEnergyHandler(level, srcPos, srcSide)
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.ENERGY);
|
||||
if (sinkEp == null) continue;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformEnergyHandler dst = Services.TRANSFER
|
||||
.getEnergyHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
int available = src.extract(remaining, true);
|
||||
if (available <= 0) continue;
|
||||
|
||||
int accepted = dst.insert(available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
int extracted = src.extract(accepted, false);
|
||||
int inserted = dst.insert(extracted, false);
|
||||
remaining -= inserted;
|
||||
}
|
||||
}
|
||||
|
||||
private static void transferFluids(Level level, BlockPos pos, BlockState state, int perTickLimit) {
|
||||
// Implementation would use Architectury FluidStack similarly to energy
|
||||
Network net = discoverNetwork(level, pos, Transport.FLUIDS);
|
||||
if (net.sources.isEmpty() || net.sinks.isEmpty()) return;
|
||||
|
||||
Map<BlockPos, List<PipeEndpoint>> sinksByPipe = indexSinksByPipe(net.sinks);
|
||||
|
||||
long remaining = perTickLimit;
|
||||
for (PipeEndpoint srcEp : net.sources) {
|
||||
if (remaining <= 0) break;
|
||||
|
||||
BlockPos srcPos = srcEp.pipePos.relative(srcEp.side);
|
||||
Direction srcSide = srcEp.side.getOpposite();
|
||||
|
||||
PlatformFluidHandler src = Services.TRANSFER
|
||||
.getFluidHandler(level, srcPos, srcSide)
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.FLUIDS);
|
||||
if (sinkEp == null) continue;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformFluidHandler dst = Services.TRANSFER
|
||||
.getFluidHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
for (FluidStack candidate : src.getExtractableFluids()) {
|
||||
if (candidate.isEmpty()) continue;
|
||||
|
||||
long available = src.extract(candidate, remaining, true);
|
||||
if (available <= 0) continue;
|
||||
|
||||
long accepted = dst.insert(candidate, available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
FluidStack toMove = candidate.copy();
|
||||
toMove.setAmount(accepted);
|
||||
|
||||
long extracted = src.extract(toMove, accepted, false);
|
||||
long inserted = dst.insert(toMove, extracted, false);
|
||||
remaining -= inserted;
|
||||
|
||||
if (remaining <= 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<BlockPos, List<PipeEndpoint>> indexSinksByPipe(List<PipeEndpoint> sinks) {
|
||||
Map<BlockPos, List<PipeEndpoint>> map = new HashMap<>();
|
||||
for (PipeEndpoint ep : sinks) {
|
||||
map.computeIfAbsent(ep.pipePos, k -> new ArrayList<>()).add(ep);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static int moveFromSourceToSingleTarget(PlatformItemHandler src, PlatformItemHandler dst, int limit) {
|
||||
int remaining = limit;
|
||||
|
||||
for (ItemStack candidate : src.getExtractableStacks()) {
|
||||
if (candidate.isEmpty()) continue;
|
||||
|
||||
int available = src.extract(candidate, remaining, true);
|
||||
if (available <= 0) continue;
|
||||
|
||||
int accepted = dst.insert(candidate, available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
int extracted = src.extract(candidate, accepted, false);
|
||||
if (extracted <= 0) continue;
|
||||
|
||||
int inserted = dst.insert(candidate, extracted, false);
|
||||
remaining -= inserted;
|
||||
|
||||
if (remaining <= 0) break;
|
||||
}
|
||||
return remaining;
|
||||
}
|
||||
}
|
||||
+213
-8
@@ -3,19 +3,29 @@ package net.cmr.jurassicrevived.block.entity.custom;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.registry.menu.ExtendedMenuProvider;
|
||||
import net.cmr.jurassicrevived.block.entity.ModBlockEntities;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidProvider;
|
||||
import net.cmr.jurassicrevived.screen.custom.TankMenu;
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.platform.Services;
|
||||
import net.cmr.jurassicrevived.platform.services.IItemFluidHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -25,7 +35,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/*import net.minecraft.core.HolderLookup;
|
||||
*///?}
|
||||
|
||||
public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider {
|
||||
public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider, InternalFluidProvider {
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(2) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -46,6 +56,66 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
private FluidStack fluidStack = FluidStack.empty();
|
||||
private static final long CAPACITY = 64000;
|
||||
|
||||
public TankFluidHandler getTank(@Nullable Direction side) {
|
||||
return tank;
|
||||
}
|
||||
|
||||
private final TankFluidHandler tank = new TankFluidHandler();
|
||||
|
||||
@Override
|
||||
public InternalFluidHandler getFluidHandler(@Nullable Direction side) {
|
||||
return tank;
|
||||
}
|
||||
|
||||
public class TankFluidHandler implements InternalFluidHandler {
|
||||
@Override
|
||||
public FluidStack getFluid() {
|
||||
return fluidStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCapacity() {
|
||||
return CAPACITY;
|
||||
}
|
||||
|
||||
public long fill(FluidStack stack, boolean simulate) {
|
||||
if (stack.isEmpty()) return 0;
|
||||
if (!fluidStack.isEmpty() && fluidStack.getFluid() != stack.getFluid()) return 0;
|
||||
|
||||
long space = CAPACITY - fluidStack.getAmount();
|
||||
if (space <= 0) return 0;
|
||||
|
||||
long toFill = Math.min(space, stack.getAmount());
|
||||
if (!simulate) {
|
||||
fluidStack = FluidStack.create(stack.getFluid(), fluidStack.getAmount() + toFill);
|
||||
setChanged();
|
||||
if (level != null && !level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
return toFill;
|
||||
}
|
||||
|
||||
public FluidStack drain(long amount, boolean simulate) {
|
||||
if (fluidStack.isEmpty() || amount <= 0) return FluidStack.empty();
|
||||
|
||||
long drained = Math.min(amount, fluidStack.getAmount());
|
||||
FluidStack out = FluidStack.create(fluidStack.getFluid(), drained);
|
||||
|
||||
if (!simulate) {
|
||||
long remaining = fluidStack.getAmount() - drained;
|
||||
fluidStack = remaining > 0
|
||||
? FluidStack.create(fluidStack.getFluid(), remaining)
|
||||
: FluidStack.empty();
|
||||
setChanged();
|
||||
if (level != null && !level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
public TankBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.TANK_BE.get(), pos, blockState);
|
||||
}
|
||||
@@ -83,6 +153,112 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
}
|
||||
|
||||
public void tick(Level level, BlockPos blockPos, BlockState blockState) {
|
||||
if (level.isClientSide) return;
|
||||
|
||||
ItemStack input = itemHandler.getItem(0);
|
||||
if (input.isEmpty()) return;
|
||||
|
||||
ItemStack output = itemHandler.getItem(1);
|
||||
|
||||
long rate = Math.max(1, JRConfigManager.get().milliBucketsPerSecond / 20);
|
||||
IItemFluidHelper helper = Services.ITEM_FLUID;
|
||||
|
||||
ItemStack inputOne = input.copy();
|
||||
inputOne.setCount(1);
|
||||
|
||||
var containedOpt = helper.getContainedFluid(inputOne);
|
||||
|
||||
if (containedOpt.isPresent() && !containedOpt.get().isEmpty()) {
|
||||
FluidStack contained = containedOpt.get();
|
||||
long canFill = tank.fill(contained, true);
|
||||
long toDrain = Math.min(rate, canFill);
|
||||
if (toDrain <= 0) return;
|
||||
|
||||
IItemFluidHelper.TransferResult drained = helper.drain(inputOne, toDrain, false);
|
||||
|
||||
// If partial drain failed (amount 0), and we requested less than full capacity, try requesting full capacity
|
||||
if (drained.amount() == 0 && toDrain < canFill) {
|
||||
drained = helper.drain(inputOne, canFill, false);
|
||||
}
|
||||
|
||||
if (drained.amount() > 0) {
|
||||
ItemStack resultStack = drained.stack();
|
||||
boolean emptyNow = helper.getContainedFluid(resultStack)
|
||||
.map(FluidStack::isEmpty)
|
||||
.orElse(true);
|
||||
|
||||
if (emptyNow) {
|
||||
if (canMoveToOutput(resultStack, output)) {
|
||||
tank.fill(FluidStack.create(contained.getFluid(), drained.amount()), false);
|
||||
input.shrink(1);
|
||||
if (input.isEmpty()) {
|
||||
itemHandler.setItem(0, ItemStack.EMPTY);
|
||||
} else {
|
||||
itemHandler.setChanged();
|
||||
}
|
||||
addToOutput(resultStack, output);
|
||||
}
|
||||
} else {
|
||||
if (input.getCount() == 1) {
|
||||
tank.fill(FluidStack.create(contained.getFluid(), drained.amount()), false);
|
||||
itemHandler.setItem(0, resultStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FluidStack tankFluid = tank.getFluid();
|
||||
if (tankFluid.isEmpty()) return;
|
||||
|
||||
long toFill = Math.min(rate, tankFluid.getAmount());
|
||||
IItemFluidHelper.TransferResult filled = helper.fill(inputOne, tankFluid, toFill, false);
|
||||
|
||||
// If partial fill failed, and we requested less than available fluid, try requesting more
|
||||
if (filled.amount() == 0 && toFill < tankFluid.getAmount()) {
|
||||
filled = helper.fill(inputOne, tankFluid, tankFluid.getAmount(), false);
|
||||
}
|
||||
|
||||
if (filled.amount() > 0) {
|
||||
ItemStack resultStack = filled.stack();
|
||||
boolean fullNow = helper.fill(resultStack, tankFluid, 1, true).amount() == 0;
|
||||
boolean tankWillBeEmpty = tankFluid.getAmount() - filled.amount() <= 0;
|
||||
|
||||
if (fullNow || tankWillBeEmpty) {
|
||||
if (canMoveToOutput(resultStack, output)) {
|
||||
tank.drain(filled.amount(), false);
|
||||
input.shrink(1);
|
||||
if (input.isEmpty()) {
|
||||
itemHandler.setItem(0, ItemStack.EMPTY);
|
||||
} else {
|
||||
itemHandler.setChanged();
|
||||
}
|
||||
addToOutput(resultStack, output);
|
||||
}
|
||||
} else {
|
||||
if (input.getCount() == 1) {
|
||||
tank.drain(filled.amount(), false);
|
||||
itemHandler.setItem(0, resultStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canMoveToOutput(ItemStack result, ItemStack output) {
|
||||
if (output.isEmpty()) return true;
|
||||
//? if >1.20.1 {
|
||||
/*return ItemStack.isSameItemSameComponents(result, output) && output.getCount() + result.getCount() <= output.getMaxStackSize();
|
||||
*///?} else {
|
||||
return ItemStack.isSameItemSameTags(result, output) && output.getCount() + result.getCount() <= output.getMaxStackSize();
|
||||
//?}
|
||||
}
|
||||
|
||||
private void addToOutput(ItemStack result, ItemStack output) {
|
||||
if (output.isEmpty()) {
|
||||
itemHandler.setItem(1, result);
|
||||
} else {
|
||||
output.grow(result.getCount());
|
||||
itemHandler.setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmptyForDrop() {
|
||||
@@ -94,9 +270,18 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) {
|
||||
super.saveAdditional(pTag, pRegistries);
|
||||
pTag.put("Inventory", itemHandler.createTag(pRegistries));
|
||||
CompoundTag fluidTag = new CompoundTag();
|
||||
fluidStack.write(pRegistries, fluidTag);
|
||||
pTag.put("Fluid", fluidTag);
|
||||
if (!fluidStack.isEmpty()) {
|
||||
// Manually save fluid stack to avoid issues with Architectury's default serialization
|
||||
CompoundTag fluidTag = new CompoundTag();
|
||||
fluidTag.putString("id", BuiltInRegistries.FLUID.getKey(fluidStack.getFluid()).toString());
|
||||
fluidTag.putLong("amount", fluidStack.getAmount());
|
||||
if (fluidStack.getPatch() != null && !fluidStack.getPatch().isEmpty()) {
|
||||
// Fallback to standard save if components are present
|
||||
pTag.put("Fluid", FluidStack.CODEC.encodeStart(NbtOps.INSTANCE, fluidStack).getOrThrow());
|
||||
} else {
|
||||
pTag.put("Fluid", fluidTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,7 +289,23 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
super.loadAdditional(pTag, pRegistries);
|
||||
itemHandler.fromTag(pTag.getList("Inventory", 10), pRegistries);
|
||||
if (pTag.contains("Fluid")) {
|
||||
this.fluidStack = FluidStack.read(pRegistries, pTag.getCompound("Fluid")).orElse(FluidStack.empty());
|
||||
CompoundTag fluidTag = pTag.getCompound("Fluid");
|
||||
if (fluidTag.contains("id") && fluidTag.contains("amount")) {
|
||||
// Manual load
|
||||
try {
|
||||
// Use ResourceLocation.parse for 1.21.1
|
||||
net.minecraft.world.level.material.Fluid fluid = BuiltInRegistries.FLUID.get(ResourceLocation.parse(fluidTag.getString("id")));
|
||||
long amount = fluidTag.getLong("amount");
|
||||
this.fluidStack = FluidStack.create(fluid, amount);
|
||||
} catch (Exception e) {
|
||||
this.fluidStack = FluidStack.empty();
|
||||
}
|
||||
} else {
|
||||
// Standard load
|
||||
this.fluidStack = FluidStack.CODEC.parse(NbtOps.INSTANCE, fluidTag).result().orElse(FluidStack.empty());
|
||||
}
|
||||
} else {
|
||||
this.fluidStack = FluidStack.empty();
|
||||
}
|
||||
}
|
||||
*///?} else {
|
||||
@@ -112,9 +313,11 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
protected void saveAdditional(CompoundTag pTag) {
|
||||
super.saveAdditional(pTag);
|
||||
pTag.put("Inventory", itemHandler.createTag());
|
||||
CompoundTag fluidTag = new CompoundTag();
|
||||
fluidStack.write(fluidTag);
|
||||
pTag.put("Fluid", fluidTag);
|
||||
if (!fluidStack.isEmpty()) {
|
||||
CompoundTag fluidTag = new CompoundTag();
|
||||
fluidStack.write(fluidTag);
|
||||
pTag.put("Fluid", fluidTag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,6 +326,8 @@ public class TankBlockEntity extends BlockEntity implements ExtendedMenuProvider
|
||||
itemHandler.fromTag(pTag.getList("Inventory", 10));
|
||||
if (pTag.contains("Fluid")) {
|
||||
this.fluidStack = FluidStack.read(pTag.getCompound("Fluid"));
|
||||
} else {
|
||||
this.fluidStack = FluidStack.empty();
|
||||
}
|
||||
}
|
||||
//?}
|
||||
|
||||
@@ -6,7 +6,7 @@ public final class JRConfig {
|
||||
public int spawnWeight = 10;
|
||||
public boolean requirePower = true;
|
||||
public int fePerSecond = 1000;
|
||||
public int itemsPerSecond = 10;
|
||||
public int itemsPerSecond = 100;
|
||||
public int milliBucketsPerSecond = 1000;
|
||||
|
||||
public JRConfig() {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package net.cmr.jurassicrevived.networking;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.screen.custom.TankMenu;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
//? if >1.20.1 {
|
||||
/*import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
*///?}
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
|
||||
public class ModPackets {
|
||||
public static final ResourceLocation TANK_SYNC = Constants.rl("tank_sync");
|
||||
|
||||
public static void register() {
|
||||
//? if >1.20.1 {
|
||||
/*NetworkManager.registerReceiver(NetworkManager.Side.S2C, TANK_SYNC_TYPE, TANK_SYNC_STREAM_CODEC, (payload, context) -> {
|
||||
FluidStack fluidStack = payload.fluidStack();
|
||||
context.queue(() -> {
|
||||
Player player = context.getPlayer();
|
||||
if (player != null) {
|
||||
AbstractContainerMenu menu = player.containerMenu;
|
||||
if (menu instanceof TankMenu tankMenu) {
|
||||
tankMenu.setFluid(fluidStack);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
*///?} else {
|
||||
NetworkManager.registerReceiver(NetworkManager.Side.S2C, TANK_SYNC, (buf, context) -> {
|
||||
FluidStack fluidStack = FluidStack.read(buf);
|
||||
context.queue(() -> {
|
||||
Player player = context.getPlayer();
|
||||
if (player != null) {
|
||||
AbstractContainerMenu menu = player.containerMenu;
|
||||
if (menu instanceof TankMenu tankMenu) {
|
||||
tankMenu.setFluid(fluidStack);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
//?}
|
||||
}
|
||||
|
||||
public static void sendTankSync(ServerPlayer player, FluidStack fluidStack) {
|
||||
//? if >1.20.1 {
|
||||
/*NetworkManager.sendToPlayer(player, new TankSyncPayload(fluidStack));
|
||||
*///?} else {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
fluidStack.write(buf);
|
||||
NetworkManager.sendToPlayer(player, TANK_SYNC, buf);
|
||||
//?}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*public static final CustomPacketPayload.Type<TankSyncPayload> TANK_SYNC_TYPE = new CustomPacketPayload.Type<>(TANK_SYNC);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, TankSyncPayload> TANK_SYNC_STREAM_CODEC = StreamCodec.of((buf, payload) -> payload.write(buf), TankSyncPayload::new);
|
||||
|
||||
public record TankSyncPayload(FluidStack fluidStack) implements CustomPacketPayload {
|
||||
public TankSyncPayload(RegistryFriendlyByteBuf buf) {
|
||||
this(readFluid(buf));
|
||||
}
|
||||
|
||||
public void write(RegistryFriendlyByteBuf buf) {
|
||||
if (fluidStack.isEmpty()) {
|
||||
buf.writeBoolean(false);
|
||||
} else {
|
||||
buf.writeBoolean(true);
|
||||
buf.writeResourceLocation(BuiltInRegistries.FLUID.getKey(fluidStack.getFluid()));
|
||||
buf.writeLong(fluidStack.getAmount());
|
||||
//? if >1.20.1 {
|
||||
/^DataComponentPatch.STREAM_CODEC.encode(buf, fluidStack.getPatch());
|
||||
^///?} else {
|
||||
buf.writeNbt(fluidStack.getTag());
|
||||
//?}
|
||||
}
|
||||
}
|
||||
|
||||
private static FluidStack readFluid(RegistryFriendlyByteBuf buf) {
|
||||
if (!buf.readBoolean()) {
|
||||
return FluidStack.empty();
|
||||
}
|
||||
ResourceLocation fluidId = buf.readResourceLocation();
|
||||
long amount = buf.readLong();
|
||||
//? if >1.20.1 {
|
||||
/^DataComponentPatch patch = DataComponentPatch.STREAM_CODEC.decode(buf);
|
||||
^///?} else {
|
||||
CompoundTag tag = buf.readNbt();
|
||||
//?}
|
||||
Fluid fluid = BuiltInRegistries.FLUID.get(fluidId);
|
||||
if (fluid == Fluids.EMPTY) {
|
||||
return FluidStack.empty();
|
||||
}
|
||||
//? if >1.20.1 {
|
||||
/^return FluidStack.create(fluid, amount, patch);
|
||||
^///?} else {
|
||||
FluidStack stack = FluidStack.create(fluid, amount);
|
||||
stack.setTag(tag);
|
||||
return stack;
|
||||
//?}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TANK_SYNC_TYPE;
|
||||
}
|
||||
}
|
||||
*///?}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.platform.services.IPlatformHelper;
|
||||
import net.cmr.jurassicrevived.platform.services.ITransferHelper;
|
||||
import net.cmr.jurassicrevived.platform.services.IItemFluidHelper;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
@@ -16,6 +18,8 @@ public class Services
|
||||
// For example this can be used to check if the code is running on Forge vs Fabric, or to ask the modloader if another
|
||||
// mod is loaded.
|
||||
public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class);
|
||||
public static final ITransferHelper TRANSFER = load(ITransferHelper.class);
|
||||
public static final IItemFluidHelper ITEM_FLUID = load(IItemFluidHelper.class);
|
||||
|
||||
// This code is used to load a service for the current environment. Your implementation of the service must be defined
|
||||
// manually by including a text file in META-INF/services named with the fully qualified class name of the service.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.cmr.jurassicrevived.platform.services;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IItemFluidHelper {
|
||||
record TransferResult(long amount, ItemStack stack) {}
|
||||
|
||||
Optional<FluidStack> getContainedFluid(ItemStack stack);
|
||||
TransferResult drain(ItemStack stack, long amount, boolean simulate);
|
||||
TransferResult fill(ItemStack stack, FluidStack fluid, long amount, boolean simulate);
|
||||
boolean isFluidHandler(ItemStack stack);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.cmr.jurassicrevived.platform.services;
|
||||
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformItemHandler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformEnergyHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformFluidHandler;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ITransferHelper {
|
||||
Optional<PlatformItemHandler> getItemHandler(Level level, BlockPos pos, Direction side);
|
||||
Optional<PlatformFluidHandler> getFluidHandler(Level level, BlockPos pos, Direction side);
|
||||
Optional<PlatformEnergyHandler> getEnergyHandler(Level level, BlockPos pos, Direction side);
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
|
||||
public interface InternalFluidHandler {
|
||||
FluidStack getFluid();
|
||||
long getCapacity();
|
||||
long fill(FluidStack stack, boolean simulate);
|
||||
FluidStack drain(long amount, boolean simulate);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InternalFluidHandlerAdapter implements PlatformFluidHandler {
|
||||
private final InternalFluidHandler handler;
|
||||
|
||||
public InternalFluidHandlerAdapter(InternalFluidHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<FluidStack> getExtractableFluids() {
|
||||
FluidStack fluid = handler.getFluid();
|
||||
return fluid.isEmpty() ? List.of() : List.of(fluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(FluidStack stack, long amount, boolean simulate) {
|
||||
if (stack.isEmpty()) return 0;
|
||||
return handler.drain(amount, simulate).getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insert(FluidStack stack, long amount, boolean simulate) {
|
||||
if (stack.isEmpty()) return 0;
|
||||
FluidStack toFill = stack.copy();
|
||||
toFill.setAmount(amount);
|
||||
return handler.fill(toFill, simulate);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface InternalFluidProvider {
|
||||
InternalFluidHandler getFluidHandler(@Nullable Direction side);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
public interface PlatformEnergyHandler {
|
||||
int extract(int amount, boolean simulate);
|
||||
int insert(int amount, boolean simulate);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
|
||||
public interface PlatformFluidHandler {
|
||||
Iterable<FluidStack> getExtractableFluids();
|
||||
long extract(FluidStack stack, long amount, boolean simulate);
|
||||
long insert(FluidStack stack, long amount, boolean simulate);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package net.cmr.jurassicrevived.platform.transfer;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public interface PlatformItemHandler {
|
||||
Iterable<ItemStack> getExtractableStacks();
|
||||
int extract(ItemStack stack, int amount, boolean simulate);
|
||||
int insert(ItemStack stack, int amount, boolean simulate);
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
package net.cmr.jurassicrevived.screen.custom;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.block.ModBlocks;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.TankBlockEntity;
|
||||
import net.cmr.jurassicrevived.networking.ModPackets;
|
||||
import net.cmr.jurassicrevived.platform.Services;
|
||||
import net.cmr.jurassicrevived.screen.ModMenuTypes;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -16,6 +21,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
public class TankMenu extends AbstractContainerMenu {
|
||||
public final TankBlockEntity blockEntity;
|
||||
private final Level level;
|
||||
private FluidStack fluidStack = FluidStack.empty();
|
||||
|
||||
public TankMenu(int pContainerId, Inventory inv, FriendlyByteBuf extraData) {
|
||||
this(pContainerId, inv, inv.player.level().getBlockEntity(extraData.readBlockPos()));
|
||||
@@ -25,20 +31,81 @@ public class TankMenu extends AbstractContainerMenu {
|
||||
super(ModMenuTypes.TANK_MENU.get(), pContainerId);
|
||||
this.blockEntity = ((TankBlockEntity) blockEntity);
|
||||
this.level = inv.player.level();
|
||||
|
||||
// Initialize fluidStack with the current state of the block entity
|
||||
// This ensures the client sees the correct fluid immediately if the BE is already synced
|
||||
if (this.blockEntity != null) {
|
||||
this.fluidStack = this.blockEntity.getFluid().copy();
|
||||
}
|
||||
|
||||
addPlayerInventory(inv);
|
||||
addPlayerHotbar(inv);
|
||||
|
||||
// Input Slot (0)
|
||||
this.addSlot(new Slot(this.blockEntity.itemHandler, 0, 44, 34));
|
||||
|
||||
// Output Slot (1)
|
||||
this.addSlot(new Slot(this.blockEntity.itemHandler, 1, 116, 34) {
|
||||
this.addSlot(new Slot(this.blockEntity.itemHandler, 0, 44, 34) {
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return Services.ITEM_FLUID.isFluidHandler(stack);
|
||||
}
|
||||
});
|
||||
|
||||
// Output Slot (1)
|
||||
this.addSlot(new Slot(this.blockEntity.itemHandler, 1, 116, 34){
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
addDataSlot(new DataSlot() {
|
||||
@Override
|
||||
public int get() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int pValue) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setFluid(FluidStack stack) {
|
||||
this.fluidStack = stack;
|
||||
}
|
||||
|
||||
public FluidStack getFluid() {
|
||||
return this.fluidStack;
|
||||
}
|
||||
public void syncFluidToPlayers() {
|
||||
if (this.level != null && !this.level.isClientSide()) {
|
||||
for (Player player : this.level.players()) {
|
||||
if (player.containerMenu == this && player instanceof ServerPlayer serverPlayer) {
|
||||
ModPackets.sendTankSync(serverPlayer, this.fluidStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAllDataToRemote() {
|
||||
super.sendAllDataToRemote();
|
||||
// Ensure we have the latest fluid state from the block entity before syncing
|
||||
if (this.blockEntity != null) {
|
||||
this.fluidStack = this.blockEntity.getFluid().copy();
|
||||
}
|
||||
syncFluidToPlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastChanges() {
|
||||
super.broadcastChanges();
|
||||
if (this.blockEntity != null) {
|
||||
FluidStack currentFluid = this.blockEntity.getFluid();
|
||||
if (!currentFluid.equals(this.fluidStack)) {
|
||||
this.fluidStack = currentFluid.copy();
|
||||
syncFluidToPlayers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int HOTBAR_SLOT_COUNT = 9;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class TankScreen extends AbstractContainerScreen<TankMenu> {
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
|
||||
renderFluidTooltipArea(guiGraphics, pMouseX, pMouseY, x, y, menu.blockEntity.getFluid(), 80, 8, fluidRenderer);
|
||||
renderFluidTooltipArea(guiGraphics, pMouseX, pMouseY, x, y, menu.getFluid(), 80, 8, fluidRenderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +64,7 @@ public class TankScreen extends AbstractContainerScreen<TankMenu> {
|
||||
|
||||
guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
fluidRenderer.render(guiGraphics, x + 80, y + 8, menu.blockEntity.getFluid());
|
||||
fluidRenderer.render(guiGraphics, x + 80, y + 8, menu.getFluid());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user