mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-26 05:28:33 +01:00
got network connections fully working!
This commit is contained in:
parent
bf60a40457
commit
87de8e353d
4 changed files with 89 additions and 56 deletions
|
@ -5,6 +5,7 @@ import de.ellpeck.prettypipes.Utility;
|
||||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
import de.ellpeck.prettypipes.network.PipeNetwork;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.InventoryHelper;
|
import net.minecraft.inventory.InventoryHelper;
|
||||||
|
@ -95,6 +96,11 @@ public class PipeBlock extends ContainerBlock {
|
||||||
return this.createState(context.getWorld(), context.getPos(), this.getDefaultState());
|
return this.createState(context.getWorld(), context.getPos(), this.getDefaultState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||||
|
onStateChanged(worldIn, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
|
public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,18 +2,11 @@ package de.ellpeck.prettypipes.events;
|
||||||
|
|
||||||
import de.ellpeck.prettypipes.PrettyPipes;
|
import de.ellpeck.prettypipes.PrettyPipes;
|
||||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
import de.ellpeck.prettypipes.network.PipeNetwork;
|
||||||
import net.minecraft.particles.ParticleType;
|
|
||||||
import net.minecraft.particles.ParticleTypes;
|
|
||||||
import net.minecraft.particles.RedstoneParticleData;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
|
||||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import org.jgrapht.graph.DefaultWeightedEdge;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
@Mod.EventBusSubscriber
|
||||||
public final class Events {
|
public final class Events {
|
||||||
|
@ -22,22 +15,4 @@ public final class Events {
|
||||||
public static void onWorldCaps(AttachCapabilitiesEvent<World> event) {
|
public static void onWorldCaps(AttachCapabilitiesEvent<World> event) {
|
||||||
event.addCapability(new ResourceLocation(PrettyPipes.ID, "network"), new PipeNetwork(event.getObject()));
|
event.addCapability(new ResourceLocation(PrettyPipes.ID, "network"), new PipeNetwork(event.getObject()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onWorldTick(TickEvent.WorldTickEvent event) {
|
|
||||||
if (event.phase != TickEvent.Phase.END)
|
|
||||||
return;
|
|
||||||
if (event.world.getGameTime() % 5 != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(event.world);
|
|
||||||
for (DefaultWeightedEdge edge : network.graph.edgeSet()) {
|
|
||||||
BlockPos start = network.graph.getEdgeSource(edge);
|
|
||||||
BlockPos end = network.graph.getEdgeTarget(edge);
|
|
||||||
|
|
||||||
RedstoneParticleData data = new RedstoneParticleData(((start.getX() * 181923 + end.getX()) % 255) / 255F, ((start.getY() * 128391 + end.getY()) % 255) / 255F, ((start.getZ() * 123891 + end.getZ()) % 255) / 255F, 1);
|
|
||||||
((ServerWorld) event.world).spawnParticle(data, start.getX() + 0.5F, start.getY() + 0.5F, start.getZ() + 0.5F, 1, 0, 0, 0, 0);
|
|
||||||
((ServerWorld) event.world).spawnParticle(data, end.getX() + 0.5F, end.getY() + 0.5F, end.getZ() + 0.5F, 1, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package de.ellpeck.prettypipes.network;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import org.jgrapht.graph.DefaultWeightedEdge;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NetworkEdge extends DefaultWeightedEdge {
|
||||||
|
|
||||||
|
public TileEntity startPipe;
|
||||||
|
public List<TileEntity> pipes = new ArrayList<>();
|
||||||
|
public TileEntity endPipe;
|
||||||
|
}
|
|
@ -2,7 +2,9 @@ package de.ellpeck.prettypipes.network;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import de.ellpeck.prettypipes.Registry;
|
import de.ellpeck.prettypipes.Registry;
|
||||||
|
import de.ellpeck.prettypipes.Utility;
|
||||||
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
|
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
|
||||||
|
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -31,8 +33,8 @@ import java.util.Set;
|
||||||
|
|
||||||
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
|
|
||||||
public final SimpleWeightedGraph<BlockPos, DefaultWeightedEdge> graph = new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
|
public final SimpleWeightedGraph<BlockPos, NetworkEdge> graph = new SimpleWeightedGraph<>(NetworkEdge.class);
|
||||||
private final DijkstraShortestPath<BlockPos, DefaultWeightedEdge> dijkstra = new DijkstraShortestPath<>(this.graph);
|
private final DijkstraShortestPath<BlockPos, NetworkEdge> dijkstra = new DijkstraShortestPath<>(this.graph);
|
||||||
private final World world;
|
private final World world;
|
||||||
|
|
||||||
public PipeNetwork(World world) {
|
public PipeNetwork(World world) {
|
||||||
|
@ -68,48 +70,84 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPipeChanged(BlockPos pos, BlockState state) {
|
public void onPipeChanged(BlockPos pos, BlockState state) {
|
||||||
Set<Pair<BlockPos, Integer>> neighbors = this.findConnectedNodesInPipe(pos, state);
|
List<NetworkEdge> neighbors = this.createAllEdges(pos, state, true);
|
||||||
// if we only have one neighbor, then there can't be any new connections
|
// if we only have one neighbor, then there can't be any new connections
|
||||||
if (neighbors.size() <= 1 && !this.graph.containsVertex(pos))
|
if (neighbors.size() <= 1 && !this.graph.containsVertex(pos))
|
||||||
return;
|
return;
|
||||||
for (Pair<BlockPos, Integer> node : neighbors)
|
for (NetworkEdge edge : neighbors) {
|
||||||
this.refreshNode(node.getLeft(), this.world.getBlockState(node.getLeft()));
|
BlockPos end = edge.endPipe.getPos();
|
||||||
System.out.println(this.graph);
|
this.refreshNode(end, this.world.getBlockState(end));
|
||||||
|
}
|
||||||
|
System.out.println(this.graph.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshNode(BlockPos pos, BlockState state) {
|
private void refreshNode(BlockPos pos, BlockState state) {
|
||||||
Set<DefaultWeightedEdge> edges = this.graph.edgesOf(pos);
|
Set<NetworkEdge> edges = this.graph.edgesOf(pos);
|
||||||
this.graph.removeAllEdges(new ArrayList<>(edges));
|
this.graph.removeAllEdges(new ArrayList<>(edges));
|
||||||
|
|
||||||
for (Pair<BlockPos, Integer> node : this.findConnectedNodesInPipe(pos, state)) {
|
for (NetworkEdge edge : this.createAllEdges(pos, state, false)) {
|
||||||
DefaultWeightedEdge edge = this.graph.addEdge(pos, node.getLeft());
|
this.graph.addEdge(edge.startPipe.getPos(), edge.endPipe.getPos(), edge);
|
||||||
this.graph.setEdgeWeight(edge, node.getRight());
|
this.graph.setEdgeWeight(edge, edge.pipes.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Pair<BlockPos, Integer>> findConnectedNodesInPipe(BlockPos pos, BlockState state) {
|
private List<NetworkEdge> createAllEdges(BlockPos pos, BlockState state, boolean allAround) {
|
||||||
Set<Pair<BlockPos, Integer>> set = new HashSet<>();
|
List<NetworkEdge> edges = new ArrayList<>();
|
||||||
this.findConnectedNodesInPipe(pos, state, set, Sets.newHashSet(pos), 0);
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findConnectedNodesInPipe(BlockPos pos, BlockState state, Set<Pair<BlockPos, Integer>> nodes, Set<BlockPos> seen, int iterations) {
|
|
||||||
if (!(state.getBlock() instanceof PipeBlock))
|
|
||||||
return;
|
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
if (!state.get(PipeBlock.DIRECTIONS.get(dir)).isConnected())
|
NetworkEdge edge = this.createEdge(pos, state, dir, allAround);
|
||||||
continue;
|
if (edge != null)
|
||||||
BlockPos offset = pos.offset(dir);
|
edges.add(edge);
|
||||||
if (seen.contains(offset))
|
|
||||||
continue;
|
|
||||||
seen.add(offset);
|
|
||||||
if (this.graph.containsVertex(offset)) {
|
|
||||||
nodes.add(Pair.of(offset, iterations));
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
this.findConnectedNodesInPipe(offset, this.world.getBlockState(offset), nodes, seen, iterations + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkEdge createEdge(BlockPos pos, BlockState state, Direction dir, boolean allAround) {
|
||||||
|
if (!allAround && !state.get(PipeBlock.DIRECTIONS.get(dir)).isConnected())
|
||||||
|
return null;
|
||||||
|
BlockPos currPos = pos.offset(dir);
|
||||||
|
BlockState currState = this.world.getBlockState(currPos);
|
||||||
|
if (!(currState.getBlock() instanceof PipeBlock))
|
||||||
|
return null;
|
||||||
|
NetworkEdge edge = new NetworkEdge();
|
||||||
|
PipeTileEntity startPipe = Utility.getTileEntity(PipeTileEntity.class, this.world, pos);
|
||||||
|
if (startPipe != null) {
|
||||||
|
edge.startPipe = startPipe;
|
||||||
|
edge.pipes.add(startPipe);
|
||||||
|
}
|
||||||
|
edge.pipes.add(Utility.getTileEntity(PipeTileEntity.class, this.world, currPos));
|
||||||
|
|
||||||
|
Set<BlockPos> seen = new HashSet<>();
|
||||||
|
seen.add(pos);
|
||||||
|
seen.add(currPos);
|
||||||
|
while (true) {
|
||||||
|
// if we found a vertex, we can stop since that's the next node
|
||||||
|
// we do this here since the first offset pipe also needs to check this
|
||||||
|
if (this.graph.containsVertex(currPos)) {
|
||||||
|
edge.endPipe = edge.pipes.get(edge.pipes.size() - 1);
|
||||||
|
return edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (Direction nextDir : Direction.values()) {
|
||||||
|
if (!currState.get(PipeBlock.DIRECTIONS.get(nextDir)).isConnected())
|
||||||
|
continue;
|
||||||
|
BlockPos offset = currPos.offset(nextDir);
|
||||||
|
if (seen.contains(offset))
|
||||||
|
continue;
|
||||||
|
seen.add(offset);
|
||||||
|
BlockState offState = this.world.getBlockState(offset);
|
||||||
|
if (!(offState.getBlock() instanceof PipeBlock))
|
||||||
|
continue;
|
||||||
|
edge.pipes.add(Utility.getTileEntity(PipeTileEntity.class, this.world, offset));
|
||||||
|
currPos = offset;
|
||||||
|
currState = offState;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PipeNetwork get(World world) {
|
public static PipeNetwork get(World world) {
|
||||||
|
|
Loading…
Reference in a new issue