pipes (not done for fabric) and tank (maybe for fabric?)

This commit is contained in:
2026-02-03 14:47:35 -05:00
parent 9deea24e7b
commit a30721d9b8
39 changed files with 2201 additions and 100 deletions
@@ -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();
}
}
@@ -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);
}
}
@@ -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());
}
}
@@ -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);
}
}
}