diff --git a/src/main/java/de/ellpeck/prettypipes/Registry.java b/src/main/java/de/ellpeck/prettypipes/Registry.java index 12e7d12..cdf5cc7 100644 --- a/src/main/java/de/ellpeck/prettypipes/Registry.java +++ b/src/main/java/de/ellpeck/prettypipes/Registry.java @@ -141,7 +141,7 @@ public final class Registry { ); } - private static > ContainerType createPipeContainer(String name) { + public static > ContainerType createPipeContainer(String name) { return (ContainerType) IForgeContainerType.create((windowId, inv, data) -> { PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, inv.player.world, data.readBlockPos()); int moduleIndex = data.readInt(); @@ -150,7 +150,7 @@ public final class Registry { }).setRegistryName(name); } - private static Item[] createTieredModule(String name, BiFunction item) { + public static Item[] createTieredModule(String name, BiFunction item) { List items = new ArrayList<>(); for (ModuleTier tier : ModuleTier.values()) items.add(item.apply(name, tier).setRegistryName(tier.name().toLowerCase(Locale.ROOT) + "_" + name)); diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index a0fb1b6..5b33147 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -6,6 +6,7 @@ import com.google.common.collect.Streams; import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.pipe.IPipeConnectable; import de.ellpeck.prettypipes.pipe.PipeBlock; import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.packets.PacketHandler; @@ -15,6 +16,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -22,6 +24,9 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; +import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import org.apache.commons.lang3.tuple.Pair; import org.jgrapht.GraphPath; @@ -48,6 +53,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL private final DijkstraShortestPath dijkstra; private final Map> nodeToConnectedNodes = new HashMap<>(); private final Map tileCache = new HashMap<>(); + private final Map> energyStorageCache = new HashMap<>(); private final ListMultimap pipeItems = ArrayListMultimap.create(); private final World world; @@ -178,6 +184,30 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return tile; } + public IEnergyStorage getEnergyStorage(BlockPos node) { + Pair value = this.energyStorageCache.get(node); + isNull: + if (value == null || value.getLeft().isRemoved()) { + for (BlockPos other : this.getOrderedNetworkNodes(node)) { + PipeTileEntity pipe = this.getPipe(other); + for (Direction dir : Direction.values()) { + IPipeConnectable connectable = pipe.getConnectable(dir); + if (connectable == null) + continue; + BlockPos pos = other.offset(dir); + if (!connectable.provideEnergyStorage(this.world, pos, other, dir.getOpposite())) + continue; + value = Pair.of(this.world.getTileEntity(pos), dir.getOpposite()); + this.energyStorageCache.put(node, value); + break isNull; + } + } + } + if (value == null) + return null; + return value.getLeft().getCapability(CapabilityEnergy.ENERGY, value.getRight()).orElse(null); + } + public List getOrderedNetworkItems(BlockPos node) { if (!this.isNode(node)) return Collections.emptyList(); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java b/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java index 6fdf34d..5806bbe 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java @@ -9,4 +9,7 @@ public interface IPipeConnectable { ConnectionType getConnectionType(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction); + default boolean provideEnergyStorage(World world, BlockPos pos, BlockPos pipePos, Direction direction) { + return false; + } } diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index af42612..50e691f 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -6,6 +6,7 @@ import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.network.PipeItem; import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.pipe.modules.containers.MainPipeContainer; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ChestBlock; import net.minecraft.entity.player.PlayerEntity; @@ -200,6 +201,17 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null); } + public IPipeConnectable getConnectable(Direction dir) { + if (!this.isConnected(dir)) + return null; + BlockPos offset = this.pos.offset(dir); + BlockState state = this.world.getBlockState(offset); + Block block = state.getBlock(); + if (block instanceof IPipeConnectable) + return (IPipeConnectable) block; + return null; + } + public boolean isConnectedInventory(Direction dir) { return this.getItemHandler(dir) != null; }