Fix cross dimensional bugs

This commit is contained in:
Raoul Van den Berge
2016-08-01 02:13:07 +02:00
parent 445355896d
commit 9f638fd296
9 changed files with 79 additions and 29 deletions

View File

@@ -1,6 +1,7 @@
package refinedstorage.api.network;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* Represents a node in the storage network.
@@ -63,4 +64,9 @@ public interface INetworkNode {
* @return The network
*/
INetworkMaster getNetwork();
/**
* @return The world where this node is in
*/
World getWorld();
}

View File

@@ -1,13 +1,37 @@
package refinedstorage.api.network;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldProvider;
import java.util.List;
import java.util.Set;
/**
* A graph of all the nodes connected to a network.
*/
public interface INetworkNodeGraph {
void rebuild(BlockPos start);
/**
* Rebuilds the node graph.
*
* @param start The starting position to start looking for nodes
* @param notify Whether to notify nodes of a connection change
*/
void rebuild(BlockPos start, boolean notify);
/**
* @return A list of all connected nodes
*/
List<INetworkNode> all();
/**
* These hashes are calculated like this: 31 * {@link BlockPos#hashCode()} + {@link WorldProvider#getDimension()}
*
* @return A set of hashes of all connected nodes
*/
Set<Integer> allHashes();
/**
* Disconnects and notifies all connected nodes.
*/
void disconnectAll();
}

View File

@@ -16,14 +16,20 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller;
private List<INetworkNode> nodes = new ArrayList<INetworkNode>();
private Set<BlockPos> nodesPos = new HashSet<BlockPos>();
private Set<Integer> nodeHashes = new HashSet<Integer>();
public NetworkNodeGraph(TileController controller) {
this.controller = controller;
}
private int hashNode(World world, INetworkNode node) {
int result = node.getPosition().hashCode();
result = 31 * result + world.provider.getDimension();
return result;
}
@Override
public void rebuild(BlockPos start) {
public void rebuild(BlockPos start, boolean notify) {
if (!controller.canRun()) {
if (!nodes.isEmpty()) {
disconnectAll();
@@ -35,8 +41,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
World world = getWorld();
List<INetworkNode> newNodes = new ArrayList<INetworkNode>();
List<INetworkNode> interDimensionalNodes = new ArrayList<INetworkNode>();
Set<BlockPos> newNodesPos = new HashSet<BlockPos>();
Set<Integer> newNodeHashes = new HashSet<Integer>();
Set<BlockPos> checked = new HashSet<BlockPos>();
Queue<BlockPos> toCheck = new ArrayDeque<BlockPos>();
@@ -66,7 +71,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
INetworkNode node = (INetworkNode) tile;
newNodes.add(node);
newNodesPos.add(node.getPosition());
newNodeHashes.add(hashNode(world, node));
if (tile instanceof TileNetworkTransmitter) {
final TileNetworkTransmitter transmitter = (TileNetworkTransmitter) tile;
@@ -80,9 +85,10 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
}
};
dimensionGraph.rebuild(transmitter.getReceiver());
dimensionGraph.rebuild(transmitter.getReceiver(), false);
interDimensionalNodes.addAll(dimensionGraph.all());
newNodes.addAll(dimensionGraph.all());
newNodeHashes.addAll(dimensionGraph.allHashes());
} else {
BlockPos receiver = transmitter.getReceiver();
@@ -105,24 +111,24 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
}
List<INetworkNode> oldNodes = new ArrayList<INetworkNode>(nodes);
Set<BlockPos> oldNodesPos = new HashSet<BlockPos>(nodesPos);
Set<Integer> oldNodeHashes = new HashSet<Integer>(nodeHashes);
this.nodes = newNodes;
this.nodesPos = newNodesPos;
this.nodeHashes = newNodeHashes;
if (notify) {
for (INetworkNode newNode : nodes) {
if (!oldNodesPos.contains(newNode.getPosition())) {
if (!oldNodeHashes.contains(hashNode(newNode.getWorld(), newNode))) {
newNode.onConnected(controller);
}
}
for (INetworkNode oldNode : oldNodes) {
if (!nodesPos.contains(oldNode.getPosition())) {
if (!nodeHashes.contains(hashNode(oldNode.getWorld(), oldNode))) {
oldNode.onDisconnected(controller);
}
}
this.nodes.addAll(interDimensionalNodes);
}
}
@Override
@@ -130,6 +136,11 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
return nodes;
}
@Override
public Set<Integer> allHashes() {
return nodeHashes;
}
@Override
public void disconnectAll() {
for (INetworkNode node : nodes) {
@@ -139,7 +150,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
}
nodes.clear();
nodesPos.clear();
nodeHashes.clear();
}
public World getWorld() {

View File

@@ -26,6 +26,10 @@ public final class NetworkUtils {
return getPattern(network, stack) != null;
}
public static void rebuildGraph(INetworkMaster network) {
network.getNodeGraph().rebuild(network.getPosition(), true);
}
public static int getItemStackHashCode(ItemStack stack) {
return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1);
}

View File

@@ -20,6 +20,7 @@ import net.minecraft.world.World;
import refinedstorage.RefinedStorage;
import refinedstorage.RefinedStorageBlocks;
import refinedstorage.RefinedStorageGui;
import refinedstorage.apiimpl.network.NetworkUtils;
import refinedstorage.item.ItemBlockController;
import refinedstorage.tile.controller.TileController;
@@ -115,7 +116,7 @@ public class BlockController extends BlockBase {
super.neighborChanged(state, world, pos, block);
if (!world.isRemote) {
((TileController) world.getTileEntity(pos)).getNodeGraph().rebuild(pos);
NetworkUtils.rebuildGraph((TileController) world.getTileEntity(pos));
}
}

View File

@@ -11,6 +11,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import refinedstorage.api.network.INetworkMaster;
import refinedstorage.apiimpl.network.NetworkUtils;
import refinedstorage.tile.TileNode;
public abstract class BlockNode extends BlockBase {
@@ -63,7 +64,7 @@ public abstract class BlockNode extends BlockBase {
TileEntity tile = world.getTileEntity(pos.offset(facing));
if (tile instanceof TileNode && ((TileNode) tile).isConnected()) {
((TileNode) tile).getNetwork().getNodeGraph().rebuild(((TileNode) tile).getNetwork().getPosition());
NetworkUtils.rebuildGraph(((TileNode) tile).getNetwork());
break;
}
@@ -86,7 +87,7 @@ public abstract class BlockNode extends BlockBase {
super.breakBlock(world, pos, state);
if (network != null) {
network.getNodeGraph().rebuild(network.getPosition());
NetworkUtils.rebuildGraph(network);
}
}
}

View File

@@ -7,6 +7,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import refinedstorage.RefinedStorage;
import refinedstorage.RefinedStorageItems;
import refinedstorage.apiimpl.network.NetworkUtils;
import refinedstorage.container.ContainerNetworkTransmitter;
import refinedstorage.inventory.ItemHandlerBasic;
import refinedstorage.inventory.ItemHandlerUpgrade;
@@ -21,7 +22,7 @@ public class TileNetworkTransmitter extends TileNode {
super.onContentsChanged(slot);
if (network != null) {
network.getNodeGraph().rebuild(network.getPosition());
NetworkUtils.rebuildGraph(network);
}
}
};
@@ -41,7 +42,7 @@ public class TileNetworkTransmitter extends TileNode {
}
if (network != null) {
network.getNodeGraph().rebuild(network.getPosition());
NetworkUtils.rebuildGraph(network);
}
}
};

View File

@@ -6,6 +6,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.network.INetworkNode;
import refinedstorage.apiimpl.network.NetworkUtils;
import refinedstorage.block.BlockNode;
import refinedstorage.tile.config.IRedstoneModeConfig;
import refinedstorage.tile.config.RedstoneMode;
@@ -45,7 +46,7 @@ public abstract class TileNode extends TileBase implements INetworkNode, ISynchr
onConnectionChange(network, update);
if (rebuildOnUpdateChange) {
network.getNodeGraph().rebuild(network.getPosition());
NetworkUtils.rebuildGraph(network);
}
}

View File

@@ -34,6 +34,7 @@ import refinedstorage.apiimpl.autocrafting.CraftingPattern;
import refinedstorage.apiimpl.autocrafting.ProcessingCraftingTask;
import refinedstorage.apiimpl.network.GridHandler;
import refinedstorage.apiimpl.network.NetworkNodeGraph;
import refinedstorage.apiimpl.network.NetworkUtils;
import refinedstorage.apiimpl.network.WirelessGridHandler;
import refinedstorage.apiimpl.storage.GroupedStorage;
import refinedstorage.block.BlockController;
@@ -189,7 +190,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
if (couldRun != canRun()) {
couldRun = canRun();
nodeGraph.rebuild(pos);
NetworkUtils.rebuildGraph(this);
}
if (getEnergyScaledForDisplay() != lastEnergyDisplay) {