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()));
|
||||
@@ -26,19 +32,80 @@ public class TankMenu extends AbstractContainerMenu {
|
||||
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
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
{
|
||||
"format_version": "1.9.0",
|
||||
"credit": "Made with Blockbench",
|
||||
"ambientocclusion": false,
|
||||
"render_type": "cutout",
|
||||
"texture_size": [64, 64],
|
||||
"textures": {
|
||||
"0": "jurassicrevived:block/generator",
|
||||
"particle": "jurassicrevived:block/generator"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [2, 0, 2],
|
||||
"to": [14, 8, 14],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 1]},
|
||||
"faces": {
|
||||
"north": {"uv": [3, 0, 6, 2], "texture": "#0"},
|
||||
"east": {"uv": [3, 2, 6, 4], "texture": "#0"},
|
||||
"south": {"uv": [3, 4, 6, 6], "texture": "#0"},
|
||||
"west": {"uv": [0, 6, 3, 8], "texture": "#0"},
|
||||
"up": {"uv": [3, 3, 0, 0], "texture": "#0"},
|
||||
"down": {"uv": [3, 3, 0, 6], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [-1.425, 9.7, 3.5],
|
||||
"to": [6.575, 17.7, 12.5],
|
||||
"rotation": {"angle": -45, "axis": "z", "origin": [6.575, 7.7, -0.5]},
|
||||
"faces": {
|
||||
"north": {"uv": [5, 6.25, 7, 8.25], "texture": "#0"},
|
||||
"east": {"uv": [6, 0, 8.25, 2], "texture": "#0"},
|
||||
"south": {"uv": [7, 6.25, 9, 8.25], "texture": "#0"},
|
||||
"west": {"uv": [6, 2, 8.25, 4], "texture": "#0"},
|
||||
"up": {"uv": [5, 8.25, 3, 6], "texture": "#0"},
|
||||
"down": {"uv": [8, 4, 6, 6.25], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 0, 1],
|
||||
"to": [3, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 8.75, 4.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [4.5, 8.75, 5, 11], "texture": "#0"},
|
||||
"south": {"uv": [5, 8.75, 5.5, 11], "texture": "#0"},
|
||||
"west": {"uv": [5.5, 8.75, 6, 11], "texture": "#0"},
|
||||
"up": {"uv": [9.25, 2.5, 8.75, 2], "texture": "#0"},
|
||||
"down": {"uv": [9.75, 2, 9.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 0, 13],
|
||||
"to": [3, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 8.75, 6.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [6.5, 8.75, 7, 11], "texture": "#0"},
|
||||
"south": {"uv": [7, 8.75, 7.5, 11], "texture": "#0"},
|
||||
"west": {"uv": [7.5, 8.75, 8, 11], "texture": "#0"},
|
||||
"up": {"uv": [10.25, 2.5, 9.75, 2], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 6, 10, 6.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 0, 13],
|
||||
"to": [15, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [8, 8.75, 8.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [8.5, 8.75, 9, 11], "texture": "#0"},
|
||||
"south": {"uv": [0, 9, 0.5, 11.25], "texture": "#0"},
|
||||
"west": {"uv": [0.5, 9, 1, 11.25], "texture": "#0"},
|
||||
"up": {"uv": [10.5, 7, 10, 6.5], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 7, 10, 7.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 7, 3],
|
||||
"to": [15, 9, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 8, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [10, 7.5, 10.5, 8], "texture": "#0"},
|
||||
"east": {"uv": [0, 8, 2.5, 8.5], "texture": "#0"},
|
||||
"south": {"uv": [10, 8, 10.5, 8.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 4, 10.5, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [3, 10.5, 2.5, 8], "texture": "#0"},
|
||||
"down": {"uv": [8.75, 0, 8.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 7, 3],
|
||||
"to": [3, 9, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 8, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [10, 8.5, 10.5, 9], "texture": "#0"},
|
||||
"east": {"uv": [8, 4.5, 10.5, 5], "texture": "#0"},
|
||||
"south": {"uv": [10, 9, 10.5, 9.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 5, 10.5, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [3.5, 10.75, 3, 8.25], "texture": "#0"},
|
||||
"down": {"uv": [4, 8.25, 3.5, 10.75], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [4, 8, 9],
|
||||
"to": [6, 14, 11],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [2, 9, 14]},
|
||||
"faces": {
|
||||
"north": {"uv": [8.75, 0.5, 9.25, 2], "texture": "#0"},
|
||||
"east": {"uv": [9, 8.25, 9.5, 9.75], "texture": "#0"},
|
||||
"south": {"uv": [9.25, 0.5, 9.75, 2], "texture": "#0"},
|
||||
"west": {"uv": [9.5, 6, 10, 7.5], "texture": "#0"},
|
||||
"up": {"uv": [10.5, 10, 10, 9.5], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 10, 10, 10.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [10, 8, 5],
|
||||
"to": [12, 14, 7],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 10]},
|
||||
"faces": {
|
||||
"north": {"uv": [9.5, 7.5, 10, 9], "texture": "#0"},
|
||||
"east": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"},
|
||||
"south": {"uv": [9.75, 0.5, 10.25, 2], "texture": "#0"},
|
||||
"west": {"uv": [9, 9.75, 9.5, 11.25], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 1, 10.25, 0.5], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 1, 10.25, 1.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 0, 1],
|
||||
"to": [15, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 9, 1.5, 11.25], "texture": "#0"},
|
||||
"east": {"uv": [1.5, 9, 2, 11.25], "texture": "#0"},
|
||||
"south": {"uv": [2, 9, 2.5, 11.25], "texture": "#0"},
|
||||
"west": {"uv": [9, 6, 9.5, 8.25], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 2, 10.25, 1.5], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 2, 10.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 7, 1],
|
||||
"to": [13, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [9, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [8, 5.5, 10.5, 6], "texture": "#0"},
|
||||
"east": {"uv": [2.5, 10.5, 3, 11], "texture": "#0"},
|
||||
"south": {"uv": [8.25, 2.5, 10.75, 3], "texture": "#0"},
|
||||
"west": {"uv": [10.5, 4, 11, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 3.5, 8.25, 3], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 3.5, 8.25, 4], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 7, 13],
|
||||
"to": [13, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [9, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 8.25, 6.5, 8.75], "texture": "#0"},
|
||||
"east": {"uv": [10.5, 4.5, 11, 5], "texture": "#0"},
|
||||
"south": {"uv": [6.5, 8.25, 9, 8.75], "texture": "#0"},
|
||||
"west": {"uv": [10.5, 5, 11, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [2.5, 9, 0, 8.5], "texture": "#0"},
|
||||
"down": {"uv": [11.25, 0, 8.75, 0.5], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, -135, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, -135, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "Root",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
}
|
||||
]
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
{
|
||||
"format_version": "1.9.0",
|
||||
"credit": "Made with Blockbench",
|
||||
"ambientocclusion": false,
|
||||
"render_type": "cutout",
|
||||
"texture_size": [64, 64],
|
||||
"textures": {
|
||||
"0": "jurassicrevived:block/white_generator",
|
||||
"particle": "jurassicrevived:block/white_generator"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [2, 0, 2],
|
||||
"to": [14, 8, 14],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 1]},
|
||||
"faces": {
|
||||
"north": {"uv": [3, 0, 6, 2], "texture": "#0"},
|
||||
"east": {"uv": [3, 2, 6, 4], "texture": "#0"},
|
||||
"south": {"uv": [3, 4, 6, 6], "texture": "#0"},
|
||||
"west": {"uv": [0, 6, 3, 8], "texture": "#0"},
|
||||
"up": {"uv": [3, 3, 0, 0], "texture": "#0"},
|
||||
"down": {"uv": [3, 3, 0, 6], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [-1.425, 9.7, 3.5],
|
||||
"to": [6.575, 17.7, 12.5],
|
||||
"rotation": {"angle": -45, "axis": "z", "origin": [6.575, 7.7, -0.5]},
|
||||
"faces": {
|
||||
"north": {"uv": [5, 6.25, 7, 8.25], "texture": "#0"},
|
||||
"east": {"uv": [6, 0, 8.25, 2], "texture": "#0"},
|
||||
"south": {"uv": [7, 6.25, 9, 8.25], "texture": "#0"},
|
||||
"west": {"uv": [6, 2, 8.25, 4], "texture": "#0"},
|
||||
"up": {"uv": [5, 8.25, 3, 6], "texture": "#0"},
|
||||
"down": {"uv": [8, 4, 6, 6.25], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 0, 1],
|
||||
"to": [3, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 8.75, 4.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [4.5, 8.75, 5, 11], "texture": "#0"},
|
||||
"south": {"uv": [5, 8.75, 5.5, 11], "texture": "#0"},
|
||||
"west": {"uv": [5.5, 8.75, 6, 11], "texture": "#0"},
|
||||
"up": {"uv": [9.25, 2.5, 8.75, 2], "texture": "#0"},
|
||||
"down": {"uv": [9.75, 2, 9.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 0, 13],
|
||||
"to": [3, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 8.75, 6.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [6.5, 8.75, 7, 11], "texture": "#0"},
|
||||
"south": {"uv": [7, 8.75, 7.5, 11], "texture": "#0"},
|
||||
"west": {"uv": [7.5, 8.75, 8, 11], "texture": "#0"},
|
||||
"up": {"uv": [10.25, 2.5, 9.75, 2], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 6, 10, 6.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 0, 13],
|
||||
"to": [15, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [8, 8.75, 8.5, 11], "texture": "#0"},
|
||||
"east": {"uv": [8.5, 8.75, 9, 11], "texture": "#0"},
|
||||
"south": {"uv": [0, 9, 0.5, 11.25], "texture": "#0"},
|
||||
"west": {"uv": [0.5, 9, 1, 11.25], "texture": "#0"},
|
||||
"up": {"uv": [10.5, 7, 10, 6.5], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 7, 10, 7.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 7, 3],
|
||||
"to": [15, 9, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 8, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [10, 7.5, 10.5, 8], "texture": "#0"},
|
||||
"east": {"uv": [0, 8, 2.5, 8.5], "texture": "#0"},
|
||||
"south": {"uv": [10, 8, 10.5, 8.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 4, 10.5, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [3, 10.5, 2.5, 8], "texture": "#0"},
|
||||
"down": {"uv": [8.75, 0, 8.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 7, 3],
|
||||
"to": [3, 9, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [-1, 8, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [10, 8.5, 10.5, 9], "texture": "#0"},
|
||||
"east": {"uv": [8, 4.5, 10.5, 5], "texture": "#0"},
|
||||
"south": {"uv": [10, 9, 10.5, 9.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 5, 10.5, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [3.5, 10.75, 3, 8.25], "texture": "#0"},
|
||||
"down": {"uv": [4, 8.25, 3.5, 10.75], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [4, 8, 9],
|
||||
"to": [6, 14, 11],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [2, 9, 14]},
|
||||
"faces": {
|
||||
"north": {"uv": [8.75, 0.5, 9.25, 2], "texture": "#0"},
|
||||
"east": {"uv": [9, 8.25, 9.5, 9.75], "texture": "#0"},
|
||||
"south": {"uv": [9.25, 0.5, 9.75, 2], "texture": "#0"},
|
||||
"west": {"uv": [9.5, 6, 10, 7.5], "texture": "#0"},
|
||||
"up": {"uv": [10.5, 10, 10, 9.5], "texture": "#0"},
|
||||
"down": {"uv": [10.5, 10, 10, 10.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [10, 8, 5],
|
||||
"to": [12, 14, 7],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 10]},
|
||||
"faces": {
|
||||
"north": {"uv": [9.5, 7.5, 10, 9], "texture": "#0"},
|
||||
"east": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"},
|
||||
"south": {"uv": [9.75, 0.5, 10.25, 2], "texture": "#0"},
|
||||
"west": {"uv": [9, 9.75, 9.5, 11.25], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 1, 10.25, 0.5], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 1, 10.25, 1.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 0, 1],
|
||||
"to": [15, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 9, 1.5, 11.25], "texture": "#0"},
|
||||
"east": {"uv": [1.5, 9, 2, 11.25], "texture": "#0"},
|
||||
"south": {"uv": [2, 9, 2.5, 11.25], "texture": "#0"},
|
||||
"west": {"uv": [9, 6, 9.5, 8.25], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 2, 10.25, 1.5], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 2, 10.25, 2.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 7, 1],
|
||||
"to": [13, 9, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [9, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [8, 5.5, 10.5, 6], "texture": "#0"},
|
||||
"east": {"uv": [2.5, 10.5, 3, 11], "texture": "#0"},
|
||||
"south": {"uv": [8.25, 2.5, 10.75, 3], "texture": "#0"},
|
||||
"west": {"uv": [10.5, 4, 11, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [10.75, 3.5, 8.25, 3], "texture": "#0"},
|
||||
"down": {"uv": [10.75, 3.5, 8.25, 4], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 7, 13],
|
||||
"to": [13, 9, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [9, 0, 12]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 8.25, 6.5, 8.75], "texture": "#0"},
|
||||
"east": {"uv": [10.5, 4.5, 11, 5], "texture": "#0"},
|
||||
"south": {"uv": [6.5, 8.25, 9, 8.75], "texture": "#0"},
|
||||
"west": {"uv": [10.5, 5, 11, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [2.5, 9, 0, 8.5], "texture": "#0"},
|
||||
"down": {"uv": [11.25, 0, 8.75, 0.5], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, -135, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, -135, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "Root",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -61,6 +61,14 @@ dependencies {
|
||||
}
|
||||
})
|
||||
|
||||
val energyVersion = if (is120) {
|
||||
commonMod.prop("teamreborn_energy_1_20_1")
|
||||
} else {
|
||||
commonMod.prop("teamreborn_energy_1_21_1")
|
||||
}
|
||||
|
||||
modImplementation("teamreborn:energy:$energyVersion")
|
||||
|
||||
modImplementation("net.fabricmc:fabric-loader:${commonMod.prop("fabric_loader_version")}")
|
||||
modApi("net.fabricmc.fabric-api:fabric-api:${commonMod.prop("fabric_api_version")}")
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage;
|
||||
import net.cmr.jurassicrevived.platform.FabricEnergyWrapper;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
public class JRMod implements ModInitializer
|
||||
{
|
||||
@@ -22,15 +24,54 @@ public class JRMod implements ModInitializer
|
||||
Constants.LOG.info("Hello Fabric world!");
|
||||
CommonClass.init();
|
||||
|
||||
/*
|
||||
Items (Fabric Transfer API)
|
||||
ItemStorage.SIDED.registerForBlockEntities((be, side) -> (Storage<ItemVariant>) ((CrateBlockEntity)be).itemHandler, ModBlockEntities.CRATE_BE.get());
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((PowerCellBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.POWER_CELL_BE.get()
|
||||
);
|
||||
|
||||
Energy (TeamReborn Energy API is standard for Fabric)
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) -> ((PowerCellBlockEntity)be).getEnergyStorage(side), ModBlockEntities.POWER_CELL_BE.get());
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((GeneratorBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.GENERATOR_BE.get()
|
||||
);
|
||||
|
||||
Fluids (Fabric Transfer API)
|
||||
FluidStorage.SIDED.registerForBlockEntities((be, side) -> ((TankBlockEntity)be).getTank(side), ModBlockEntities.TANK_BE.get());
|
||||
*/
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((DNAExtractorBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.DNA_EXTRACTOR_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((DNAAnalyzerBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.DNA_ANALYZER_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((DNAHybridizerBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.DNA_HYBRIDIZER_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((FossilCleanerBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.FOSSIL_CLEANER_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((FossilGrinderBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.FOSSIL_GRINDER_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((EmbryonicMachineBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.EMBRYONIC_MACHINE_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((EmbryoCalcificationMachineBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.EMBRYO_CALCIFICATION_MACHINE_BE.get()
|
||||
);
|
||||
|
||||
EnergyStorage.SIDED.registerForBlockEntities((be, side) ->
|
||||
new FabricEnergyWrapper(((IncubatorBlockEntity) be).getEnergyStorage(side)),
|
||||
ModBlockEntities.INCUBATOR_BE.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
public class FabricEnergyWrapper implements EnergyStorage {
|
||||
private final ModEnergyStorage storage;
|
||||
|
||||
public FabricEnergyWrapper(ModEnergyStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insert(long maxAmount, TransactionContext transaction) {
|
||||
return storage.receiveEnergy((int) maxAmount, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(long maxAmount, TransactionContext transaction) {
|
||||
return storage.extractEnergy((int) maxAmount, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAmount() {
|
||||
return storage.getEnergyStored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCapacity() {
|
||||
return storage.getMaxEnergyStored();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.platform.services.IItemFluidHelper;
|
||||
import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class FabricItemFluidHelper implements IItemFluidHelper {
|
||||
|
||||
@Override
|
||||
public Optional<FluidStack> getContainedFluid(ItemStack stack) {
|
||||
ContainerItemContext ctx = ContainerItemContext.withConstant(stack.copy());
|
||||
Storage<FluidVariant> storage = ctx.find(FluidStorage.ITEM);
|
||||
if (storage == null) {
|
||||
if (stack.is(Items.WATER_BUCKET)) return Optional.of(FluidStack.create(Fluids.WATER, 1000));
|
||||
if (stack.is(Items.LAVA_BUCKET)) return Optional.of(FluidStack.create(Fluids.LAVA, 1000));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
for (StorageView<FluidVariant> view : storage) {
|
||||
if (!view.isResourceBlank() && view.getAmount() > 0) {
|
||||
return Optional.of(FluidStack.create(view.getResource().getFluid(), view.getAmount()));
|
||||
}
|
||||
}
|
||||
return Optional.of(FluidStack.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult drain(ItemStack stack, long amount, boolean simulate) {
|
||||
ContainerItemContext ctx = ContainerItemContext.withConstant(stack.copy());
|
||||
Storage<FluidVariant> storage = ctx.find(FluidStorage.ITEM);
|
||||
if (storage == null) {
|
||||
if (stack.is(Items.WATER_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
if (stack.is(Items.LAVA_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long extracted = 0;
|
||||
for (StorageView<FluidVariant> view : storage) {
|
||||
if (!view.isResourceBlank()) {
|
||||
extracted = storage.extract(view.getResource(), amount, tx);
|
||||
if (extracted > 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (extracted > 0) {
|
||||
if (!simulate) tx.commit();
|
||||
ItemStack resultStack = ctx.getItemVariant().toStack((int) ctx.getAmount());
|
||||
return new TransferResult(extracted, resultStack);
|
||||
}
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult fill(ItemStack stack, FluidStack fluid, long amount, boolean simulate) {
|
||||
ContainerItemContext ctx = ContainerItemContext.withConstant(stack.copy());
|
||||
Storage<FluidVariant> storage = ctx.find(FluidStorage.ITEM);
|
||||
if (storage == null) {
|
||||
if (stack.is(Items.BUCKET) && amount >= 1000) {
|
||||
if (fluid.getFluid().isSame(Fluids.WATER)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.WATER_BUCKET));
|
||||
}
|
||||
if (fluid.getFluid().isSame(Fluids.LAVA)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.LAVA_BUCKET));
|
||||
}
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long inserted = storage.insert(FluidVariant.of(fluid.getFluid()), amount, tx);
|
||||
if (inserted > 0) {
|
||||
if (!simulate) tx.commit();
|
||||
ItemStack resultStack = ctx.getItemVariant().toStack((int) ctx.getAmount());
|
||||
return new TransferResult(inserted, resultStack);
|
||||
}
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidHandler(ItemStack stack) {
|
||||
ContainerItemContext ctx = ContainerItemContext.withConstant(stack);
|
||||
Storage<FluidVariant> storage = ctx.find(FluidStorage.ITEM);
|
||||
return storage != null || stack.is(Items.BUCKET) || stack.is(Items.WATER_BUCKET) || stack.is(Items.LAVA_BUCKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.platform.services.ITransferHelper;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformItemHandler;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformEnergyHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformFluidHandler;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
//import net.fabricmc.fabric.api.transfer.v1.energy.EnergyStorage;
|
||||
//import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FabricTransferHelper implements ITransferHelper {
|
||||
|
||||
@Override
|
||||
public Optional<PlatformItemHandler> getItemHandler(Level level, BlockPos pos, Direction side) {
|
||||
Storage<ItemVariant> storage = ItemStorage.SIDED.find(level, pos, side);
|
||||
if (storage == null) return Optional.empty();
|
||||
return Optional.of(new FabricItemHandler(storage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformFluidHandler> getFluidHandler(Level level, BlockPos pos, Direction side) {
|
||||
var storage = FluidStorage.SIDED.find(level, pos, side);
|
||||
if (storage == null) return Optional.empty();
|
||||
return Optional.of(new FabricFluidHandler(storage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformEnergyHandler> getEnergyHandler(Level level, BlockPos pos, Direction side) {
|
||||
EnergyStorage storage = EnergyStorage.SIDED.find(level, pos, side);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static class FabricFluidHandler implements PlatformFluidHandler {
|
||||
private final net.fabricmc.fabric.api.transfer.v1.storage.Storage<FluidVariant> storage;
|
||||
|
||||
private FabricFluidHandler(net.fabricmc.fabric.api.transfer.v1.storage.Storage<FluidVariant> storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<FluidStack> getExtractableFluids() {
|
||||
List<FluidStack> stacks = new ArrayList<>();
|
||||
for (StorageView<FluidVariant> view : storage) {
|
||||
if (view.isResourceBlank()) continue;
|
||||
FluidVariant v = view.getResource();
|
||||
long amt = view.getAmount();
|
||||
if (amt > 0) {
|
||||
FluidStack stack = FluidStack.create(v.getFluid(), amt);
|
||||
stacks.add(stack);
|
||||
}
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(FluidStack stack, long amount, boolean simulate) {
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long extracted = storage.extract(FluidVariant.of(stack.getFluid()), amount, tx);
|
||||
if (!simulate) tx.commit();
|
||||
return extracted;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insert(FluidStack stack, long amount, boolean simulate) {
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long inserted = storage.insert(FluidVariant.of(stack.getFluid()), amount, tx);
|
||||
if (!simulate) tx.commit();
|
||||
return inserted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FabricEnergyHandler implements PlatformEnergyHandler {
|
||||
private FabricEnergyHandler() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(int amount, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(int amount, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FabricItemHandler implements PlatformItemHandler {
|
||||
private final Storage<ItemVariant> storage;
|
||||
|
||||
private FabricItemHandler(Storage<ItemVariant> storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ItemStack> getExtractableStacks() {
|
||||
List<ItemStack> stacks = new ArrayList<>();
|
||||
for (StorageView<ItemVariant> view : storage) {
|
||||
if (view.isResourceBlank()) continue;
|
||||
ItemVariant v = view.getResource();
|
||||
long amt = view.getAmount();
|
||||
if (amt > 0) stacks.add(v.toStack((int) Math.min(amt, Integer.MAX_VALUE)));
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(ItemStack stack, int amount, boolean simulate) {
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long extracted = storage.extract(ItemVariant.of(stack), amount, tx);
|
||||
if (!simulate) tx.commit();
|
||||
return (int) extracted;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(ItemStack stack, int amount, boolean simulate) {
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
long inserted = storage.insert(ItemVariant.of(stack), amount, tx);
|
||||
if (!simulate) tx.commit();
|
||||
return (int) inserted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.FabricItemFluidHelper
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.FabricTransferHelper
|
||||
@@ -42,3 +42,6 @@ cloth_config_version_1_21_1=15.0.140
|
||||
jade_version=14.3.4
|
||||
jade_version_1_20_1=11.13.1
|
||||
jade_version_1_21_1=15.10.4
|
||||
|
||||
teamreborn_energy_1_20_1=3.0.0
|
||||
teamreborn_energy_1_21_1=4.1.0
|
||||
@@ -0,0 +1,106 @@
|
||||
// ... existing code ...
|
||||
package net.cmr.jurassicrevived.event;
|
||||
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.*;
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.platform.ForgeEnergyStorage;
|
||||
import net.cmr.jurassicrevived.platform.ForgeTankFluidAdapter;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.common.util.NonNullSupplier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = Constants.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
|
||||
public class ForgeEvents {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void attachCapabilities(AttachCapabilitiesEvent<BlockEntity> event) {
|
||||
BlockEntity be = event.getObject();
|
||||
|
||||
if (be instanceof PowerCellBlockEntity pc) {
|
||||
event.addCapability(Constants.rl("energy_power_cell"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(pc.getEnergyStorage(null))));
|
||||
}
|
||||
|
||||
if (be instanceof GeneratorBlockEntity gen) {
|
||||
event.addCapability(Constants.rl("energy_generator"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(gen.getEnergyStorage(null))));
|
||||
}
|
||||
|
||||
if (be instanceof TankBlockEntity tank) {
|
||||
event.addCapability(Constants.rl("fluid_tank"),
|
||||
new FluidProvider(() -> new ForgeTankFluidAdapter(tank.getTank(null))));
|
||||
}
|
||||
|
||||
if (JRConfigManager.get().requirePower) {
|
||||
if (be instanceof DNAExtractorBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_dna_extractor"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof DNAAnalyzerBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_dna_analyzer"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof FossilCleanerBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_fossil_cleaner"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof FossilGrinderBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_fossil_grinder"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof DNAHybridizerBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_dna_hybridizer"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof EmbryonicMachineBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_embryonic_machine"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof EmbryoCalcificationMachineBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_embryo_calcification"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
if (be instanceof IncubatorBlockEntity e) {
|
||||
event.addCapability(Constants.rl("energy_incubator"),
|
||||
new EnergyProvider(() -> new ForgeEnergyStorage(e.getEnergyStorage(null))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class EnergyProvider implements ICapabilityProvider {
|
||||
private final LazyOptional<?> lazy;
|
||||
|
||||
private EnergyProvider(NonNullSupplier<?> supplier) {
|
||||
this.lazy = LazyOptional.of(supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
return cap == ForgeCapabilities.ENERGY ? lazy.cast() : LazyOptional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FluidProvider implements ICapabilityProvider {
|
||||
private final LazyOptional<?> lazy;
|
||||
|
||||
private FluidProvider(NonNullSupplier<?> supplier) {
|
||||
this.lazy = LazyOptional.of(supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
return cap == ForgeCapabilities.FLUID_HANDLER ? lazy.cast() : LazyOptional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyStorage;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
|
||||
public record ForgeEnergyStorage(ModEnergyStorage storage) implements IEnergyStorage {
|
||||
@Override
|
||||
public int receiveEnergy(int maxReceive, boolean simulate) {
|
||||
return storage.receiveEnergy(maxReceive, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return storage.extractEnergy(maxExtract, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnergyStored() {
|
||||
return storage.getEnergyStored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxEnergyStored() {
|
||||
return storage.getMaxEnergyStored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return storage.canExtract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canReceive() {
|
||||
return storage.canReceive();
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.platform.services.IItemFluidHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ForgeItemFluidHelper implements IItemFluidHelper {
|
||||
|
||||
@Override
|
||||
public Optional<FluidStack> getContainedFluid(ItemStack stack) {
|
||||
Optional<FluidStack> handlerFluid = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
if (handler.getTanks() <= 0) return FluidStack.empty();
|
||||
var fs = handler.getFluidInTank(0);
|
||||
if (fs.isEmpty()) return FluidStack.empty();
|
||||
return FluidStack.create(fs.getFluid(), fs.getAmount(), fs.getTag());
|
||||
});
|
||||
|
||||
if (handlerFluid.isPresent() && !handlerFluid.get().isEmpty()) return handlerFluid;
|
||||
|
||||
if (stack.is(Items.WATER_BUCKET)) {
|
||||
return Optional.of(FluidStack.create(Fluids.WATER, 1000));
|
||||
}
|
||||
if (stack.is(Items.LAVA_BUCKET)) {
|
||||
return Optional.of(FluidStack.create(Fluids.LAVA, 1000));
|
||||
}
|
||||
return Optional.of(FluidStack.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult drain(ItemStack stack, long amount, boolean simulate) {
|
||||
Optional<TransferResult> handlerResult = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
var drained = handler.drain((int) amount,
|
||||
simulate ? IFluidHandlerItem.FluidAction.SIMULATE : IFluidHandlerItem.FluidAction.EXECUTE);
|
||||
return new TransferResult(drained.getAmount(), handler.getContainer());
|
||||
});
|
||||
|
||||
if (handlerResult.isPresent()) return handlerResult.get();
|
||||
|
||||
if (stack.is(Items.WATER_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
if (stack.is(Items.LAVA_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult fill(ItemStack stack, FluidStack fluid, long amount, boolean simulate) {
|
||||
Optional<TransferResult> handlerResult = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
var toFill = new net.minecraftforge.fluids.FluidStack(fluid.getFluid(), (int) amount, fluid.getTag());
|
||||
int filled = handler.fill(toFill,
|
||||
simulate ? IFluidHandlerItem.FluidAction.SIMULATE : IFluidHandlerItem.FluidAction.EXECUTE);
|
||||
return new TransferResult(filled, handler.getContainer());
|
||||
});
|
||||
|
||||
if (handlerResult.isPresent()) return handlerResult.get();
|
||||
|
||||
if (stack.is(Items.BUCKET) && amount >= 1000) {
|
||||
if (fluid.getFluid().isSame(Fluids.WATER)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.WATER_BUCKET));
|
||||
}
|
||||
if (fluid.getFluid().isSame(Fluids.LAVA)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.LAVA_BUCKET));
|
||||
}
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.block.entity.custom.TankBlockEntity;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
public record ForgeTankFluidAdapter(TankBlockEntity.TankFluidHandler tank) implements IFluidHandler {
|
||||
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack getFluidInTank(int tankIndex) {
|
||||
if (tankIndex != 0) return FluidStack.EMPTY;
|
||||
return new FluidStack(tank.getFluid().getFluid(), (int) tank.getFluid().getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTankCapacity(int tankIndex) {
|
||||
return tankIndex == 0 ? (int) tank.getCapacity() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tankIndex, FluidStack stack) {
|
||||
return tankIndex == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
if (resource.isEmpty()) return 0;
|
||||
long filled = tank.fill(dev.architectury.fluid.FluidStack.create(resource.getFluid(), resource.getAmount()), action.simulate());
|
||||
return (int) filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
if (resource.isEmpty()) return FluidStack.EMPTY;
|
||||
var drained = tank.drain(resource.getAmount(), action.simulate());
|
||||
return new FluidStack(drained.getFluid(), (int) drained.getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
var drained = tank.drain(maxDrain, action.simulate());
|
||||
return new FluidStack(drained.getFluid(), (int) drained.getAmount());
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.platform.services.ITransferHelper;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformItemHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformEnergyHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformFluidHandler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ForgeTransferHelper implements ITransferHelper {
|
||||
|
||||
@Override
|
||||
public Optional<PlatformItemHandler> getItemHandler(Level level, BlockPos pos, Direction side) {
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null) return Optional.empty();
|
||||
return be.getCapability(ForgeCapabilities.ITEM_HANDLER, side)
|
||||
.resolve()
|
||||
.map(ForgeItemHandler::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformFluidHandler> getFluidHandler(Level level, BlockPos pos, Direction side) {
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null) return Optional.empty();
|
||||
return be.getCapability(ForgeCapabilities.FLUID_HANDLER, side)
|
||||
.resolve()
|
||||
.map(ForgeFluidHandler::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformEnergyHandler> getEnergyHandler(Level level, BlockPos pos, Direction side) {
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null) return Optional.empty();
|
||||
return be.getCapability(ForgeCapabilities.ENERGY, side)
|
||||
.resolve()
|
||||
.map(ForgeEnergyHandler::new);
|
||||
}
|
||||
|
||||
private static class ForgeItemHandler implements PlatformItemHandler {
|
||||
private final IItemHandler handler;
|
||||
|
||||
private ForgeItemHandler(IItemHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ItemStack> getExtractableStacks() {
|
||||
List<ItemStack> stacks = new ArrayList<>();
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack stack = handler.getStackInSlot(i);
|
||||
if (!stack.isEmpty()) stacks.add(stack.copy());
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(ItemStack stack, int amount, boolean simulate) {
|
||||
int remaining = amount;
|
||||
for (int i = 0; i < handler.getSlots() && remaining > 0; i++) {
|
||||
ItemStack slot = handler.getStackInSlot(i);
|
||||
if (!ItemHandlerHelper.canItemStacksStack(slot, stack)) continue;
|
||||
|
||||
ItemStack extracted = handler.extractItem(i, remaining, simulate);
|
||||
remaining -= extracted.getCount();
|
||||
}
|
||||
return amount - remaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(ItemStack stack, int amount, boolean simulate) {
|
||||
ItemStack toInsert = stack.copy();
|
||||
toInsert.setCount(amount);
|
||||
|
||||
ItemStack remainder = toInsert;
|
||||
for (int i = 0; i < handler.getSlots() && !remainder.isEmpty(); i++) {
|
||||
remainder = handler.insertItem(i, remainder, simulate);
|
||||
}
|
||||
return amount - remainder.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ForgeFluidHandler implements PlatformFluidHandler {
|
||||
private final IFluidHandler handler;
|
||||
|
||||
private ForgeFluidHandler(IFluidHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<FluidStack> getExtractableFluids() {
|
||||
List<FluidStack> stacks = new ArrayList<>();
|
||||
for (int i = 0; i < handler.getTanks(); i++) {
|
||||
net.minecraftforge.fluids.FluidStack fs = handler.getFluidInTank(i);
|
||||
if (!fs.isEmpty()) {
|
||||
stacks.add(FluidStack.create(fs.getFluid(), fs.getAmount(), fs.getTag()));
|
||||
}
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(FluidStack stack, long amount, boolean simulate) {
|
||||
net.minecraftforge.fluids.FluidStack req =
|
||||
new net.minecraftforge.fluids.FluidStack(stack.getFluid(), (int) amount, stack.getTag());
|
||||
net.minecraftforge.fluids.FluidStack drained = handler.drain(req, simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE);
|
||||
return drained.getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insert(FluidStack stack, long amount, boolean simulate) {
|
||||
net.minecraftforge.fluids.FluidStack toFill =
|
||||
new net.minecraftforge.fluids.FluidStack(stack.getFluid(), (int) amount, stack.getTag());
|
||||
return handler.fill(toFill, simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ForgeEnergyHandler implements PlatformEnergyHandler {
|
||||
private final IEnergyStorage storage;
|
||||
|
||||
private ForgeEnergyHandler(IEnergyStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(int amount, boolean simulate) {
|
||||
return storage.extractEnergy(amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(int amount, boolean simulate) {
|
||||
return storage.receiveEnergy(amount, simulate);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.ForgeItemFluidHelper
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.ForgeTransferHelper
|
||||
@@ -2,11 +2,18 @@ package net.cmr.jurassicrevived.event;
|
||||
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.block.entity.ModBlockEntities;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.FossilCleanerBlockEntity;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.GeneratorBlockEntity;
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.PowerCellBlockEntity;
|
||||
import net.cmr.jurassicrevived.block.entity.custom.TankBlockEntity;
|
||||
import net.cmr.jurassicrevived.neoforge.capabilities.NeoForgeEnergyStorage;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
|
||||
@EventBusSubscriber(modid = Constants.MOD_ID)
|
||||
public class NeoForgeEvents
|
||||
@@ -24,27 +31,64 @@ public class NeoForgeEvents
|
||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.EMBRYO_CALCIFICATION_MACHINE_BE.get(), (be, side) -> be.getItemHandler(side));
|
||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.CRATE_BE.get(), (be, side) -> be.getItemHandler(side));
|
||||
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.INCUBATOR_BE.get(), (be, side) -> be.getItemHandler(side));
|
||||
*/
|
||||
|
||||
Energy
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.POWER_CELL_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.GENERATOR_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
// Energy
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.POWER_CELL_BE.get(),
|
||||
(be, side) -> new NeoForgeEnergyStorage(((PowerCellBlockEntity) be).getEnergyStorage(side)));
|
||||
|
||||
Fluids
|
||||
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, ModBlockEntities.TANK_BE.get(), (be, side) -> be.getTank(side));
|
||||
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, ModBlockEntities.FOSSIL_CLEANER_BE.get(), (be, side) -> be.getTank(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.GENERATOR_BE.get(),
|
||||
(be, side) -> new NeoForgeEnergyStorage(((GeneratorBlockEntity) be).getEnergyStorage(side)));
|
||||
|
||||
Machine Logic (if config allows)
|
||||
if (JRConfigManager.get().requirePower) {
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.DNA_EXTRACTOR_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.DNA_ANALYZER_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.FOSSIL_CLEANER_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.FOSSIL_GRINDER_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.DNA_HYBRIDIZER_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.EMBRYONIC_MACHINE_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.EMBRYO_CALCIFICATION_MACHINE_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.INCUBATOR_BE.get(), (be, side) -> be.getEnergyStorage(side));
|
||||
}
|
||||
// Fluids
|
||||
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, ModBlockEntities.TANK_BE.get(),
|
||||
(be, side) -> new TankFluidAdapter(((TankBlockEntity) be).getTank(side)));
|
||||
|
||||
*/
|
||||
//event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, ModBlockEntities.FOSSIL_CLEANER_BE.get(),
|
||||
// (be, side) -> new TankFluidAdapter(((FossilCleanerBlockEntity) be).getTank(side)));
|
||||
}
|
||||
|
||||
private record TankFluidAdapter(TankBlockEntity.TankFluidHandler tank) implements IFluidHandler {
|
||||
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack getFluidInTank(int tankIndex) {
|
||||
if (tankIndex != 0) return FluidStack.EMPTY;
|
||||
return new FluidStack(tank.getFluid().getFluid(), (int) tank.getFluid().getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTankCapacity(int tankIndex) {
|
||||
return tankIndex == 0 ? (int) tank.getCapacity() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tankIndex, FluidStack stack) {
|
||||
return tankIndex == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
if (resource.isEmpty()) return 0;
|
||||
long filled = tank.fill(dev.architectury.fluid.FluidStack.create(resource.getFluid(), resource.getAmount()), action.simulate());
|
||||
return (int) filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
if (resource.isEmpty()) return FluidStack.EMPTY;
|
||||
var drained = tank.drain(resource.getAmount(), action.simulate());
|
||||
return new FluidStack(drained.getFluid(), (int) drained.getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
var drained = tank.drain(maxDrain, action.simulate());
|
||||
return new FluidStack(drained.getFluid(), (int) drained.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.platform.services.IItemFluidHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class NeoForgeItemFluidHelper implements IItemFluidHelper {
|
||||
|
||||
@Override
|
||||
public Optional<FluidStack> getContainedFluid(ItemStack stack) {
|
||||
Optional<FluidStack> handlerFluid = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
if (handler.getTanks() <= 0) return FluidStack.empty();
|
||||
var fs = handler.getFluidInTank(0);
|
||||
if (fs.isEmpty()) return FluidStack.empty();
|
||||
return FluidStack.create(fs.getFluid(), fs.getAmount());
|
||||
});
|
||||
|
||||
if (handlerFluid.isPresent() && !handlerFluid.get().isEmpty()) return handlerFluid;
|
||||
|
||||
if (stack.is(Items.WATER_BUCKET)) {
|
||||
return Optional.of(FluidStack.create(Fluids.WATER, 1000));
|
||||
}
|
||||
if (stack.is(Items.LAVA_BUCKET)) {
|
||||
return Optional.of(FluidStack.create(Fluids.LAVA, 1000));
|
||||
}
|
||||
return Optional.of(FluidStack.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult drain(ItemStack stack, long amount, boolean simulate) {
|
||||
Optional<TransferResult> handlerResult = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
var drained = handler.drain((int) amount,
|
||||
simulate ? IFluidHandlerItem.FluidAction.SIMULATE : IFluidHandlerItem.FluidAction.EXECUTE);
|
||||
return new TransferResult(drained.getAmount(), handler.getContainer());
|
||||
});
|
||||
|
||||
if (handlerResult.isPresent()) return handlerResult.get();
|
||||
|
||||
if (stack.is(Items.WATER_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
if (stack.is(Items.LAVA_BUCKET) && amount >= 1000) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.BUCKET));
|
||||
}
|
||||
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferResult fill(ItemStack stack, FluidStack fluid, long amount, boolean simulate) {
|
||||
Optional<TransferResult> handlerResult = FluidUtil.getFluidHandler(stack.copy())
|
||||
.map(handler -> {
|
||||
var toFill = new net.neoforged.neoforge.fluids.FluidStack(fluid.getFluid(), (int) amount);
|
||||
int filled = handler.fill(toFill,
|
||||
simulate ? IFluidHandlerItem.FluidAction.SIMULATE : IFluidHandlerItem.FluidAction.EXECUTE);
|
||||
return new TransferResult(filled, handler.getContainer());
|
||||
});
|
||||
|
||||
if (handlerResult.isPresent()) return handlerResult.get();
|
||||
|
||||
if (stack.is(Items.BUCKET) && amount >= 1000) {
|
||||
if (fluid.getFluid().isSame(Fluids.WATER)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.WATER_BUCKET));
|
||||
}
|
||||
if (fluid.getFluid().isSame(Fluids.LAVA)) {
|
||||
return new TransferResult(1000, simulate ? stack : new ItemStack(Items.LAVA_BUCKET));
|
||||
}
|
||||
}
|
||||
return new TransferResult(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidHandler(ItemStack stack) {
|
||||
return FluidUtil.getFluidHandler(stack).isPresent() || stack.is(Items.BUCKET) || stack.is(Items.WATER_BUCKET) || stack.is(Items.LAVA_BUCKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package net.cmr.jurassicrevived.platform;
|
||||
|
||||
import net.cmr.jurassicrevived.platform.services.ITransferHelper;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformItemHandler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidHandlerAdapter;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidProvider;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformEnergyHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.PlatformFluidHandler;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class NeoForgeTransferHelper implements ITransferHelper {
|
||||
|
||||
@Override
|
||||
public Optional<PlatformItemHandler> getItemHandler(Level level, BlockPos pos, Direction side) {
|
||||
IItemHandler handler = level.getCapability(Capabilities.ItemHandler.BLOCK, pos, side);
|
||||
return Optional.ofNullable(handler).map(NeoForgeItemHandler::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformFluidHandler> getFluidHandler(Level level, BlockPos pos, Direction side) {
|
||||
IFluidHandler handler = level.getCapability(Capabilities.FluidHandler.BLOCK, pos, side);
|
||||
if (handler != null) return Optional.of(new NeoForgeFluidHandler(handler));
|
||||
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be instanceof InternalFluidProvider provider) {
|
||||
return Optional.of(new InternalFluidHandlerAdapter(provider.getFluidHandler(side)));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlatformEnergyHandler> getEnergyHandler(Level level, BlockPos pos, Direction side) {
|
||||
IEnergyStorage storage = level.getCapability(Capabilities.EnergyStorage.BLOCK, pos, side);
|
||||
return Optional.ofNullable(storage).map(NeoForgeEnergyHandler::new);
|
||||
}
|
||||
|
||||
private static class NeoForgeFluidHandler implements PlatformFluidHandler {
|
||||
private final IFluidHandler handler;
|
||||
|
||||
private NeoForgeFluidHandler(IFluidHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<FluidStack> getExtractableFluids() {
|
||||
List<FluidStack> stacks = new ArrayList<>();
|
||||
for (int i = 0; i < handler.getTanks(); i++) {
|
||||
net.neoforged.neoforge.fluids.FluidStack fs = handler.getFluidInTank(i);
|
||||
if (!fs.isEmpty()) {
|
||||
stacks.add(FluidStack.create(fs.getFluid(), fs.getAmount()));
|
||||
}
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(FluidStack stack, long amount, boolean simulate) {
|
||||
net.neoforged.neoforge.fluids.FluidStack req =
|
||||
new net.neoforged.neoforge.fluids.FluidStack(stack.getFluid(), (int) amount);
|
||||
net.neoforged.neoforge.fluids.FluidStack drained = handler.drain(
|
||||
req,
|
||||
simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE
|
||||
);
|
||||
return drained.getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insert(FluidStack stack, long amount, boolean simulate) {
|
||||
net.neoforged.neoforge.fluids.FluidStack toFill =
|
||||
new net.neoforged.neoforge.fluids.FluidStack(stack.getFluid(), (int) amount);
|
||||
return handler.fill(
|
||||
toFill,
|
||||
simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NeoForgeEnergyHandler implements PlatformEnergyHandler {
|
||||
private final IEnergyStorage storage;
|
||||
|
||||
private NeoForgeEnergyHandler(IEnergyStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(int amount, boolean simulate) {
|
||||
return storage.extractEnergy(amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(int amount, boolean simulate) {
|
||||
return storage.receiveEnergy(amount, simulate);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NeoForgeItemHandler implements PlatformItemHandler {
|
||||
private final IItemHandler handler;
|
||||
|
||||
private NeoForgeItemHandler(IItemHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ItemStack> getExtractableStacks() {
|
||||
List<ItemStack> stacks = new ArrayList<>();
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack stack = handler.getStackInSlot(i);
|
||||
if (!stack.isEmpty()) stacks.add(stack.copy());
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extract(ItemStack stack, int amount, boolean simulate) {
|
||||
int remaining = amount;
|
||||
for (int i = 0; i < handler.getSlots() && remaining > 0; i++) {
|
||||
ItemStack slot = handler.getStackInSlot(i);
|
||||
if (!itemsMatch(slot, stack)) continue;
|
||||
|
||||
ItemStack extracted = handler.extractItem(i, remaining, simulate);
|
||||
remaining -= extracted.getCount();
|
||||
}
|
||||
return amount - remaining;
|
||||
}
|
||||
|
||||
private static boolean itemsMatch(ItemStack a, ItemStack b) {
|
||||
//? if >1.20.1 {
|
||||
return ItemStack.isSameItemSameComponents(a, b);
|
||||
//?} else {
|
||||
/*return ItemStack.isSameItemSameTags(a, b);*/
|
||||
//?}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(ItemStack stack, int amount, boolean simulate) {
|
||||
ItemStack toInsert = stack.copy();
|
||||
toInsert.setCount(amount);
|
||||
|
||||
ItemStack remainder = toInsert;
|
||||
for (int i = 0; i < handler.getSlots() && !remainder.isEmpty(); i++) {
|
||||
remainder = handler.insertItem(i, remainder, simulate);
|
||||
}
|
||||
return amount - remainder.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.NeoForgeItemFluidHelper
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.cmr.jurassicrevived.platform.NeoForgeTransferHelper
|
||||
Reference in New Issue
Block a user