package mcjty.rftools.items.netmonitor; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import io.netty.buffer.ByteBuf; import mcjty.lib.varia.Coordinate; import mcjty.rftools.BlockInfo; import mcjty.rftools.varia.EnergyTools; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import java.util.*; public class PacketGetConnectedBlocks implements IMessage, IMessageHandler<PacketGetConnectedBlocks, PacketConnectedBlocksReady> { private int x; private int y; private int z; @Override public void fromBytes(ByteBuf buf) { x = buf.readInt(); y = buf.readInt(); z = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(x); buf.writeInt(y); buf.writeInt(z); } public PacketGetConnectedBlocks() { } public PacketGetConnectedBlocks(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } @Override public PacketConnectedBlocksReady onMessage(PacketGetConnectedBlocks message, MessageContext ctx) { EntityPlayer player = ctx.getServerHandler().playerEntity; Map<Coordinate,BlockInfo> connectedBlocks = new HashMap<Coordinate, BlockInfo>(); findConnectedBlocks(connectedBlocks, player.worldObj, message.x, message.y, message.z); if (connectedBlocks.size() > NetworkMonitorConfiguration.maximumBlocks) { connectedBlocks = compactConnectedBlocks(connectedBlocks, message.x, message.y, message.z, NetworkMonitorConfiguration.maximumBlocks); } int minx = 300000000; int miny = 300000000; int minz = 300000000; for (Coordinate coordinate : connectedBlocks.keySet()) { minx = Math.min(minx, coordinate.getX()); miny = Math.min(miny, coordinate.getY()); minz = Math.min(minz, coordinate.getZ()); } return new PacketConnectedBlocksReady(connectedBlocks, minx, miny, minz); } private Map<Coordinate,BlockInfo> compactConnectedBlocks(Map<Coordinate,BlockInfo> old, final int x, final int y, final int z, int max) { List<Coordinate> list = new ArrayList<Coordinate>(old.keySet()); Collections.sort(list, new Comparator<Coordinate>() { @Override public int compare(Coordinate o1, Coordinate o2) { double sqdist1 = calcDist(o1); double sqdist2 = calcDist(o2); if (sqdist1 < sqdist2) { return -1; } else if (sqdist1 > sqdist2) { return 1; } else { return 0; } } private int calcDist(Coordinate o1) { return (o1.getX()-x) * (o1.getX()-x) + (o1.getY()-y) * (o1.getY()-y) + (o1.getZ()-z) * (o1.getZ()-z); } }); Map<Coordinate,BlockInfo> connectedBlocks = new HashMap<Coordinate, BlockInfo>(); for (Coordinate coordinate : list) { connectedBlocks.put(coordinate, old.get(coordinate)); max--; if (max <= 0) { break; } } return connectedBlocks; } private void findConnectedBlocks(Map<Coordinate,BlockInfo> connectedBlocks, World world, int x, int y, int z) { if (y < 0 || y >= world.getHeight()) { return; } Coordinate c = new Coordinate(x, y, z); if (connectedBlocks.containsKey(c)) { return; } TileEntity tileEntity = world.getTileEntity(x, y, z); if (tileEntity != null) { if (EnergyTools.isEnergyTE(tileEntity)) { connectedBlocks.put(c, new BlockInfo(tileEntity, c)); findConnectedBlocks(connectedBlocks, world, x + 1, y, z); findConnectedBlocks(connectedBlocks, world, x - 1, y, z); findConnectedBlocks(connectedBlocks, world, x, y - 1, z); findConnectedBlocks(connectedBlocks, world, x, y + 1, z); findConnectedBlocks(connectedBlocks, world, x, y, z - 1); findConnectedBlocks(connectedBlocks, world, x, y, z + 1); } } } }