diff --git a/Universal-Electricity b/Universal-Electricity index 117d3ca17..726693735 160000 --- a/Universal-Electricity +++ b/Universal-Electricity @@ -1 +1 @@ -Subproject commit 117d3ca17939777f44bf413404c673f37db545e0 +Subproject commit 726693735ab79731cf4d40bb941b6d9d5bf30de4 diff --git a/src/main/java/resonantinduction/wire/part/PartFlatWire.java b/src/main/java/resonantinduction/wire/part/PartFlatWire.java index 5879ba4ca..26883f5af 100644 --- a/src/main/java/resonantinduction/wire/part/PartFlatWire.java +++ b/src/main/java/resonantinduction/wire/part/PartFlatWire.java @@ -37,869 +37,834 @@ import codechicken.multipart.TileMultipart; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -/** - * This is the base class for all wire types. It can be used for any sub type, - * as it contains the base calculations necessary to create a working wire. This - * calculates all possible connections to sides, around corners, and inside - * corners, while checking for microblock obstructions. +/** This is the base class for all wire types. It can be used for any sub type, as it contains the + * base calculations necessary to create a working wire. This calculates all possible connections to + * sides, around corners, and inside corners, while checking for microblock obstructions. * - * @author Modified by Calclavia, MrTJP - * - */ + * @author Modified by Calclavia, MrTJP */ public class PartFlatWire extends PartAdvancedWire implements TFacePart, JNormalOcclusion { - public static Cuboid6[][] selectionBounds = new Cuboid6[3][6]; - public static Cuboid6[][] occlusionBounds = new Cuboid6[3][6]; - - static - { - for (int t = 0; t < 3; t++) - { - // Subtract the box a little because we'd like things like posts to get first hit - Cuboid6 selection = new Cuboid6(0, 0, 0, 1, (t + 2) / 16D, 1).expand(-0.005); - Cuboid6 occlusion = new Cuboid6(2 / 8D, 0, 2 / 8D, 6 / 8D, (t + 2) / 16D, 6 / 8D); - for (int s = 0; s < 6; s++) - { - selectionBounds[t][s] = selection.copy().apply(Rotation.sideRotations[s].at(Vector3.center)); - occlusionBounds[t][s] = occlusion.copy().apply(Rotation.sideRotations[s].at(Vector3.center)); - } - } - } - - public byte side; - - /** - * A map of the corners. - * - * - * Currently split into 4 nybbles (from lowest) - * 0 = Corner connections (this wire should connect around a corner to something external) - * 1 = Straight connections (this wire should connect to something external) - * 2 = Internal connections (this wire should connect to something internal) - * 3 = Internal open connections (this wire is not blocked by a cover/edge part and *could* - * connect through side) - * bit 16 = connection to the centerpart - * 5 = Render corner connections. Like corner connections but set to low if the other wire part - * is smaller than this (they render to us not us to them) - */ - public int connMap; - - public PartFlatWire() - { - - } - - public PartFlatWire(int typeID) - { - this(EnumWireMaterial.values()[typeID]); - } - - public PartFlatWire(EnumWireMaterial type) - { - material = type; - } - - public void preparePlacement(int side, int meta) - { - this.side = (byte) (side ^ 1); - this.setMaterial(meta); - } - - /** - * PACKET and NBT Methods - */ - @Override - public void load(NBTTagCompound tag) - { - super.load(tag); - this.side = tag.getByte("side"); - this.connMap = tag.getInteger("connMap"); - } - - @Override - public void save(NBTTagCompound tag) - { - super.save(tag); - tag.setByte("side", this.side); - tag.setInteger("connMap", this.connMap); - } - - @Override - public void readDesc(MCDataInput packet) - { - super.readDesc(packet); - this.side = packet.readByte(); - this.connMap = packet.readInt(); - } - - @Override - public void writeDesc(MCDataOutput packet) - { - super.writeDesc(packet); - packet.writeByte(this.side); - packet.writeInt(this.connMap); - } - - @Override - public void read(MCDataInput packet) - { - read(packet, packet.readUByte()); - } - - @Override - public void read(MCDataInput packet, int packetID) - { - if (packetID == 0) - { - this.connMap = packet.readInt(); - tile().markRender(); - } - else - { - super.read(packet, packetID); - } - } - - public void sendConnUpdate() - { - tile().getWriteStream(this).writeByte(0).writeInt(this.connMap); - } - - /** - * WORLD EVENTS - */ - @Override - public void onRemoved() - { - super.onRemoved(); - - if (!world().isRemote) - { - for (int r = 0; r < 4; r++) - { - if (maskConnects(r)) - { - if ((connMap & 1 << r) != 0) - { - notifyCornerChange(r); - } - else if ((connMap & 0x10 << r) != 0) - { - notifyStraightChange(r); - } - } - } - } - } - - @Override - public void onChunkLoad() - { - if ((connMap & 0x80000000) != 0) // compat with converters, recalc connections - { - if (dropIfCantStay()) - { - return; - } - - connMap = 0; - - updateInternalConnections(); - - if (updateOpenConnections()) - { - updateExternalConnections(); - } - - tile().markDirty(); - } - - this.recalculateConnections(); - - super.onChunkLoad(); - } - - @Override - public void onAdded() - { - super.onAdded(); - - if (!world().isRemote) - { - updateOpenConnections(); - boolean changed = updateInternalConnections(); - // don't use || because it's fail fast - changed |= updateExternalConnections(); - - if (changed) - { - sendConnUpdate(); - } - - this.recalculateConnections(); - } - } - - @Override - public void onPartChanged(TMultiPart part) - { - if (!world().isRemote) - { - boolean changed = updateInternalConnections(); - - if (updateOpenConnections()) - { - changed |= updateExternalConnections(); - } - - if (changed) - { - sendConnUpdate(); - } - - this.recalculateConnections(); - } - - super.onPartChanged(part); - } - - @Override - public void onNeighborChanged() - { - if (!world().isRemote) - { - if (dropIfCantStay()) - { - return; - } - - if (updateExternalConnections()) - { - sendConnUpdate(); - } - - this.recalculateConnections(); - } - super.onNeighborChanged(); - } - - @Override - public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item) - { - if (!world().isRemote) - { - System.out.println(this.getNetwork()); - } - - return super.activate(player, part, item); - } - - @Override - public void recalculateConnections() - { - this.updateOpenConnections(); - - boolean[] calculatedSides = new boolean[6]; - - /** - * Check external connections. - */ - for (byte r = 0; r < 4; r++) - { - if (maskOpen(r)) - { - int absDir = Rotation.rotateSide(this.side, r); - - // Check direct connection. - if (this.setExternalConnection(r, absDir)) - { - calculatedSides[absDir] = true; - } - - // Check Corner Connection - BlockCoord cornerPos = new BlockCoord(tile()); - cornerPos.offset(absDir); - - if (canConnectThroughCorner(cornerPos, absDir ^ 1, this.side)) - { - cornerPos.offset(this.side); - TileMultipart tpCorner = Utility.getMultipartTile(world(), cornerPos); - - if (tpCorner != null) - { - TMultiPart tp = tpCorner.partMap(absDir ^ 1); - - if (this.canConnectTo(tp)) - { - // We found a wire, merge networks! - this.connections[absDir] = tp; - this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); - calculatedSides[absDir] = true; - continue; - } - } - } - - if (!calculatedSides[absDir]) - { - this.disconnect(absDir); - } - } - } - - /** - * Check internal connections. - */ - for (byte r = 0; r < 4; r++) - { - int absDir = Rotation.rotateSide(this.side, r); - - /** - * Look for an internal straight connection. - */ - if (tile().partMap(PartMap.edgeBetween(absDir, this.side)) == null) - { - TMultiPart tp = tile().partMap(absDir); - - if (this.canConnectTo(tp)) - { - // We found a wire! Merge networks! - this.connections[absDir] = tp; - this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); - continue; - } - } - - if (!calculatedSides[absDir]) - { - this.disconnect(absDir); - } - } - - // Connect to the face of the block the wire is placed on. - this.setExternalConnection(-1, this.side); - - this.getNetwork().reconstruct(); - } - - public boolean setExternalConnection(int r, int absSide) - { - BlockCoord pos = new BlockCoord(tile()).offset(absSide); - - /** - * Look for an external wire connection. - */ - TileMultipart t = Utility.getMultipartTile(world(), pos); - - if (t != null && r != -1) - { - TMultiPart tp = t.partMap(this.side); - - if (this.canConnectTo(tp)) - { - // Check the wire we are connecting to and see if THAT block can accept this one. - int otherR = (r + 2) % 4; - - if (((PartFlatWire) tp).canConnectTo(this) && ((PartFlatWire) tp).maskOpen(otherR)) - { - // We found a wire! Merge connection. - this.connections[absSide] = tp; - this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); - return true; - } - } - - this.disconnect(absSide); - } - - /** - * Look for an external energy handler. - */ - TileEntity tileEntity = world().getBlockTileEntity(pos.x, pos.y, pos.z); - - if (this.canConnectTo(tileEntity)) - { - this.connections[absSide] = tileEntity; - return true; - } - - this.disconnect(absSide); - - return false; - } - - private void disconnect(int i) - { - if (this.connections[i] != null) - { - if (this.connections[i] instanceof PartFlatWire) - { - PartFlatWire wire = (PartFlatWire) this.connections[i]; - this.connections[i] = null; - this.getNetwork().split(this, wire); - } - else - { - this.connections[i] = null; - } - } - } - - @Override - public Object[] getConnections() - { - return this.connections; - } - - public boolean canStay() - { - BlockCoord pos = new BlockCoord(tile()).offset(side); - return Utility.canPlaceWireOnSide(world(), pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side ^ 1), false); - } - - public boolean dropIfCantStay() - { - if (!canStay()) - { - drop(); - return true; - } - return false; - } - - public void drop() - { - TileMultipart.dropItem(getItem(), world(), Vector3.fromTileEntityCenter(tile())); - tile().remPart(this); - } - - /** - * Recalculates connections to blocks outside this space - * - * @return true if a new connection was added or one was removed - */ - protected boolean updateExternalConnections() - { - int newConn = 0; - - for (int r = 0; r < 4; r++) - { - if (!maskOpen(r)) - { - continue; - } - - if (connectStraight(r)) - { - newConn |= 0x10 << r; - } - else - { - int cnrMode = connectCorner(r); - - if (cnrMode != 0) - { - newConn |= 1 << r; - - if (cnrMode == 2) - { - newConn |= 0x100000 << r;// render flag - } - } - } - } - - if (newConn != (connMap & 0xF000FF)) - { - int diff = connMap ^ newConn; - connMap = connMap & ~0xF000FF | newConn; - - // Notify corner disconnections - for (int r = 0; r < 4; r++) - { - if ((diff & 1 << r) != 0) - { - notifyCornerChange(r); - } - } - - return true; - } - - return false; - } - - /** - * Recalculates connections to other parts within this space - * - * @return true if a new connection was added or one was removed - */ - protected boolean updateInternalConnections() - { - int newConn = 0; - for (int r = 0; r < 4; r++) - { - if (connectInternal(r)) - { - newConn |= 0x100 << r; - } - } - - if (connectCenter()) - { - newConn |= 0x10000; - } - - if (newConn != (connMap & 0x10F00)) - { - connMap = connMap & ~0x10F00 | newConn; - return true; - } - return false; - } - - /** - * Recalculates connections that can be made to other parts outside of this - * space - * - * @return true if external connections should be recalculated - */ - protected boolean updateOpenConnections() - { - int newConn = 0; - for (int r = 0; r < 4; r++) - if (connectionOpen(r)) - newConn |= 0x1000 << r; - - if (newConn != (connMap & 0xF000)) - { - connMap = connMap & ~0xF000 | newConn; - return true; - } - return false; - } - - public boolean connectionOpen(int r) - { - int absDir = Rotation.rotateSide(side, r); - TMultiPart facePart = tile().partMap(absDir); - if (facePart != null && (!(facePart instanceof PartFlatWire) || !canConnectTo((PartFlatWire) facePart))) - return false; - - if (tile().partMap(PartMap.edgeBetween(side, absDir)) != null) - return false; - - return true; - } - - /** - * Return a corner connection state. - * 0 = No connection - * 1 = Physical connection - * 2 = Render connection - */ - public int connectCorner(int r) - { - int absDir = Rotation.rotateSide(side, r); - - BlockCoord pos = new BlockCoord(tile()); - pos.offset(absDir); - - if (!canConnectThroughCorner(pos, absDir ^ 1, side)) - return 0; - - pos.offset(side); - TileMultipart t = Utility.getMultipartTile(world(), pos); - if (t != null) - { - TMultiPart tp = t.partMap(absDir ^ 1); - - if (canConnectTo(tp)) - { - boolean b = ((PartFlatWire) tp).connectCorner(this, Rotation.rotationTo(absDir ^ 1, side ^ 1)); - - if (b) - { - // let them connect to us - if (!renderThisCorner((PartFlatWire) tp)) - { - return 1; - } - - return 2; - } - } - } - return 0; - } - - public boolean canConnectThroughCorner(BlockCoord pos, int side1, int side2) - { - if (world().isAirBlock(pos.x, pos.y, pos.z)) - { - return true; - } - - TileMultipart t = Utility.getMultipartTile(world(), pos); - if (t != null) - { - return t.partMap(side1) == null && t.partMap(side2) == null && t.partMap(PartMap.edgeBetween(side1, side2)) == null; - } - - return false; - } - - public boolean connectStraight(int r) - { - int absDir = Rotation.rotateSide(side, r); - - BlockCoord pos = new BlockCoord(tile()).offset(absDir); - - TileMultipart t = Utility.getMultipartTile(world(), pos); - if (t != null) - { - TMultiPart tp = t.partMap(side); - - if (this.canConnectTo(tp)) - { - return ((PartFlatWire) tp).connectStraight(this, (r + 2) % 4); - } - } - else - { - TileEntity tileEntity = world().getBlockTileEntity(pos.x, pos.y, pos.z); - return this.canConnectTo(tileEntity); - } - - return false; - } - - public boolean connectInternal(int r) - { - int absDir = Rotation.rotateSide(side, r); - - if (tile().partMap(PartMap.edgeBetween(absDir, side)) != null) - return false; - - TMultiPart tp = tile().partMap(absDir); - - if (this.canConnectTo(tp)) - { - return ((PartFlatWire) tp).connectInternal(this, Rotation.rotationTo(absDir, side)); - } - - return connectInternalOverride(tp, r); - } - - public boolean connectInternalOverride(TMultiPart p, int r) - { - return false; - } - - public boolean connectCenter() - { - TMultiPart tp = tile().partMap(6); - - if (this.canConnectTo(tp)) - { - return ((PartFlatWire) tp).connectInternal(this, side); - } - - return false; - } - - public boolean renderThisCorner(PartFlatWire part) - { - if (!(part instanceof PartFlatWire)) - return false; - - PartFlatWire wire = (PartFlatWire) part; - if (wire.getThickness() == getThickness()) - return side < wire.side; - - return wire.getThickness() > getThickness(); - } - - public boolean connectCorner(PartFlatWire wire, int r) - { - if (this.canConnectTo(wire) && maskOpen(r)) - { - int oldConn = connMap; - connMap |= 0x1 << r; - if (renderThisCorner(wire))// render connection - connMap |= 0x100000 << r; - - if (oldConn != connMap) - sendConnUpdate(); - return true; - } - return false; - } - - public boolean connectStraight(PartFlatWire wire, int r) - { - if (this.canConnectTo(wire) && maskOpen(r)) - { - int oldConn = connMap; - connMap |= 0x10 << r; - if (oldConn != connMap) - sendConnUpdate(); - return true; - } - return false; - } - - public boolean connectInternal(PartFlatWire wire, int r) - { - if (this.canConnectTo(wire)) - { - int oldConn = connMap; - connMap |= 0x100 << r; - if (oldConn != connMap) - sendConnUpdate(); - return true; - } - return false; - } - - public boolean canConnectCorner(int r) - { - return true; - } - - public void notifyCornerChange(int r) - { - int absDir = Rotation.rotateSide(side, r); - - BlockCoord pos = new BlockCoord(tile()).offset(absDir).offset(side); - world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID); - } - - public void notifyStraightChange(int r) - { - int absDir = Rotation.rotateSide(side, r); - - BlockCoord pos = new BlockCoord(tile()).offset(absDir); - world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID); - } - - public boolean maskConnects(int r) - { - return (connMap & 0x111 << r) != 0; - } - - public boolean maskOpen(int r) - { - return (connMap & 0x1000 << r) != 0; - } - - /** START TILEMULTIPART INTERACTIONS **/ - @Override - public float getStrength(MovingObjectPosition hit, EntityPlayer player) - { - return 4; - } - - @Override - public int getSlotMask() - { - return 1 << this.side; - } - - @Override - public Iterable getSubParts() - { - return Arrays.asList(new IndexedCuboid6(0, selectionBounds[getThickness()][side])); - } - - @Override - public boolean occlusionTest(TMultiPart npart) - { - return NormalOcclusionTest.apply(this, npart); - } - - @Override - public Iterable getOcclusionBoxes() - { - return Arrays.asList(occlusionBounds[getThickness()][side]); - } - - public int getThickness() - { - return this.isInsulated ? 2 : 1; - } - - @Override - public int redstoneConductionMap() - { - return 0; - } - - @Override - public boolean solid(int arg0) - { - return false; - } - - @Override - public String getType() - { - return "resonant_induction_flat_wire"; - } - - /** - * RENDERING - */ - @SideOnly(Side.CLIENT) - public Icon getIcon() - { - return RenderFlatWire.flatWireTexture; - } - - public Colour getColour() - { - return this.isInsulated ? ResonantInduction.DYE_COLORS[this.color] : this.getMaterial().color; - } - - public boolean useStaticRenderer() - { - return true; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderStatic(Vector3 pos, LazyLightMatrix olm, int pass) - { - if (pass == 0 && useStaticRenderer()) - { - CCRenderState.setBrightness(world(), x(), y(), z()); - RenderFlatWire.render(this, pos); - CCRenderState.setColour(-1); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void renderDynamic(Vector3 pos, float frame, int pass) - { - if (pass == 0 && !useStaticRenderer()) - { - GL11.glDisable(GL11.GL_LIGHTING); - TextureUtils.bindAtlas(0); - CCRenderState.useModelColours(true); - CCRenderState.startDrawing(7); - RenderFlatWire.render(this, pos); - CCRenderState.draw(); - CCRenderState.setColour(-1); - GL11.glEnable(GL11.GL_LIGHTING); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void drawBreaking(RenderBlocks renderBlocks) - { - CCRenderState.reset(); - RenderFlatWire.renderBreakingOverlay(renderBlocks.overrideBlockTexture, this); - } + public static Cuboid6[][] selectionBounds = new Cuboid6[3][6]; + public static Cuboid6[][] occlusionBounds = new Cuboid6[3][6]; + + static + { + for (int t = 0; t < 3; t++) + { + // Subtract the box a little because we'd like things like posts to get first hit + Cuboid6 selection = new Cuboid6(0, 0, 0, 1, (t + 2) / 16D, 1).expand(-0.005); + Cuboid6 occlusion = new Cuboid6(2 / 8D, 0, 2 / 8D, 6 / 8D, (t + 2) / 16D, 6 / 8D); + for (int s = 0; s < 6; s++) + { + selectionBounds[t][s] = selection.copy().apply(Rotation.sideRotations[s].at(Vector3.center)); + occlusionBounds[t][s] = occlusion.copy().apply(Rotation.sideRotations[s].at(Vector3.center)); + } + } + } + + public byte side; + + /** A map of the corners. + * + * + * Currently split into 4 nybbles (from lowest) 0 = Corner connections (this wire should connect + * around a corner to something external) 1 = Straight connections (this wire should connect to + * something external) 2 = Internal connections (this wire should connect to something internal) + * 3 = Internal open connections (this wire is not blocked by a cover/edge part and *could* + * connect through side) bit 16 = connection to the centerpart 5 = Render corner connections. + * Like corner connections but set to low if the other wire part is smaller than this (they + * render to us not us to them) */ + public int connMap; + + public PartFlatWire() + { + + } + + public PartFlatWire(int typeID) + { + this(EnumWireMaterial.values()[typeID]); + } + + public PartFlatWire(EnumWireMaterial type) + { + material = type; + } + + public void preparePlacement(int side, int meta) + { + this.side = (byte) (side ^ 1); + this.setMaterial(meta); + } + + /** PACKET and NBT Methods */ + @Override + public void load(NBTTagCompound tag) + { + super.load(tag); + this.side = tag.getByte("side"); + this.connMap = tag.getInteger("connMap"); + } + + @Override + public void save(NBTTagCompound tag) + { + super.save(tag); + tag.setByte("side", this.side); + tag.setInteger("connMap", this.connMap); + } + + @Override + public void readDesc(MCDataInput packet) + { + super.readDesc(packet); + this.side = packet.readByte(); + this.connMap = packet.readInt(); + } + + @Override + public void writeDesc(MCDataOutput packet) + { + super.writeDesc(packet); + packet.writeByte(this.side); + packet.writeInt(this.connMap); + } + + @Override + public void read(MCDataInput packet) + { + read(packet, packet.readUByte()); + } + + @Override + public void read(MCDataInput packet, int packetID) + { + if (packetID == 0) + { + this.connMap = packet.readInt(); + tile().markRender(); + } + else + { + super.read(packet, packetID); + } + } + + public void sendConnUpdate() + { + tile().getWriteStream(this).writeByte(0).writeInt(this.connMap); + } + + /** WORLD EVENTS */ + @Override + public void onRemoved() + { + super.onRemoved(); + + if (!world().isRemote) + { + for (int r = 0; r < 4; r++) + { + if (maskConnects(r)) + { + if ((connMap & 1 << r) != 0) + { + notifyCornerChange(r); + } + else if ((connMap & 0x10 << r) != 0) + { + notifyStraightChange(r); + } + } + } + } + } + + @Override + public void onChunkLoad() + { + if ((connMap & 0x80000000) != 0) // compat with converters, recalc connections + { + if (dropIfCantStay()) + { + return; + } + + connMap = 0; + + updateInternalConnections(); + + if (updateOpenConnections()) + { + updateExternalConnections(); + } + + tile().markDirty(); + } + + this.recalculateConnections(); + + super.onChunkLoad(); + } + + @Override + public void onAdded() + { + super.onAdded(); + + if (!world().isRemote) + { + updateOpenConnections(); + boolean changed = updateInternalConnections(); + // don't use || because it's fail fast + changed |= updateExternalConnections(); + + if (changed) + { + sendConnUpdate(); + } + + this.recalculateConnections(); + } + } + + @Override + public void onPartChanged(TMultiPart part) + { + if (!world().isRemote) + { + boolean changed = updateInternalConnections(); + + if (updateOpenConnections()) + { + changed |= updateExternalConnections(); + } + + if (changed) + { + sendConnUpdate(); + } + + this.recalculateConnections(); + } + + super.onPartChanged(part); + } + + @Override + public void onNeighborChanged() + { + if (!world().isRemote) + { + if (dropIfCantStay()) + { + return; + } + + if (updateExternalConnections()) + { + sendConnUpdate(); + } + + this.recalculateConnections(); + } + super.onNeighborChanged(); + } + + @Override + public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item) + { + if (!world().isRemote) + { + System.out.println(this.getNetwork()); + } + + return super.activate(player, part, item); + } + + @Override + public void recalculateConnections() + { + this.updateOpenConnections(); + + boolean[] calculatedSides = new boolean[6]; + + /** Check external connections. */ + for (byte r = 0; r < 4; r++) + { + if (maskOpen(r)) + { + int absDir = Rotation.rotateSide(this.side, r); + + // Check direct connection. + if (this.setExternalConnection(r, absDir)) + { + calculatedSides[absDir] = true; + } + + // Check Corner Connection + BlockCoord cornerPos = new BlockCoord(tile()); + cornerPos.offset(absDir); + + if (canConnectThroughCorner(cornerPos, absDir ^ 1, this.side)) + { + cornerPos.offset(this.side); + TileMultipart tpCorner = Utility.getMultipartTile(world(), cornerPos); + + if (tpCorner != null) + { + TMultiPart tp = tpCorner.partMap(absDir ^ 1); + + if (this.canConnectTo(tp)) + { + // We found a wire, merge networks! + this.connections[absDir] = tp; + this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); + calculatedSides[absDir] = true; + continue; + } + } + } + + if (!calculatedSides[absDir]) + { + this.disconnect(absDir); + } + } + } + + /** Check internal connections. */ + for (byte r = 0; r < 4; r++) + { + int absDir = Rotation.rotateSide(this.side, r); + + /** Look for an internal straight connection. */ + if (tile().partMap(PartMap.edgeBetween(absDir, this.side)) == null) + { + TMultiPart tp = tile().partMap(absDir); + + if (this.canConnectTo(tp)) + { + // We found a wire! Merge networks! + this.connections[absDir] = tp; + this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); + continue; + } + } + + if (!calculatedSides[absDir]) + { + this.disconnect(absDir); + } + } + + // Connect to the face of the block the wire is placed on. + this.setExternalConnection(-1, this.side); + + this.getNetwork().reconstruct(); + } + + public boolean setExternalConnection(int r, int absSide) + { + BlockCoord pos = new BlockCoord(tile()).offset(absSide); + + /** Look for an external wire connection. */ + TileMultipart t = Utility.getMultipartTile(world(), pos); + + if (t != null && r != -1) + { + TMultiPart tp = t.partMap(this.side); + + if (this.canConnectTo(tp)) + { + // Check the wire we are connecting to and see if THAT block can accept this one. + int otherR = (r + 2) % 4; + + if (tp instanceof PartFlatWire && ((PartFlatWire) tp).canConnectTo(this) && ((PartFlatWire) tp).maskOpen(otherR)) + { + // We found a wire! Merge connection. + this.connections[absSide] = tp; + this.getNetwork().merge(((PartFlatWire) tp).getNetwork()); + return true; + } + } + + this.disconnect(absSide); + } + + /** Look for an external energy handler. */ + TileEntity tileEntity = world().getBlockTileEntity(pos.x, pos.y, pos.z); + + if (this.canConnectTo(tileEntity)) + { + this.connections[absSide] = tileEntity; + return true; + } + + this.disconnect(absSide); + + return false; + } + + private void disconnect(int i) + { + if (this.connections[i] != null) + { + if (this.connections[i] instanceof PartFlatWire) + { + PartFlatWire wire = (PartFlatWire) this.connections[i]; + this.connections[i] = null; + this.getNetwork().split(this, wire); + } + else + { + this.connections[i] = null; + } + } + } + + @Override + public Object[] getConnections() + { + return this.connections; + } + + public boolean canStay() + { + BlockCoord pos = new BlockCoord(tile()).offset(side); + return Utility.canPlaceWireOnSide(world(), pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side ^ 1), false); + } + + public boolean dropIfCantStay() + { + if (!canStay()) + { + drop(); + return true; + } + return false; + } + + public void drop() + { + TileMultipart.dropItem(getItem(), world(), Vector3.fromTileEntityCenter(tile())); + tile().remPart(this); + } + + /** Recalculates connections to blocks outside this space + * + * @return true if a new connection was added or one was removed */ + protected boolean updateExternalConnections() + { + int newConn = 0; + + for (int r = 0; r < 4; r++) + { + if (!maskOpen(r)) + { + continue; + } + + if (connectStraight(r)) + { + newConn |= 0x10 << r; + } + else + { + int cnrMode = connectCorner(r); + + if (cnrMode != 0) + { + newConn |= 1 << r; + + if (cnrMode == 2) + { + newConn |= 0x100000 << r;// render flag + } + } + } + } + + if (newConn != (connMap & 0xF000FF)) + { + int diff = connMap ^ newConn; + connMap = connMap & ~0xF000FF | newConn; + + // Notify corner disconnections + for (int r = 0; r < 4; r++) + { + if ((diff & 1 << r) != 0) + { + notifyCornerChange(r); + } + } + + return true; + } + + return false; + } + + /** Recalculates connections to other parts within this space + * + * @return true if a new connection was added or one was removed */ + protected boolean updateInternalConnections() + { + int newConn = 0; + for (int r = 0; r < 4; r++) + { + if (connectInternal(r)) + { + newConn |= 0x100 << r; + } + } + + if (connectCenter()) + { + newConn |= 0x10000; + } + + if (newConn != (connMap & 0x10F00)) + { + connMap = connMap & ~0x10F00 | newConn; + return true; + } + return false; + } + + /** Recalculates connections that can be made to other parts outside of this space + * + * @return true if external connections should be recalculated */ + protected boolean updateOpenConnections() + { + int newConn = 0; + for (int r = 0; r < 4; r++) + if (connectionOpen(r)) + newConn |= 0x1000 << r; + + if (newConn != (connMap & 0xF000)) + { + connMap = connMap & ~0xF000 | newConn; + return true; + } + return false; + } + + public boolean connectionOpen(int r) + { + int absDir = Rotation.rotateSide(side, r); + TMultiPart facePart = tile().partMap(absDir); + if (facePart != null && (!(facePart instanceof PartFlatWire) || !canConnectTo((PartFlatWire) facePart))) + return false; + + if (tile().partMap(PartMap.edgeBetween(side, absDir)) != null) + return false; + + return true; + } + + /** Return a corner connection state. 0 = No connection 1 = Physical connection 2 = Render + * connection */ + public int connectCorner(int r) + { + int absDir = Rotation.rotateSide(side, r); + + BlockCoord pos = new BlockCoord(tile()); + pos.offset(absDir); + + if (!canConnectThroughCorner(pos, absDir ^ 1, side)) + return 0; + + pos.offset(side); + TileMultipart t = Utility.getMultipartTile(world(), pos); + if (t != null) + { + TMultiPart tp = t.partMap(absDir ^ 1); + + if (canConnectTo(tp)) + { + boolean b = ((PartFlatWire) tp).connectCorner(this, Rotation.rotationTo(absDir ^ 1, side ^ 1)); + + if (b) + { + // let them connect to us + if (!renderThisCorner((PartFlatWire) tp)) + { + return 1; + } + + return 2; + } + } + } + return 0; + } + + public boolean canConnectThroughCorner(BlockCoord pos, int side1, int side2) + { + if (world().isAirBlock(pos.x, pos.y, pos.z)) + { + return true; + } + + TileMultipart t = Utility.getMultipartTile(world(), pos); + if (t != null) + { + return t.partMap(side1) == null && t.partMap(side2) == null && t.partMap(PartMap.edgeBetween(side1, side2)) == null; + } + + return false; + } + + public boolean connectStraight(int r) + { + int absDir = Rotation.rotateSide(side, r); + + BlockCoord pos = new BlockCoord(tile()).offset(absDir); + + TileMultipart t = Utility.getMultipartTile(world(), pos); + if (t != null) + { + TMultiPart tp = t.partMap(side); + + if (this.canConnectTo(tp)) + { + return ((PartFlatWire) tp).connectStraight(this, (r + 2) % 4); + } + } + else + { + TileEntity tileEntity = world().getBlockTileEntity(pos.x, pos.y, pos.z); + return this.canConnectTo(tileEntity); + } + + return false; + } + + public boolean connectInternal(int r) + { + int absDir = Rotation.rotateSide(side, r); + + if (tile().partMap(PartMap.edgeBetween(absDir, side)) != null) + return false; + + TMultiPart tp = tile().partMap(absDir); + + if (this.canConnectTo(tp)) + { + return ((PartFlatWire) tp).connectInternal(this, Rotation.rotationTo(absDir, side)); + } + + return connectInternalOverride(tp, r); + } + + public boolean connectInternalOverride(TMultiPart p, int r) + { + return false; + } + + public boolean connectCenter() + { + TMultiPart tp = tile().partMap(6); + + if (this.canConnectTo(tp)) + { + return ((PartFlatWire) tp).connectInternal(this, side); + } + + return false; + } + + public boolean renderThisCorner(PartFlatWire part) + { + if (!(part instanceof PartFlatWire)) + return false; + + PartFlatWire wire = (PartFlatWire) part; + if (wire.getThickness() == getThickness()) + return side < wire.side; + + return wire.getThickness() > getThickness(); + } + + public boolean connectCorner(PartFlatWire wire, int r) + { + if (this.canConnectTo(wire) && maskOpen(r)) + { + int oldConn = connMap; + connMap |= 0x1 << r; + if (renderThisCorner(wire))// render connection + connMap |= 0x100000 << r; + + if (oldConn != connMap) + sendConnUpdate(); + return true; + } + return false; + } + + public boolean connectStraight(PartFlatWire wire, int r) + { + if (this.canConnectTo(wire) && maskOpen(r)) + { + int oldConn = connMap; + connMap |= 0x10 << r; + if (oldConn != connMap) + sendConnUpdate(); + return true; + } + return false; + } + + public boolean connectInternal(PartFlatWire wire, int r) + { + if (this.canConnectTo(wire)) + { + int oldConn = connMap; + connMap |= 0x100 << r; + if (oldConn != connMap) + sendConnUpdate(); + return true; + } + return false; + } + + public boolean canConnectCorner(int r) + { + return true; + } + + public void notifyCornerChange(int r) + { + int absDir = Rotation.rotateSide(side, r); + + BlockCoord pos = new BlockCoord(tile()).offset(absDir).offset(side); + world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID); + } + + public void notifyStraightChange(int r) + { + int absDir = Rotation.rotateSide(side, r); + + BlockCoord pos = new BlockCoord(tile()).offset(absDir); + world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID); + } + + public boolean maskConnects(int r) + { + return (connMap & 0x111 << r) != 0; + } + + public boolean maskOpen(int r) + { + return (connMap & 0x1000 << r) != 0; + } + + /** START TILEMULTIPART INTERACTIONS **/ + @Override + public float getStrength(MovingObjectPosition hit, EntityPlayer player) + { + return 4; + } + + @Override + public int getSlotMask() + { + return 1 << this.side; + } + + @Override + public Iterable getSubParts() + { + return Arrays.asList(new IndexedCuboid6(0, selectionBounds[getThickness()][side])); + } + + @Override + public boolean occlusionTest(TMultiPart npart) + { + return NormalOcclusionTest.apply(this, npart); + } + + @Override + public Iterable getOcclusionBoxes() + { + return Arrays.asList(occlusionBounds[getThickness()][side]); + } + + public int getThickness() + { + return this.isInsulated ? 2 : 1; + } + + @Override + public int redstoneConductionMap() + { + return 0; + } + + @Override + public boolean solid(int arg0) + { + return false; + } + + @Override + public String getType() + { + return "resonant_induction_flat_wire"; + } + + /** RENDERING */ + @SideOnly(Side.CLIENT) + public Icon getIcon() + { + return RenderFlatWire.flatWireTexture; + } + + public Colour getColour() + { + return this.isInsulated ? ResonantInduction.DYE_COLORS[this.color] : this.getMaterial().color; + } + + public boolean useStaticRenderer() + { + return true; + } + + @Override + @SideOnly(Side.CLIENT) + public void renderStatic(Vector3 pos, LazyLightMatrix olm, int pass) + { + if (pass == 0 && useStaticRenderer()) + { + CCRenderState.setBrightness(world(), x(), y(), z()); + RenderFlatWire.render(this, pos); + CCRenderState.setColour(-1); + } + } + + @Override + @SideOnly(Side.CLIENT) + public void renderDynamic(Vector3 pos, float frame, int pass) + { + if (pass == 0 && !useStaticRenderer()) + { + GL11.glDisable(GL11.GL_LIGHTING); + TextureUtils.bindAtlas(0); + CCRenderState.useModelColours(true); + CCRenderState.startDrawing(7); + RenderFlatWire.render(this, pos); + CCRenderState.draw(); + CCRenderState.setColour(-1); + GL11.glEnable(GL11.GL_LIGHTING); + } + } + + @Override + @SideOnly(Side.CLIENT) + public void drawBreaking(RenderBlocks renderBlocks) + { + CCRenderState.reset(); + RenderFlatWire.renderBreakingOverlay(renderBlocks.overrideBlockTexture, this); + } } \ No newline at end of file