Made network transmitter work over dimensions

This commit is contained in:
Raoul Van den Berge
2016-08-01 00:16:20 +02:00
parent ddd6c319e1
commit 384d79c998
11 changed files with 188 additions and 134 deletions

View File

@@ -38,9 +38,9 @@ public interface INetworkMaster {
boolean canRun(); boolean canRun();
/** /**
* @return A list with all the network nodes * @return A graph of connected nodes to this network
*/ */
List<INetworkNode> getNodes(); INetworkNodeGraph getNodeGraph();
/** /**
* @return The {@link IGridHandler} for this network * @return The {@link IGridHandler} for this network
@@ -101,11 +101,6 @@ public interface INetworkMaster {
*/ */
void rebuildPatterns(); void rebuildPatterns();
/**
* Rebuilds the network node list.
*/
void rebuildNodes();
/** /**
* Returns crafting patterns from an item stack. * Returns crafting patterns from an item stack.
* *

View File

@@ -0,0 +1,13 @@
package refinedstorage.api.network;
import net.minecraft.util.math.BlockPos;
import java.util.List;
public interface INetworkNodeGraph {
void rebuild(BlockPos start);
List<INetworkNode> all();
void disconnectAll();
}

View File

@@ -0,0 +1,148 @@
package refinedstorage.apiimpl.network;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import refinedstorage.api.network.INetworkNode;
import refinedstorage.api.network.INetworkNodeGraph;
import refinedstorage.tile.TileNetworkTransmitter;
import refinedstorage.tile.controller.TileController;
import java.util.*;
public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller;
private List<INetworkNode> nodes = new ArrayList<INetworkNode>();
private Set<BlockPos> nodesPos = new HashSet<BlockPos>();
public NetworkNodeGraph(TileController controller) {
this.controller = controller;
}
@Override
public void rebuild(BlockPos start) {
if (!controller.canRun()) {
if (!nodes.isEmpty()) {
disconnectAll();
}
return;
}
World world = getWorld();
List<INetworkNode> newNodes = new ArrayList<INetworkNode>();
List<INetworkNode> interDimensionalNodes = new ArrayList<INetworkNode>();
Set<BlockPos> newNodesPos = new HashSet<BlockPos>();
Set<BlockPos> checked = new HashSet<BlockPos>();
Queue<BlockPos> toCheck = new ArrayDeque<BlockPos>();
checked.add(start);
toCheck.add(start);
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = start.offset(facing);
checked.add(pos);
toCheck.add(pos);
}
BlockPos currentPos;
while ((currentPos = toCheck.poll()) != null) {
TileEntity tile = world.getTileEntity(currentPos);
if (tile instanceof TileController && !controller.getPos().equals(tile.getPos())) {
world.createExplosion(null, tile.getPos().getX(), tile.getPos().getY(), tile.getPos().getZ(), 4.5f, true);
}
if (!(tile instanceof INetworkNode)) {
continue;
}
INetworkNode node = (INetworkNode) tile;
newNodes.add(node);
newNodesPos.add(node.getPosition());
if (tile instanceof TileNetworkTransmitter) {
final TileNetworkTransmitter transmitter = (TileNetworkTransmitter) tile;
if (transmitter.canTransmit()) {
if (!transmitter.isInSameDimension()) {
NetworkNodeGraph dimensionGraph = new NetworkNodeGraph(controller) {
@Override
public World getWorld() {
return DimensionManager.getWorld(transmitter.getReceiverDimension());
}
};
dimensionGraph.rebuild(transmitter.getReceiver());
interDimensionalNodes.addAll(dimensionGraph.all());
} else {
BlockPos receiver = transmitter.getReceiver();
if (checked.add(receiver)) {
toCheck.add(receiver);
}
}
}
}
if (node.canConduct()) {
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = currentPos.offset(facing);
if (checked.add(pos)) {
toCheck.add(pos);
}
}
}
}
List<INetworkNode> oldNodes = new ArrayList<INetworkNode>(nodes);
Set<BlockPos> oldNodesPos = new HashSet<BlockPos>(nodesPos);
this.nodes = newNodes;
this.nodesPos = newNodesPos;
for (INetworkNode newNode : nodes) {
if (!oldNodesPos.contains(newNode.getPosition())) {
newNode.onConnected(controller);
}
}
for (INetworkNode oldNode : oldNodes) {
if (!nodesPos.contains(oldNode.getPosition())) {
oldNode.onDisconnected(controller);
}
}
this.nodes.addAll(interDimensionalNodes);
}
@Override
public List<INetworkNode> all() {
return nodes;
}
@Override
public void disconnectAll() {
for (INetworkNode node : nodes) {
if (node.isConnected()) {
node.onDisconnected(controller);
}
}
nodes.clear();
nodesPos.clear();
}
public World getWorld() {
return controller.getWorld();
}
}

View File

@@ -37,7 +37,7 @@ public class WirelessGridHandler implements IWirelessGridHandler {
public boolean onOpen(EntityPlayer player, EnumHand hand) { public boolean onOpen(EntityPlayer player, EnumHand hand) {
boolean inRange = false; boolean inRange = false;
for (INetworkNode node : network.getNodes()) { for (INetworkNode node : network.getNodeGraph().all()) {
if (node instanceof IWirelessTransmitter) { if (node instanceof IWirelessTransmitter) {
IWirelessTransmitter transmitter = (IWirelessTransmitter) node; IWirelessTransmitter transmitter = (IWirelessTransmitter) node;

View File

@@ -30,7 +30,7 @@ public class GroupedStorage implements IGroupedStorage {
public void rebuild() { public void rebuild() {
storages.clear(); storages.clear();
for (INetworkNode node : network.getNodes()) { for (INetworkNode node : network.getNodeGraph().all()) {
if (node.canUpdate() && node instanceof IStorageProvider) { if (node.canUpdate() && node instanceof IStorageProvider) {
((IStorageProvider) node).addStorages(storages); ((IStorageProvider) node).addStorages(storages);
} }

View File

@@ -104,7 +104,7 @@ public class BlockController extends BlockBase {
@Override @Override
public void breakBlock(World world, BlockPos pos, IBlockState state) { public void breakBlock(World world, BlockPos pos, IBlockState state) {
if (!world.isRemote) { if (!world.isRemote) {
((TileController) world.getTileEntity(pos)).disconnectAll(); ((TileController) world.getTileEntity(pos)).getNodeGraph().disconnectAll();
} }
super.breakBlock(world, pos, state); super.breakBlock(world, pos, state);
@@ -115,7 +115,7 @@ public class BlockController extends BlockBase {
super.neighborChanged(state, world, pos, block); super.neighborChanged(state, world, pos, block);
if (!world.isRemote) { if (!world.isRemote) {
((TileController) world.getTileEntity(pos)).rebuildNodes(); ((TileController) world.getTileEntity(pos)).getNodeGraph().rebuild(pos);
} }
} }

View File

@@ -63,7 +63,7 @@ public abstract class BlockNode extends BlockBase {
TileEntity tile = world.getTileEntity(pos.offset(facing)); TileEntity tile = world.getTileEntity(pos.offset(facing));
if (tile instanceof TileNode && ((TileNode) tile).isConnected()) { if (tile instanceof TileNode && ((TileNode) tile).isConnected()) {
((TileNode) tile).getNetwork().rebuildNodes(); ((TileNode) tile).getNetwork().getNodeGraph().rebuild(((TileNode) tile).getNetwork().getPosition());
break; break;
} }
@@ -86,7 +86,7 @@ public abstract class BlockNode extends BlockBase {
super.breakBlock(world, pos, state); super.breakBlock(world, pos, state);
if (network != null) { if (network != null) {
network.rebuildNodes(); network.getNodeGraph().rebuild(network.getPosition());
} }
} }
} }

View File

@@ -39,8 +39,6 @@ public class GuiNetworkTransmitter extends GuiBase {
distance = t("gui.refinedstorage:network_transmitter.different_dimension"); distance = t("gui.refinedstorage:network_transmitter.different_dimension");
} else if (networkTransmitter.getDistance() == -1) { } else if (networkTransmitter.getDistance() == -1) {
distance = t("gui.refinedstorage:network_transmitter.missing_card"); distance = t("gui.refinedstorage:network_transmitter.missing_card");
} else if (!networkTransmitter.isReceiverValid()) {
distance = t("gui.refinedstorage:network_transmitter.missing_receiver");
} else { } else {
distance = t("gui.refinedstorage:network_transmitter.distance", networkTransmitter.getDistance()); distance = t("gui.refinedstorage:network_transmitter.distance", networkTransmitter.getDistance());
} }

View File

@@ -28,7 +28,7 @@ public class TileNetworkTransmitter extends TileNode {
} }
if (network != null) { if (network != null) {
network.rebuildNodes(); network.getNodeGraph().rebuild(network.getPosition());
} }
} }
}; };
@@ -39,7 +39,6 @@ public class TileNetworkTransmitter extends TileNode {
// Used clientside // Used clientside
private int distance; private int distance;
private boolean inSameDimension; private boolean inSameDimension;
private boolean receiverValid;
public TileNetworkTransmitter() { public TileNetworkTransmitter() {
rebuildOnUpdateChange = true; rebuildOnUpdateChange = true;
@@ -50,10 +49,7 @@ public class TileNetworkTransmitter extends TileNode {
} }
public boolean canTransmit() { public boolean canTransmit() {
return canUpdate() return canUpdate() && receiver != null;
&& receiver != null
&& isInSameDimension()
&& isReceiverValid();
} }
@Override @Override
@@ -78,7 +74,6 @@ public class TileNetworkTransmitter extends TileNode {
buf.writeInt((receiver != null && isInSameDimension()) ? getDistance() : -1); buf.writeInt((receiver != null && isInSameDimension()) ? getDistance() : -1);
buf.writeBoolean(isInSameDimension()); buf.writeBoolean(isInSameDimension());
buf.writeBoolean(isReceiverValid());
} }
@Override @Override
@@ -87,7 +82,6 @@ public class TileNetworkTransmitter extends TileNode {
distance = buf.readInt(); distance = buf.readInt();
inSameDimension = buf.readBoolean(); inSameDimension = buf.readBoolean();
receiverValid = buf.readBoolean();
} }
@Override @Override
@@ -108,6 +102,10 @@ public class TileNetworkTransmitter extends TileNode {
return receiver; return receiver;
} }
public int getReceiverDimension() {
return receiverDimension;
}
public int getDistance() { public int getDistance() {
if (worldObj.isRemote) { if (worldObj.isRemote) {
return distance; return distance;
@@ -123,8 +121,4 @@ public class TileNetworkTransmitter extends TileNode {
public boolean isInSameDimension() { public boolean isInSameDimension() {
return worldObj.isRemote ? inSameDimension : worldObj.provider.getDimension() == receiverDimension; return worldObj.isRemote ? inSameDimension : worldObj.provider.getDimension() == receiverDimension;
} }
public boolean isReceiverValid() {
return worldObj.isRemote ? receiverValid : (receiver != null && isInSameDimension() && worldObj.getTileEntity(receiver) instanceof TileNetworkReceiver);
}
} }

View File

@@ -45,7 +45,7 @@ public abstract class TileNode extends TileBase implements INetworkNode, ISynchr
onConnectionChange(network, update); onConnectionChange(network, update);
if (rebuildOnUpdateChange) { if (rebuildOnUpdateChange) {
network.rebuildNodes(); network.getNodeGraph().rebuild(network.getPosition());
} }
} }

View File

@@ -13,7 +13,6 @@ import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
@@ -26,10 +25,7 @@ import refinedstorage.RefinedStorageBlocks;
import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.ICraftingPattern;
import refinedstorage.api.autocrafting.ICraftingPatternContainer; import refinedstorage.api.autocrafting.ICraftingPatternContainer;
import refinedstorage.api.autocrafting.ICraftingTask; import refinedstorage.api.autocrafting.ICraftingTask;
import refinedstorage.api.network.IGridHandler; import refinedstorage.api.network.*;
import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.network.INetworkNode;
import refinedstorage.api.network.IWirelessGridHandler;
import refinedstorage.api.storage.CompareUtils; import refinedstorage.api.storage.CompareUtils;
import refinedstorage.api.storage.IGroupedStorage; import refinedstorage.api.storage.IGroupedStorage;
import refinedstorage.api.storage.IStorage; import refinedstorage.api.storage.IStorage;
@@ -37,6 +33,7 @@ import refinedstorage.apiimpl.autocrafting.BasicCraftingTask;
import refinedstorage.apiimpl.autocrafting.CraftingPattern; import refinedstorage.apiimpl.autocrafting.CraftingPattern;
import refinedstorage.apiimpl.autocrafting.ProcessingCraftingTask; import refinedstorage.apiimpl.autocrafting.ProcessingCraftingTask;
import refinedstorage.apiimpl.network.GridHandler; import refinedstorage.apiimpl.network.GridHandler;
import refinedstorage.apiimpl.network.NetworkNodeGraph;
import refinedstorage.apiimpl.network.WirelessGridHandler; import refinedstorage.apiimpl.network.WirelessGridHandler;
import refinedstorage.apiimpl.storage.GroupedStorage; import refinedstorage.apiimpl.storage.GroupedStorage;
import refinedstorage.block.BlockController; import refinedstorage.block.BlockController;
@@ -49,7 +46,6 @@ import refinedstorage.network.MessageGridUpdate;
import refinedstorage.tile.ISynchronizedContainer; import refinedstorage.tile.ISynchronizedContainer;
import refinedstorage.tile.TileBase; import refinedstorage.tile.TileBase;
import refinedstorage.tile.TileCrafter; import refinedstorage.tile.TileCrafter;
import refinedstorage.tile.TileNetworkTransmitter;
import refinedstorage.tile.config.IRedstoneModeConfig; import refinedstorage.tile.config.IRedstoneModeConfig;
import refinedstorage.tile.config.RedstoneMode; import refinedstorage.tile.config.RedstoneMode;
import refinedstorage.tile.externalstorage.ExternalStorage; import refinedstorage.tile.externalstorage.ExternalStorage;
@@ -93,8 +89,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
} }
}; };
private List<INetworkNode> nodes = new ArrayList<INetworkNode>(); private INetworkNodeGraph nodeGraph = new NetworkNodeGraph(this);
private Set<BlockPos> nodesPos = new HashSet<BlockPos>();
private List<ICraftingPattern> patterns = new ArrayList<ICraftingPattern>(); private List<ICraftingPattern> patterns = new ArrayList<ICraftingPattern>();
@@ -139,6 +134,11 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
return energy.getEnergyStored() > 0 && redstoneMode.isEnabled(worldObj, pos); return energy.getEnergyStored() > 0 && redstoneMode.isEnabled(worldObj, pos);
} }
@Override
public INetworkNodeGraph getNodeGraph() {
return nodeGraph;
}
@Override @Override
public void update() { public void update() {
if (!worldObj.isRemote) { if (!worldObj.isRemote) {
@@ -189,7 +189,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
if (couldRun != canRun()) { if (couldRun != canRun()) {
couldRun = canRun(); couldRun = canRun();
rebuildNodes(); nodeGraph.rebuild(pos);
} }
if (getEnergyScaledForDisplay() != lastEnergyDisplay) { if (getEnergyScaledForDisplay() != lastEnergyDisplay) {
@@ -224,17 +224,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
} }
} }
public void disconnectAll() {
for (INetworkNode node : nodes) {
if (node.isConnected()) {
node.onDisconnected(this);
}
}
nodes.clear();
nodesPos.clear();
}
@Override @Override
public void invalidate() { public void invalidate() {
super.invalidate(); super.invalidate();
@@ -244,11 +233,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
} }
} }
@Override
public List<INetworkNode> getNodes() {
return nodes;
}
public List<ClientNode> getClientNodes() { public List<ClientNode> getClientNodes() {
return clientNodes; return clientNodes;
} }
@@ -364,7 +348,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
public void rebuildPatterns() { public void rebuildPatterns() {
patterns.clear(); patterns.clear();
for (INetworkNode node : nodes) { for (INetworkNode node : nodeGraph.all()) {
if (node instanceof TileCrafter && node.canUpdate()) { if (node instanceof TileCrafter && node.canUpdate()) {
TileCrafter crafter = (TileCrafter) node; TileCrafter crafter = (TileCrafter) node;
@@ -387,84 +371,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
storage.rebuild(); storage.rebuild();
} }
@Override
public void rebuildNodes() {
if (!canRun()) {
if (!nodes.isEmpty()) {
disconnectAll();
}
return;
}
List<INetworkNode> newNodes = new ArrayList<INetworkNode>();
Set<BlockPos> newNodesPos = new HashSet<BlockPos>();
Set<BlockPos> checked = new HashSet<BlockPos>();
Queue<BlockPos> toCheck = new ArrayDeque<BlockPos>();
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = this.pos.offset(facing);
checked.add(pos);
toCheck.add(pos);
}
BlockPos currentPos;
while ((currentPos = toCheck.poll()) != null) {
TileEntity tile = worldObj.getTileEntity(currentPos);
if (tile instanceof TileController && !pos.equals(tile.getPos())) {
worldObj.createExplosion(null, tile.getPos().getX(), tile.getPos().getY(), tile.getPos().getZ(), 4.5f, true);
}
if (!(tile instanceof INetworkNode)) {
continue;
}
INetworkNode node = (INetworkNode) tile;
newNodes.add(node);
newNodesPos.add(node.getPosition());
if (tile instanceof TileNetworkTransmitter) {
BlockPos receiver = ((TileNetworkTransmitter) tile).getReceiver();
if (((TileNetworkTransmitter) tile).canTransmit() && checked.add(receiver)) {
toCheck.add(receiver);
}
}
if (node.canConduct()) {
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = currentPos.offset(facing);
if (checked.add(pos)) {
toCheck.add(pos);
}
}
}
}
List<INetworkNode> oldNodes = new ArrayList<INetworkNode>(nodes);
Set<BlockPos> oldNodesPos = new HashSet<BlockPos>(nodesPos);
this.nodes = newNodes;
this.nodesPos = newNodesPos;
for (INetworkNode newNode : nodes) {
if (!oldNodesPos.contains(newNode.getPosition())) {
newNode.onConnected(this);
}
}
for (INetworkNode oldNode : oldNodes) {
if (!nodesPos.contains(oldNode.getPosition())) {
oldNode.onDisconnected(this);
}
}
}
@Override @Override
public void sendStorageToClient() { public void sendStorageToClient() {
for (EntityPlayer player : worldObj.playerEntities) { for (EntityPlayer player : worldObj.playerEntities) {
@@ -707,7 +613,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
if (!worldObj.isRemote) { if (!worldObj.isRemote) {
int usage = RefinedStorage.INSTANCE.controllerBaseUsage; int usage = RefinedStorage.INSTANCE.controllerBaseUsage;
for (INetworkNode node : nodes) { for (INetworkNode node : nodeGraph.all()) {
if (node.canUpdate()) { if (node.canUpdate()) {
usage += node.getEnergyUsage(); usage += node.getEnergyUsage();
} }
@@ -759,7 +665,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR
List<ClientNode> clientNodes = new ArrayList<ClientNode>(); List<ClientNode> clientNodes = new ArrayList<ClientNode>();
for (INetworkNode node : nodes) { for (INetworkNode node : nodeGraph.all()) {
if (node.canUpdate()) { if (node.canUpdate()) {
IBlockState state = worldObj.getBlockState(node.getPosition()); IBlockState state = worldObj.getBlockState(node.getPosition());