Jump to content

Minothor

Members
  • Posts

    63
  • Joined

Everything posted by Minothor

  1. Ah, righto, I was assuming that it would feed back into either an animation or other visual cooldown indicator of some kind. Yeah, without that, it's less work for both the coder and the server!
  2. Yeah, you're going to have to store the items in the Tileentity and read the nbtdata from the Tileentity being rendered. I use something similar with directions on my pipes: https://github.com/Minothor/diagonalCabling/blob/master/src/main/java/diaCable/renderers/blocks/TileEntityFluxCableRenderer.java
  3. The wiki provides an excellent primer tut on NBT here: http://www.minecraftforge.net/wiki/Creating_NBT_for_items The two methods that have been suggested to you so far both involve the onUpdate function (called every tick by the game) Cool's has a variable stored per Itemstack that could be named "coolDownTicksToGo" which is the number of ticks left until the item can be reused. The update function just decreases the number if it's >=0. Using the item sets the variable to the number of ticks needed to count down. Sieben's provides a bit more accuracy since tick rate can be variable. He stores the date/time (a 'Long' type in Java) the item was last used in the Itemstack nbt tag and uses the update function to check if the time difference between that stored time and the current time is >= the cooldown period. Using the item just sets have var to the current time.
  4. Hi all, I'm having a really bizarre issue with setting up one of my mods since reinstalling this PC. setupDecompWorkspace, clean and eclipse are all accepted by gradle and gradlew.bat however, the eclipse command is not adding any of the required folders. Any ideas on why this might be happening would be welcome at this point, it's getting frustrating as hell. Project in Question: https://github.com/Minothor/diagonalCabling Intended behaviour: Restored ability to just clone and run quickstart.bat in order to resume coding
  5. Grey has an excellent breakdown on rendering here: http://greyminecraftcoder.blogspot.be/2013/08/rendering-items.html Basically, you need to write your custom renderer and bind the relevant item rendering perspects in to it. For example, this renderer responds to the EQUIPPED_FIRST_PERSON mode and displays the cards in the player's hand instead of the item: https://github.com/Minothor/EmeraldCasino/blob/master/src/main/java/EmeraldCasino/renderers/items/ I hope this helps and good luck, custom rendering can be a right pain at times!
  6. Currently the server is keeping the correct connections data and it's the client that's out of sync, I'm shunting all the connection making/breaking/checking code out of the tile entities now and into static methods in the MFHelper api class. Partly to centralize control so that one fix works for all, partly so that I'm not duplicating whole methods for each TE. I'll keep you guys posted if I manage to solve it or not. Cheers again to everyone for the suggestions, help and support!
  7. ipsq, getUnlocalisedName() will return the name that the mod or minecraft game assigns it, the names of items that have been renamed in-game are stored in a displayName string on the itemStack container. The contained item's unlocalised name will be a constant still. (unless I'm misunderstanding your requirements) If you really need to though, you could probably test the path of the resource referenced by IIcon and compare that but it's probably unnecessary. Also, Lars, with Cauldron, that's no longer strictly true, although it can cause all kinds of issues, it is at least theoretically feasible to write a mod that leverages both frameworks.
  8. Cheers for pointing that out Lars, I've cleaned that up and I'm wondering if I can force the client side to resync in any other way... I'll do some more research over the weekend. Cheers again to everyone for all the help and suggestions so far though! (these forums actually help keep me motivated and ambitious)
  9. Cheers for pointing out some of the points that I'd missed in the datapacket methods, I've also added in debug code to check the side that's desyncing and it is indeed the client-side that isn't updating it's connections list, server side it cleaning up just fine it would seem. I've added in your changes in the datapacket methods, but the desync is still rearing it's ugly head I'm afraid. Here's the TileEntity class as it stands currently: package net.RPower.RPowermod.machines.power.cable; import java.util.LinkedList; import java.util.List; import java.util.Queue; import RPower.api.power.block.I_MFSink; import RPower.api.power.block.cable.I_MFCable; import RPower.api.power.block.cable.I_PipeDirection; import RPower.api.power.core.E_MFPacketType; import RPower.api.power.core.MFHelper; import RPower.api.power.core.MFPacket; import net.RPower.RPowermod.core.RPCore; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; public class TileEntityFluxCable extends TileEntity implements I_MFCable { //Connections are an array of [up, Down, North, East, West, South] public List<I_PipeDirection> connections; //whether or not the cable is lossy public boolean insulatedCable; //maximum limit the cable can carry public double packetSizeLimit; //Packets awaiting processing public Queue<MFPacket> internalBuffer; //automatically calculated. public double percentageLoss; //transfer mode, unbridged connections can only cross an intersection in straight lines (may be reserved for advanced cabling) public boolean bridgeConnections; private double distLimit; public TileEntityFluxCable() { this(32); } public TileEntityFluxCable(double packetSize) { this(packetSize,false); } public TileEntityFluxCable(double packetSize, boolean insulated) { this(packetSize,insulated,true); } public TileEntityFluxCable(double packetSize, boolean insulated,boolean bridged) { packetSizeLimit= packetSize; insulatedCable=insulated; bridgeConnections=bridged; connections=new LinkedList<I_PipeDirection>(); internalBuffer=new LinkedList<MFPacket>(); checkLoss(insulated); distLimit = insulatedCable?(4*packetSize):packetSize; } private void checkLoss(boolean insulated) { if(!insulated) { percentageLoss=(packetSizeLimit/MFPacket.POWERLIMIT); } } @Override public boolean takePacket(MFPacket packet) { double excess=0; if(!insulatedCable) { excess+=(percentageLoss*packet.getBuffer()); packet.setBuffer(packet.getBuffer()-excess); } if(packet.getBuffer()>packetSizeLimit) { excess += packet.getBuffer()-packetSizeLimit; packet.setBuffer(packetSizeLimit); } powerBleed(excess); boolean result=false; result=internalBuffer.add(packet); return result; } @Override public void writeToNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = new byte[connections.size()]; int i =0; for (I_PipeDirection connection: connections) { connectionsArr[i] = connection.toByte(); i++; } nbtTag.setByteArray("connections", connectionsArr); nbtTag.setBoolean("insulated", insulatedCable); nbtTag.setBoolean("bridged", bridgeConnections); nbtTag.setDouble("packetLimit", packetSizeLimit); super.writeToNBT(nbtTag); }; @Override public void readFromNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = nbtTag.getByteArray("connections"); for (byte b : connectionsArr) { I_PipeDirection temp = new PipeDirection(b); connections.add(temp); } insulatedCable=nbtTag.getBoolean("insulated"); bridgeConnections=nbtTag.getBoolean("bridged"); packetSizeLimit=nbtTag.getDouble("packetLimit"); checkLoss(insulatedCable); super.readFromNBT(nbtTag); } //Fixed by Whov @Override public Packet getDescriptionPacket() { Packet packet = super.getDescriptionPacket(); NBTTagCompound nbtTag = packet != null ? ((S35PacketUpdateTileEntity)packet).func_148857_g() : new NBTTagCompound(); writeToNBT(nbtTag); this.writeToNBT(nbtTag); //TODO: Get this damn working! return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } //Fixed by Whov @Override public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { super.onDataPacket(networkManager, packet); readFromNBT(packet.func_148857_g()); } @Override public void updateEntity() { if(!internalBuffer.isEmpty()) { MFPacket packet = internalBuffer.remove(); boolean result=false; byte direction; for(int i=0; i<59;i++) { int posNeg = ((int)(Math.random()*%2==0)?1:-1; double randXvel=Math.random()*(2*posNeg); double randYvel=Math.random()*(2*posNeg); double randZvel=Math.random()*(2*posNeg); this.worldObj.spawnParticle("magicCrit", xCoord, yCoord, zCoord, randXvel, randYvel, randZvel); } switch(packet.getType()) { case RESPOND: direction = packet.getOrigin().peek(); result = (direction!=-1); result = pushPacket(packet); break; default: direction = packet.getOrigin().peek(); packet.getOrigin().add(randDir(direction).toByte()); result=pushPacket(packet); break; } } super.updateEntity(); } private I_PipeDirection randDir(byte initDirection) { I_PipeDirection origin = new PipeDirection(initDirection); origin.invert(); I_PipeDirection newDirection = origin; int attempt = 0; while (!connections.isEmpty()&&attempt<26&&newDirection.equals(origin)) { attempt++; int randNum=(int)(Math.random()*connections.size()); newDirection = connections.get(randNum); } return newDirection; } @Override public boolean checkConnections() { boolean result=false; int x,y,z,i=0; for(y=-1;y<2;y++) { //System.out.println("Y Level: "+y); for(x=-1;x<2;x++) { //System.out.println("X Position: "+x); for(z=-1;z<2;z++) { //System.out.println("Z Position: "+z); i++; Block target = worldObj.getBlock(xCoord+x, yCoord+y, zCoord+z); //System.out.print("Test["+i+"] Checking block at ["+(xCoord+x)+","+(yCoord+y)+","+(zCoord+z)+"]"); if(target.hasTileEntity(target.getDamageValue(worldObj, xCoord+x, yCoord+y, zCoord+z))&&MFHelper.checkConnectable(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))) { //System.out.print(" - Valid!"); boolean twoWay = (worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable; formConnection(twoWay, x,y,z); } //System.out.print('\n'); } } //System.out.println("================================================================="); } return result; } @Override public synchronized void formConnection(boolean twoWay, int x, int y, int z) { if(!(x==0&&y==0&&z==0)) { connections.add(new PipeDirection(x, y, z)); if (twoWay) { ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); worldObj.markBlockForUpdate(xCoord+x, yCoord+y, zCoord+z); } //System.out.println("connection formed"); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } } @Override public synchronized void breakConnection(boolean twoWay, int x, int y, int z) { I_PipeDirection targetConnector = new PipeDirection(x,y,z); if(connections.contains(targetConnector)) { System.out.println("Connector found..."); System.out.println("Remove operation was "+(connections.remove(targetConnector)?"":"un")+"successful."); } if (twoWay&&(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable) { I_MFCable targetTile = (I_MFCable)worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z); targetTile.breakConnection(false,-x, -y, -z); worldObj.markBlockForUpdate(xCoord+x, yCoord+y, zCoord+z); } worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } @Override public boolean pushPacket(MFPacket packet) { boolean result= false; if(packet.getType()==E_MFPacketType.RESPOND&&packet.getBuffer()<=0) { packet=null; } if(packet!=null&&packet.getOrigin().size()<=distLimit); { byte direction = packet.getOrigin().peek(); if(packet.getType()==E_MFPacketType.RESPOND) packet.getOrigin().pop(); int[]origin = {xCoord,yCoord,zCoord}; int[] target = new PipeDirection(direction).getTarget(); for(int i=0;i<3;i++) { target[i]+=origin[i]; } result = this.worldObj.getBlock(target[0], target[1], target[2]).hasTileEntity(0); if(result) result=this.worldObj.getTileEntity(target[0], target[1], target[2])instanceof I_MFSink; if(result) result=((I_MFSink)this.worldObj.getTileEntity(target[0], target[1], target[2])).takePacket(packet); if(!result) powerBleed(packet.getBuffer()); } return result; } @Override public boolean canUpdate() { return true; } @Override public double flowLimit() { return packetSizeLimit; } @Override public void powerBleed(double excess) { //add power bleed to chunk atmosphere -> own effects + taint if Thaumcraft installed if(excess>0) System.err.println(""+excess+" MF bled off into atmosphere!\n"); } @Override public double getPacketLimit() { return packetSizeLimit; } @Override public boolean isInsulated() { return insulatedCable; } @Override public boolean isBridged() { return bridgeConnections; } @Override public boolean canDeBridge() { return insulatedCable; } @Override public List<I_PipeDirection> getConnections() { System.out.println("Getting "+(worldObj.isRemote?"Client":"Server")+" connections"); return connections; } public String toJSON() { String result = "\n{"; result+=("\n\t\"tileX\":\""+xCoord+"\","); result+=("\n\t\"tileY\":\""+yCoord+"\","); result+=("\n\t\"tileZ\":\""+zCoord+"\","); result+=("\n\t\"connections\":[\n"); for (I_PipeDirection pipe : connections) { result+=(pipe.toJSON()+",\n"); } result+="]"; result+="\n}\n"; return result; } @Override public void breakAllConnections() { int conNum=connections.size(); for (int i= 0; i<conNum;i++) { int[] target = connections.get(0).getTarget(); breakConnection(true, target[0], target[1], target[2]); } } }
  10. I'm not really that good, to be honest, before this year I hadn't really touched Java since 2007.
  11. I haven't been able to test the single function yet, just the removal of a pipe with only one connection. As for the test, I overrode the equals function with a test that checks the results of each connection's toByte() method so I'm evaluating the direction rather than the object in memory. As far as I can tell, the server and client entities desync, but the server side maintains the correct number while meaning that the pipes client side can behave in unintended ways since packets are transient and don't sync. One solution will be to make packet handling server side only and sync the tile entities when the server ones receive a packet. Still left with the visual artifacts client side though.
  12. I catch the break block in the block class and tell the tileEntity to run the breakAllConnections() method before calling the superclass break method. Code: https://github.com/BackSpace47/main/blob/PowerSystem_V2/java/net/RPower/RPowermod/machines/power/cable/BlockFluxCable.java
  13. Ah, yeah, that's because the x value is the relative value from -1 to 1, so xCoord + (-1) is the same as xCoord -1. I'm thinking of adding a cleanUp() function that can be marked to run on block update, see if that helps.
  14. Please could you elaborate on that? I'm looking through the break connection code and I'm inverting the relative coords in all the right places as far as I can see.
  15. hitting a new bug now I'm afraid, remotely calling the breakConnection() function on adjacent pipes sometimes leaves open ended connections towards the removed pipe. package net.RPower.RPowermod.machines.power.cable; import java.util.LinkedList; import java.util.List; import java.util.Queue; import RPower.api.power.E_MFPacketType; import RPower.api.power.I_MFSink; import RPower.api.power.MFHelper; import RPower.api.power.MFPacket; import RPower.api.power.cable.I_MFCable; import RPower.api.power.cable.I_PipeDirection; import net.RPower.RPowermod.core.RPCore; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; public class TileEntityFluxCable extends TileEntity implements I_MFCable { //Connections are an array of [up, Down, North, East, West, South] public List<I_PipeDirection> connections; //whether or not the cable is lossy public boolean insulatedCable; //maximum limit the cable can carry public double packetSizeLimit; //Packets awaiting processing public Queue<MFPacket> internalBuffer; //automatically calculated. public double percentageLoss; //transfer mode, unbridged connections can only cross an intersection in straight lines (may be reserved for advanced cabling) public boolean bridgeConnections; private double distLimit; public TileEntityFluxCable() { this(32); } public TileEntityFluxCable(double packetSize) { this(packetSize,false); } public TileEntityFluxCable(double packetSize, boolean insulated) { this(packetSize,insulated,true); } public TileEntityFluxCable(double packetSize, boolean insulated,boolean bridged) { packetSizeLimit= packetSize; insulatedCable=insulated; bridgeConnections=bridged; connections=new LinkedList<I_PipeDirection>(); internalBuffer=new LinkedList<MFPacket>(); checkLoss(insulated); distLimit = insulatedCable?(4*packetSize):packetSize; } private void checkLoss(boolean insulated) { if(!insulated) { percentageLoss=(packetSizeLimit/MFPacket.POWERLIMIT); } } @Override public boolean takePacket(MFPacket packet) { double excess=0; if(!insulatedCable) { excess+=(percentageLoss*packet.getBuffer()); packet.setBuffer(packet.getBuffer()-excess); } if(packet.getBuffer()>packetSizeLimit) { excess += packet.getBuffer()-packetSizeLimit; packet.setBuffer(packetSizeLimit); } powerBleed(excess); boolean result=false; result=internalBuffer.add(packet); return result; } @Override public void writeToNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = new byte[connections.size()]; int i =0; for (I_PipeDirection connection: connections) { connectionsArr[i] = connection.toByte(); i++; } nbtTag.setByteArray("connections", connectionsArr); nbtTag.setBoolean("insulated", insulatedCable); nbtTag.setBoolean("bridged", bridgeConnections); nbtTag.setDouble("packetLimit", packetSizeLimit); super.writeToNBT(nbtTag); }; @Override public void readFromNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = nbtTag.getByteArray("connections"); for (byte b : connectionsArr) { I_PipeDirection temp = new PipeDirection(b); connections.add(temp); } insulatedCable=nbtTag.getBoolean("insulated"); bridgeConnections=nbtTag.getBoolean("bridged"); packetSizeLimit=nbtTag.getDouble("packetLimit"); checkLoss(insulatedCable); super.readFromNBT(nbtTag); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTag = new NBTTagCompound(); this.writeToNBT(nbtTag); //TODO: Get this damn working! return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } @Override public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } @Override public void updateEntity() { if(!internalBuffer.isEmpty()) { MFPacket packet = internalBuffer.remove(); boolean result=false; byte direction; for(int i=0; i<59;i++) { int posNeg = ((int)(Math.random()*%2==0)?1:-1; double randXvel=Math.random()*(2*posNeg); double randYvel=Math.random()*(2*posNeg); double randZvel=Math.random()*(2*posNeg); this.worldObj.spawnParticle("magicCrit", xCoord, yCoord, zCoord, randXvel, randYvel, randZvel); } switch(packet.getType()) { case RESPOND: direction = packet.getOrigin().peek(); result = (direction!=-1); result = pushPacket(packet); break; default: direction = packet.getOrigin().peek(); packet.getOrigin().add(randDir(direction).toByte()); result=pushPacket(packet); break; } } super.updateEntity(); } private I_PipeDirection randDir(byte initDirection) { I_PipeDirection origin = new PipeDirection(initDirection); origin.invert(); I_PipeDirection newDirection = origin; int attempt = 0; while (!connections.isEmpty()&&attempt<26&&newDirection.equals(origin)) { attempt++; int randNum=(int)(Math.random()*connections.size()); newDirection = connections.get(randNum); } return newDirection; } public boolean checkConnections() { boolean result=false; int x,y,z,i=0; for(y=-1;y<2;y++) { //System.out.println("Y Level: "+y); for(x=-1;x<2;x++) { //System.out.println("X Position: "+x); for(z=-1;z<2;z++) { //System.out.println("Z Position: "+z); i++; Block target = worldObj.getBlock(xCoord+x, yCoord+y, zCoord+z); //System.out.print("Test["+i+"] Checking block at ["+(xCoord+x)+","+(yCoord+y)+","+(zCoord+z)+"]"); if(target.hasTileEntity(target.getDamageValue(worldObj, xCoord+x, yCoord+y, zCoord+z))&&MFHelper.checkConnectable(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))) { //System.out.print(" - Valid!"); boolean twoWay = (worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable; formConnection(twoWay, x,y,z); } //System.out.print('\n'); } } //System.out.println("================================================================="); } return result; } @Override public void formConnection(boolean twoWay, int x, int y, int z) { if(!(x==0&&y==0&&z==0)) { connections.add(new PipeDirection(x, y, z)); if (twoWay) { ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); worldObj.markBlockForUpdate(xCoord+x, yCoord+y, zCoord+z); } //System.out.println("connection formed"); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } } @Override public void breakConnection(boolean twoWay, int x, int y, int z) { if (twoWay&&(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable) { I_MFCable targetTile = (I_MFCable)worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z); targetTile.breakConnection(false,-x, -y, -z); worldObj.markBlockForUpdate(xCoord+x, yCoord+y, zCoord+z); } connections.remove(new PipeDirection(x,y,z)); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } @Override public boolean pushPacket(MFPacket packet) { boolean result= false; if(packet.getType()==E_MFPacketType.RESPOND&&packet.getBuffer()<=0) { packet=null; } if(packet!=null&&packet.getOrigin().size()<=distLimit); { byte direction = packet.getOrigin().peek(); if(packet.getType()==E_MFPacketType.RESPOND) packet.getOrigin().pop(); int[]origin = {xCoord,yCoord,zCoord}; int[] target = new PipeDirection(direction).getTarget(); for(int i=0;i<3;i++) { target[i]+=origin[i]; } result = this.worldObj.getBlock(target[0], target[1], target[2]).hasTileEntity(0); if(result) result=this.worldObj.getTileEntity(target[0], target[1], target[2])instanceof I_MFSink; if(result) result=((I_MFSink)this.worldObj.getTileEntity(target[0], target[1], target[2])).takePacket(packet); if(!result) powerBleed(packet.getBuffer()); } return result; } @Override public boolean canUpdate() { return true; } @Override public double flowLimit() { return packetSizeLimit; } @Override public void powerBleed(double excess) { //add power bleed to chunk atmosphere -> own effects + taint if Thaumcraft installed if(excess>0) System.err.println(""+excess+" MF bled off into atmosphere!\n"); } @Override public double getPacketLimit() { return packetSizeLimit; } @Override public boolean isInsulated() { return insulatedCable; } @Override public boolean isBridged() { return bridgeConnections; } @Override public boolean canDeBridge() { return insulatedCable; } @Override public List<I_PipeDirection> getConnections() { return connections; } public String toJSON() { String result = "\n{"; result+=("\n\t\"tileX\":\""+xCoord+"\","); result+=("\n\t\"tileY\":\""+yCoord+"\","); result+=("\n\t\"tileZ\":\""+zCoord+"\","); result+=("\n\t\"connections\":[\n"); for (I_PipeDirection pipe : connections) { result+=(pipe.toJSON()+",\n"); } result+="]"; result+="\n}\n"; return result; } @Override public void breakAllConnections() { for (I_PipeDirection direction : connections) { int[] target = direction.getTarget(); breakConnection(true, target[0], target[1], target[2]); } } } package RPower.api.power.cable; import net.RPower.RPowermod.machines.power.cable.PipeDirection; public abstract class A_PipeDirection implements I_PipeDirection { protected int[] target = {0,0,0}; public A_PipeDirection(int xOffset, int yOffset, int zOffset) { int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } //TODO: Solve why connections of Y= 1, X&Z=0 evaluate to -89 instead of 111. public A_PipeDirection(byte b) { //System.out.println("["+b+"]"); //y = b/100 (nearest whole) int yOffset = (byte)b/100; //System.out.println(b+" yO:"+yOffset); //remove the processed value from the byte b-=(100*yOffset); //System.out.println(" "+b); if(b<0) b*=-1; //x = (b/10)-1 (again, nearest whole and convert 0-> -1, 1 -> 0, 2 -> 1) int xOffset = (b/10)-1; //System.out.println(b+" xO:"+xOffset); //remove the processed value from the byte b-= (10*(xOffset+1)); //System.out.println(" "+b); //z = b-1 (converting 0-> -1, 1 -> 0, 2 -> 1) int zOffset = b-1; //System.out.println(b+" zO:"+zOffset); int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } @Override public void setTarget(int[] target) { this.target = target; } @Override public int[] getTarget() { return target; } @Override public byte toByte() { byte modifier = (byte) (target[1]<0?-1:1); //=(100*y)+(10*(x+1))+(z+1) byte xRef = (byte) ((modifier*10)*(1+target[0])); //System.out.println("Byte xRef:"+xRef); byte yRef = (byte) (100*target[1]); //System.out.println("Byte yRef:"+yRef); byte zRef = (byte)(modifier*(1+target[2])); //System.out.println("Byte zRef:"+zRef); byte result = (byte) (zRef+xRef+yRef); return result; } @Override public String toJSON() { String result = "\n{"; result+=("\n\t\"targetX\":\""+target[0]+"\","); result+=("\n\t\"targetY\":\""+target[1]+"\","); result+=("\n\t\"targetZ\":\""+target[2]+"\""); result+="\n}\n"; return result; } @Override public void invert() { int[] newTarget = {-target[0],-target[1],-target[2]}; target = newTarget; } @Override public boolean equals(Object obj) { if (obj==null||!(obj instanceof I_PipeDirection)) return false; return ((I_PipeDirection)obj).toByte()==this.toByte(); } }
  16. that's more a combo of the solid-colour testing texture and lighting glitches and I'll tweak those once I've got the mechanics verified.
  17. Cheers for the suggestions and help everyone, after swapping over to Tesselator and handling directions in a class similar to an ENUM I've managed to get it working, the Renderer is a bit of a mess of "if()" statements though, but for now it works: https://lh6.googleusercontent.com/-LgFEnwWolU4/U_2YFF6-3kI/AAAAAAAAB-s/hBZU0QYU_Ws/w854-h480-no/2014-08-27_10.29.42.png[/img] Fixed Abstract Class for PipeDirection (saving and loading to byte array for the NBT was the main issue) package RPower.api.power.cable; public abstract class A_PipeDirection implements I_PipeDirection { protected int[] target = {0,0,0}; public A_PipeDirection(int xOffset, int yOffset, int zOffset) { int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } //TODO: Solve why connections of Y= 1, X&Z=0 evaluate to -89 instead of 111. public A_PipeDirection(byte b) { System.out.println("["+b+"]"); //y = b/100 (nearest whole) int yOffset = (byte)b/100; System.out.println(b+" yO:"+yOffset); //remove the processed value from the byte b-=(100*yOffset); System.out.println(" "+b); if(b<0) b*=-1; //x = (b/10)-1 (again, nearest whole and convert 0-> -1, 1 -> 0, 2 -> 1) int xOffset = (b/10)-1; System.out.println(b+" xO:"+xOffset); //remove the processed value from the byte b-= (10*(xOffset+1)); System.out.println(" "+b); //z = b-1 (converting 0-> -1, 1 -> 0, 2 -> 1) int zOffset = b-1; System.out.println(b+" zO:"+zOffset); int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } @Override public void setTarget(int[] target) { this.target = target; } @Override public int[] getTarget() { return target; } @Override public byte toByte() { byte modifier = (byte) (target[1]<0?-1:1); //=(100*y)+(10*(x+1))+(z+1) byte xRef = (byte) ((modifier*10)*(1+target[0])); System.out.println("Byte xRef:"+xRef); byte yRef = (byte) (100*target[1]); System.out.println("Byte yRef:"+yRef); byte zRef = (byte)(modifier*(1+target[2])); System.out.println("Byte zRef:"+zRef); byte result = (byte) (zRef+xRef+yRef); return result; } @Override public String toJSON() { String result = "\n{"; result+=("\n\t\"targetX\":\""+target[0]+"\","); result+=("\n\t\"targetY\":\""+target[1]+"\","); result+=("\n\t\"targetZ\":\""+target[2]+"\""); result+="\n}\n"; return result; } } Fixed TileEntity (now correctly checks the surrounding 26 blocks for connectable Tiles): package net.RPower.RPowermod.machines.power.cable; import java.util.LinkedList; import java.util.List; import java.util.Queue; import RPower.api.power.E_MFPacketType; import RPower.api.power.I_MFSink; import RPower.api.power.MFHelper; import RPower.api.power.MFPacket; import RPower.api.power.cable.I_MFCable; import RPower.api.power.cable.I_PipeDirection; import net.RPower.RPowermod.core.RPCore; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; public class TileEntityFluxCable extends TileEntity implements I_MFCable { //Connections are an array of [up, Down, North, East, West, South] public List<I_PipeDirection> connections; //whether or not the cable is lossy public boolean insulatedCable; //maximum limit the cable can carry public double packetSizeLimit; //Packets awaiting processing public Queue<MFPacket> internalBuffer; //automatically calculated. public double percentageLoss; //transfer mode, unbridged connections can only cross an intersection in straight lines (may be reserved for advanced cabling) public boolean bridgeConnections; public TileEntityFluxCable() { this(32); } public TileEntityFluxCable(double packetSize) { this(packetSize,false); } public TileEntityFluxCable(double packetSize, boolean insulated) { this(packetSize,insulated,true); } public TileEntityFluxCable(double packetSize, boolean insulated,boolean bridged) { packetSizeLimit= packetSize; insulatedCable=insulated; bridgeConnections=bridged; connections=new LinkedList<I_PipeDirection>(); internalBuffer=new LinkedList<MFPacket>(); checkLoss(insulated); } private void checkLoss(boolean insulated) { if(!insulated) { percentageLoss=(packetSizeLimit/MFPacket.POWERLIMIT); } } @Override public boolean takePacket(MFPacket packet) { double excess=0; if(!insulatedCable) { excess+=(percentageLoss*packet.getBuffer()); packet.setBuffer(packet.getBuffer()-excess); } if(packet.getBuffer()>packetSizeLimit) { excess += packet.getBuffer()-packetSizeLimit; packet.setBuffer(packetSizeLimit); } powerBleed(excess); boolean result=false; result=internalBuffer.add(packet); return result; } @Override public void writeToNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = new byte[connections.size()]; int i =0; for (I_PipeDirection connection: connections) { connectionsArr[i] = connection.toByte(); i++; } nbtTag.setByteArray("connections", connectionsArr); nbtTag.setBoolean("insulated", insulatedCable); nbtTag.setBoolean("bridged", bridgeConnections); nbtTag.setDouble("packetLimit", packetSizeLimit); super.writeToNBT(nbtTag); }; @Override public void readFromNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = nbtTag.getByteArray("connections"); for (byte b : connectionsArr) { I_PipeDirection temp = new PipeDirection(b); connections.add(temp); } insulatedCable=nbtTag.getBoolean("insulated"); bridgeConnections=nbtTag.getBoolean("bridged"); packetSizeLimit=nbtTag.getDouble("packetLimit"); checkLoss(insulatedCable); super.readFromNBT(nbtTag); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTag = new NBTTagCompound(); this.writeToNBT(nbtTag); //TODO: Get this damn working! return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } @Override public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } @Override public void updateEntity() { if(!internalBuffer.isEmpty()) { MFPacket packet = internalBuffer.remove(); boolean result=false; byte direction; for(int i=0; i<59;i++) { int posNeg = ((int)(Math.random()*%2==0)?1:-1; double randXvel=Math.random()*(2*posNeg); double randYvel=Math.random()*(2*posNeg); double randZvel=Math.random()*(2*posNeg); this.worldObj.spawnParticle("magicCrit", xCoord, yCoord, zCoord, randXvel, randYvel, randZvel); } switch(packet.getType()) { case RESPOND: direction = packet.getOrigin().peek(); result = (direction!=-1); result = pushPacket(packet); break; default: direction = packet.getOrigin().peek(); packet.getOrigin().add(randDir(direction).toByte()); result=pushPacket(packet); break; } } super.updateEntity(); } private I_PipeDirection randDir(byte initDirection) { int randNum=(int)(Math.random()*connections.size()); return connections.get(randNum); } public boolean checkConnections() { boolean result=false; int x,y,z,i=0; for(y=-1;y<2;y++) { System.out.println("Y Level: "+y); for(x=-1;x<2;x++) { System.out.println("X Position: "+x); for(z=-1;z<2;z++) { System.out.println("Z Position: "+z); i++; Block target = worldObj.getBlock(xCoord+x, yCoord+y, zCoord+z); System.out.print("Test["+i+"] Checking block at ["+(xCoord+x)+","+(yCoord+y)+","+(zCoord+z)+"]"); if(target.hasTileEntity(target.getDamageValue(worldObj, xCoord+x, yCoord+y, zCoord+z))&&MFHelper.checkConnectable(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))) { System.out.print(" - Valid!"); boolean twoWay = (worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable; formConnection(twoWay, x,y,z); } System.out.print('\n'); } } System.out.println("================================================================="); } return result; } @Override public void formConnection(boolean twoWay, int x, int y, int z) { if(!(x==0&&y==0&&z==0)) { connections.add(new PipeDirection(x, y, z)); if (twoWay) { ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); worldObj.markBlockForUpdate(xCoord+x, yCoord+y, zCoord+z); } System.out.println("connection formed"); } } @Override public void breakConnection(I_PipeDirection direction) { // if ((worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable) // ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); // System.out.println("connection removed"); // connections.remove(direction); } @Override public boolean pushPacket(MFPacket packet) { byte direction = packet.getOrigin().peek(); if(packet.getType()==E_MFPacketType.RESPOND) packet.getOrigin().pop(); boolean result= false; int[]origin = {xCoord,yCoord,zCoord}; int[] target = new PipeDirection(direction).getTarget(); for(int i=0;i<3;i++) { target[i]+=origin[i]; } result = this.worldObj.getBlock(target[0], target[1], target[2]).hasTileEntity(0); if(result) result=this.worldObj.getTileEntity(target[0], target[1], target[2])instanceof I_MFSink; if(result) result=((I_MFSink)this.worldObj.getTileEntity(target[0], target[1], target[2])).takePacket(packet); if(!result) powerBleed(packet.getBuffer()); return result; } @Override public boolean canUpdate() { return true; } @Override public double flowLimit() { return packetSizeLimit; } @Override public void powerBleed(double excess) { //add power bleed to chunk atmosphere -> own effects + taint if Thaumcraft installed if(excess>0) System.err.println(""+excess+" MF bled off into atmosphere!\n"); } @Override public double getPacketLimit() { return packetSizeLimit; } @Override public boolean isInsulated() { return insulatedCable; } @Override public boolean isBridged() { return bridgeConnections; } @Override public boolean canDeBridge() { return insulatedCable; } @Override public List<I_PipeDirection> getConnections() { return connections; } public String toJSON() { String result = "\n{"; result+=("\n\t\"tileX\":\""+xCoord+"\","); result+=("\n\t\"tileY\":\""+yCoord+"\","); result+=("\n\t\"tileZ\":\""+zCoord+"\","); result+=("\n\t\"connections\":[\n"); for (I_PipeDirection pipe : connections) { result+=(pipe.toJSON()+",\n"); } result+="]"; result+="\n}\n"; return result; } } Fixed Renderer: package net.RPower.RPowermod.renderers.block; import org.lwjgl.opengl.GL11; import RPower.api.power.cable.I_PipeDirection; import cpw.mods.fml.client.registry.RenderingRegistry; import net.RPower.RPowermod.machines.power.cable.TileEntityFluxCable; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.shader.TesselatorVertexState; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; /** * * @author Minothor, Flenix *Renders the card Decks in the world *Adapted from Flenix's Tutorial at: *http://www.minecraftforge.net/wiki/Rendering_a_Techne_Model_as_a_Block */ //TODO: Cancel rendering if not visible //Current Idea: Player.yaw/pitch trigonometry && sky light public class TileEntityFluxCableRenderer extends TileEntitySpecialRenderer { private final ResourceLocation texture; public static int blockRenderId; public static final float pixel = 1.0F/16; public Tessellator tessellator; public TileEntityFluxCableRenderer() { tessellator = Tessellator.instance; blockRenderId = RenderingRegistry.getNextAvailableRenderId(); texture = new ResourceLocation(net.RPower.RPowermod.core.RPCore.modid+":textures/blocks/fluxCable.png"); } @Override public void renderTileEntityAt(TileEntity entity, double x, double y, double z, float scale) { //binding the textures Minecraft.getMinecraft().renderEngine.bindTexture(texture); GL11.glPushMatrix(); //initial location (what's up with the 0.5 and 1.5 difference I wonder) GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); GL11.glDisable(GL11.GL_CULL_FACE); drawHub(); //let LWGL know we're doing more matixy manipulation stuff //rotate to avoid model rendering upside down for (I_PipeDirection connection : ((TileEntityFluxCable)entity).connections) { int[] target = connection.getTarget(); float[] angles = {0,0,0}; float yMod = (target[0]==0&&target[2]==0)?90F:45F; float xMod=0; float xDir=0; float zDir=0; float zMod=0; if(target[1]==0) xMod=-90F; if(target[0]==0) { xDir=target[2]; xMod=-90F; } if(target[2]==0) { xDir=target[0]; xMod=180F; if(xDir>0) { xMod=0F; } } if(target[0]!=0&&target[2]!=0) { if(target[2]>0) { xDir=1; xMod=-135; if(target[0]>0) { xDir*=-1; xMod=45F; yMod-=10; } } else if(target[0]<0) { zDir=1; xDir=-1; zMod=360F; xMod=225F; yMod-=10; } else if(target[0]>0) { if(target[2]<0) { xDir=1; xMod=45; yMod-=10; } } if(target[0]<0&&target[2]>0) { if(target[1]<0) yMod=35F; if(target[1]>0) yMod=35F; } } angles[0]=zDir*zMod; angles[1]=xDir*xMod; angles[2]=target[1]*yMod; drawConnector(angles); } //pop both sections off the render stack GL11.glPopMatrix(); //System.out.println("FOV : "+Minecraft.getMinecraft().gameSettings.fovSetting); GL11.glEnable(GL11.GL_CULL_FACE); } private void drawHub() { tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //90x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //180x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //270x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); GL11.glRotatef(90, 0, 1, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(180, 0, 1, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 0, 1, 0); } private void drawRails(int size) { GL11.glPushMatrix(); GL11.glRotatef(45, 1, 0, 0); Tessellator tessellator = Tessellator.instance; drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); GL11.glRotatef(-45, 1, 0, 0); GL11.glPopMatrix(); } private void drawRail(int size, Tessellator tessellator) { float offset=27.4F; GL11.glRotatef(45F-offset, 1, 0, 0); GL11.glRotatef(-offset, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 0.5*pixel, -2*pixel, size*pixel, 1*pixel); tessellator.addVertexWithUV(size*pixel, 0.5*pixel, -2*pixel, 0*pixel, 0*pixel); tessellator.addVertexWithUV(size*pixel, -0.5*pixel, -2*pixel, 0*pixel, 0*pixel); tessellator.addVertexWithUV(0, -0.5*pixel, -2*pixel, size*pixel, 1*pixel); tessellator.draw(); GL11.glRotatef(offset, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 0.5*pixel, -2*pixel, size*pixel, 2*pixel); tessellator.addVertexWithUV(size*pixel, 0.5*pixel, -2*pixel, 0*pixel, 1*pixel); tessellator.addVertexWithUV(size*pixel, -0.5*pixel, -2*pixel, 0*pixel, 1*pixel); tessellator.addVertexWithUV(0, -0.5*pixel, -2*pixel, size*pixel, 2*pixel); tessellator.draw(); GL11.glRotatef(-45F+offset, 1, 0, 0); } private void drawCore(int size) { GL11.glPushMatrix(); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 1*pixel, 0, size*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, 1*pixel, 0, 0*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, -1*pixel, 0, 0*pixel, 6*pixel); tessellator.addVertexWithUV(0, -1*pixel, 0, size*pixel, 6*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 1*pixel, 0, size*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, 1*pixel, 0, 0*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, -1*pixel, 0, 0*pixel, 6*pixel); tessellator.addVertexWithUV(0, -1*pixel, 0, size*pixel, 6*pixel); tessellator.draw(); GL11.glRotatef(90, -1, 0, 0); GL11.glPopMatrix(); } private void drawConnector(float[] angle) { int size = 8; if((angle[1]!=90)||(angle[1]!=90)) size+=3; if(((angle[0]!=90)||(angle[2]!=90))&&((angle[0]!=-90)||(angle[2]!=-90))) size+=3; GL11.glRotatef(angle[0], 1, 0, 0); GL11.glRotatef(angle[1], 0, 1, 0); GL11.glRotatef(angle[2], 0, 0, 1); drawCore(size); drawRails(size); GL11.glRotatef(-angle[2], 0, 0, 1); GL11.glRotatef(-angle[1], 0, 1, 0); GL11.glRotatef(-angle[0], 1, 0, 0); } private void adjustLightFixture(World world, int x, int y, int z, Block block) { float brightness = block.getLightValue(world, x, y, z); int skyLight = world.getLightBrightnessForSkyBlocks(x, y, z, 0); int modulousModifier = skyLight % 65536; int divModifier = skyLight / 65536; tessellator.setColorOpaque_F(brightness, brightness, brightness); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, modulousModifier, divModifier); } }
  18. Look inside the .jar file, check if the "assets" folder is inside it. If it is not inside the file, copy that image folder into the .jar file. (guessing that their English is pretty poor, so I'm not brave enough to try explaining about adding it to the build path which would seem to be the issue)
  19. The only thing I can see that's obvious is that I forgot to stop the pipe from including itself in the connections, but even after I changed the checkConnection code to ignore the centre block: boolean centre = (x==0)&&(y==0)&&(z==0); if(target.hasTileEntity(target.getDamageValue(worldObj, xCoord+z, yCoord+y, zCoord+z))&&MFHelper.checkConnectable(worldObj.getTileEntity(xCoord+z, yCoord+y, zCoord+z))) { if(!centre){ boolean twoWay = (worldObj.getTileEntity(xCoord+z, yCoord+y, zCoord+z))instanceof I_MFCable; formConnection(twoWay, x,y,z); } } It's still returning 4 connections EDIT: Changed the check to be inside the formConnection() function, it now disregards any that have x,y,z all set to 0. Still struggling to find all the pipes though, it only appears to be detecting pipes that satisfy these relative conditions: (y<0, x>0, z>0) any ideas what's going on?
  20. Warning: Code Flood Incoming Below I've torn apart the code and rewritten a lot of it, by and large, it's cleaner and stabler, but I am getting a really strange bug now. If I check the number of connections on a pipe block, it seems to spawn with 6 connections in it's list even with no blocks around it and this is hampering my efforts to test individual pipe rendering directions working together. Just to clarify, the rendering I can now handle fine, it's the weird connection list behaviour that's confusing me now. [spoiler= Interfaces] package RPower.api.power.cable; import java.util.List; import RPower.api.power.I_MFSink; import RPower.api.power.I_MFSource; public interface I_MFCable extends I_MFSink, I_MFSource{ public double getPacketLimit(); public boolean isInsulated(); public boolean isBridged(); public boolean canDeBridge(); public List<I_PipeDirection> getConnections(); public void formConnection(boolean twoWay, int x, int y, int z); public void breakConnection(I_PipeDirection direction); } package RPower.api.power.cable; public interface I_PipeDirection { public void setTarget(int[] target); public int[] getTarget(); public byte toByte(); } [spoiler=Abstract Classes] package RPower.api.power.cable; public class A_PipeDirection implements I_PipeDirection { protected int[] target = {0,0,0}; public A_PipeDirection(int xOffset, int yOffset, int zOffset) { int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } public A_PipeDirection(byte b) { //y = b/100 (nearest whole) int yOffset = (byte)b/100; //remove the processed value from the byte b-=(100*yOffset); //x = (b/10)-1 (again, nearest whole and convert 0-> -1, 1 -> 0, 2 -> 1) int xOffset = (b/10)-1; //remove the processed value from the byte b-= (10*(xOffset+1)); //z = b-1 (converting 0-> -1, 1 -> 0, 2 -> 1) int zOffset = b-1; int[] targetArr= {xOffset,yOffset,zOffset}; setTarget(targetArr); } @Override public void setTarget(int[] target) { this.target = target; } @Override public int[] getTarget() { return target; } @Override public byte toByte() { //=(100*y)+(10*(x+1))+(z+1) //used for saving in NBT byte result = (byte) ((100*target[1]) + (10*(1+target[0])) + (1+target[2])); return result; } } [spoiler=normal API classes] package RPower.api.power; import java.util.Stack; public class MFPacket { public static final double POWERLIMIT = 2048; private E_MFPacketType packetType; private Stack<Byte> packetOrigin; private double buffer; public MFPacket(E_MFPacketType type) { setType(type); setBuffer(0); packetOrigin = new Stack(); packetOrigin.add((byte)-1); } public E_MFPacketType getType() { return packetType; } public void setType(E_MFPacketType type) { packetType=type; } public double getBuffer() { return buffer; } public void setBuffer(double amount) { if(amount<0) amount=0; buffer=amount; } public Stack<Byte> getOrigin() { return packetOrigin; } } package RPower.api.power; import RPower.api.power.cable.I_MFCable; import RPower.api.power.cable.I_PipeDirection; import net.RPower.RPowermod.machines.power.cable.PipeDirection; import net.RPower.RPowermod.machines.power.cable.TileEntityFluxCable; import net.minecraft.tileentity.TileEntity; public class MFHelper { public static synchronized boolean checkConnectable(TileEntity tileEntity) { boolean result = (tileEntity instanceof I_MFSink || tileEntity instanceof I_MFSource); if (result) System.out.println("Success!"); System.out.println(tileEntity.toString()); return result; } } [spoiler=Block & TileEntity] package net.RPower.RPowermod.machines.power.cable; import RPower.api.power.E_MFPacketType; import RPower.api.power.MFHelper; import RPower.api.power.MFPacket; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class BlockFluxCable extends BlockContainer{ public BlockFluxCable(Material p_i45394_1_) { super(p_i45394_1_); } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int metaD, float hitX, float hitY, float hitZ) { // MFPacket temp = new MFPacket(E_MFPacketType.REQUEST); // ((TileEntityFluxCable)world.getTileEntity(x, y, z)).takePacket(temp); System.err.println("This pipe has "+((TileEntityFluxCable)world.getTileEntity(x, y, z)).getConnections().size()+" connections."); return false; } @Override public void onBlockAdded(World world, int x, int y, int z) { ((TileEntityFluxCable)world.getTileEntity(x, y, z)).checkConnections(); super.onBlockAdded(world, x, y, z); } @Override public TileEntity createNewTileEntity(World world, int metadata) { TileEntity cable = new TileEntityFluxCable(32); return cable; } @Override public boolean isAir(IBlockAccess world, int x, int y, int z) { return false; } @Override protected boolean canSilkHarvest() { return false; }; @Override public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int metadata) { return false; }; @Override public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z) { return false; } @SideOnly(Side.CLIENT) @Override public boolean renderAsNormalBlock() { return false; } @Override @SideOnly(Side.CLIENT) public boolean shouldSideBeRendered(IBlockAccess blockAccess, int x, int y, int z, int side) { return false; }; @SideOnly(Side.CLIENT) @Override public boolean isOpaqueCube() { return false; } @Override public int getRenderType() { return -1; } } package net.RPower.RPowermod.machines.power.cable; import java.util.LinkedList; import java.util.List; import java.util.Queue; import RPower.api.power.E_MFPacketType; import RPower.api.power.I_MFSink; import RPower.api.power.MFHelper; import RPower.api.power.MFPacket; import RPower.api.power.cable.I_MFCable; import RPower.api.power.cable.I_PipeDirection; import net.RPower.RPowermod.core.RPCore; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; public class TileEntityFluxCable extends TileEntity implements I_MFCable { //Connections are an array of [up, Down, North, East, West, South] public List<I_PipeDirection> connections; //whether or not the cable is lossy public boolean insulatedCable; //maximum limit the cable can carry public double packetSizeLimit; //Packets awaiting processing public Queue<MFPacket> internalBuffer; //automatically calculated. public double percentageLoss; //transfer mode, unbridged connections can only cross an intersection in straight lines (may be reserved for advanced cabling) public boolean bridgeConnections; public TileEntityFluxCable() { this(32); } public TileEntityFluxCable(double packetSize) { this(packetSize,false); } public TileEntityFluxCable(double packetSize, boolean insulated) { this(packetSize,insulated,true); } public TileEntityFluxCable(double packetSize, boolean insulated,boolean bridged) { packetSizeLimit= packetSize; insulatedCable=insulated; bridgeConnections=bridged; connections=new LinkedList<I_PipeDirection>(); internalBuffer=new LinkedList<MFPacket>(); checkLoss(insulated); } private void checkLoss(boolean insulated) { if(!insulated) { percentageLoss=(packetSizeLimit/MFPacket.POWERLIMIT); } } @Override public boolean takePacket(MFPacket packet) { double excess=0; if(!insulatedCable) { excess+=(percentageLoss*packet.getBuffer()); packet.setBuffer(packet.getBuffer()-excess); } if(packet.getBuffer()>packetSizeLimit) { excess += packet.getBuffer()-packetSizeLimit; packet.setBuffer(packetSizeLimit); } powerBleed(excess); boolean result=false; result=internalBuffer.add(packet); return result; } @Override public void writeToNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = new byte[connections.size()]; int i =0; for (I_PipeDirection connection: connections) { connectionsArr[i] = connection.toByte(); i++; } nbtTag.setByteArray("connections", connectionsArr); nbtTag.setBoolean("insulated", insulatedCable); nbtTag.setBoolean("bridged", bridgeConnections); nbtTag.setDouble("packetLimit", packetSizeLimit); super.writeToNBT(nbtTag); }; @Override public void readFromNBT(NBTTagCompound nbtTag) { byte[] connectionsArr = nbtTag.getByteArray("connections"); for (byte b : connectionsArr) { I_PipeDirection temp = new PipeDirection(b); connections.add(temp); } insulatedCable=nbtTag.getBoolean("insulated"); bridgeConnections=nbtTag.getBoolean("bridged"); packetSizeLimit=nbtTag.getDouble("packetLimit"); checkLoss(insulatedCable); super.readFromNBT(nbtTag); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTag = new NBTTagCompound(); this.writeToNBT(nbtTag); //TODO: Get this damn working! return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } @Override public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } @Override public void updateEntity() { if(!internalBuffer.isEmpty()) { MFPacket packet = internalBuffer.remove(); boolean result=false; byte direction; for(int i=0; i<59;i++) { int posNeg = ((int)(Math.random()*%2==0)?1:-1; double randXvel=Math.random()*(2*posNeg); double randYvel=Math.random()*(2*posNeg); double randZvel=Math.random()*(2*posNeg); this.worldObj.spawnParticle("magicCrit", xCoord, yCoord, zCoord, randXvel, randYvel, randZvel); } switch(packet.getType()) { case RESPOND: direction = packet.getOrigin().peek(); result = (direction!=-1); result = pushPacket(packet); break; default: direction = packet.getOrigin().peek(); packet.getOrigin().add(randDir(direction).toByte()); result=pushPacket(packet); break; } } super.updateEntity(); } private I_PipeDirection randDir(byte initDirection) { int randNum=(int)(Math.random()*connections.size()); return connections.get(randNum); } public boolean checkConnections() { boolean result=false; int x,y,z; for(x=-1;x<2;x++) { for(y=-1;y<2;y++) { for(z=-1;z<2;z++) { Block target = worldObj.getBlock(xCoord+x, yCoord+y, zCoord+z); if(target.hasTileEntity(target.getDamageValue(worldObj, xCoord+x, yCoord+y, zCoord+z))&&MFHelper.checkConnectable(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))) { boolean twoWay = (worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable; formConnection(twoWay, x,y,z); } } } } return result; } @Override public void formConnection(boolean twoWay, int x, int y, int z) { connections.add(new PipeDirection(x, y, z)); if (twoWay) ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); System.out.println("connection formed"); } @Override public void breakConnection(I_PipeDirection direction) { // if ((worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))instanceof I_MFCable) // ((I_MFCable)(worldObj.getTileEntity(xCoord+x, yCoord+y, zCoord+z))).formConnection(false, -x, -y, -z); // System.out.println("connection removed"); // connections.remove(direction); } @Override public boolean pushPacket(MFPacket packet) { byte direction = packet.getOrigin().peek(); if(packet.getType()==E_MFPacketType.RESPOND) packet.getOrigin().pop(); boolean result= false; int[]origin = {xCoord,yCoord,zCoord}; int[] target = new PipeDirection(direction).getTarget(); for(int i=0;i<3;i++) { target[i]+=origin[i]; } result = this.worldObj.getBlock(target[0], target[1], target[2]).hasTileEntity(0); if(result) result=this.worldObj.getTileEntity(target[0], target[1], target[2])instanceof I_MFSink; if(result) result=((I_MFSink)this.worldObj.getTileEntity(target[0], target[1], target[2])).takePacket(packet); if(!result) powerBleed(packet.getBuffer()); return result; } @Override public boolean canUpdate() { return true; } @Override public double flowLimit() { return packetSizeLimit; } @Override public void powerBleed(double excess) { //add power bleed to chunk atmosphere -> own effects + taint if Thaumcraft installed if(excess>0) System.err.println(""+excess+" MF bled off into atmosphere!\n"); } @Override public double getPacketLimit() { return packetSizeLimit; } @Override public boolean isInsulated() { return insulatedCable; } @Override public boolean isBridged() { return bridgeConnections; } @Override public boolean canDeBridge() { return insulatedCable; } @Override public List<I_PipeDirection> getConnections() { return connections; } } [spoiler=Renderer] package net.RPower.RPowermod.renderers.block; import org.lwjgl.opengl.GL11; import RPower.api.power.cable.I_PipeDirection; import cpw.mods.fml.client.registry.RenderingRegistry; import net.RPower.RPowermod.machines.power.cable.TileEntityFluxCable; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.shader.TesselatorVertexState; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; /** * * @author Minothor, Flenix *Renders the card Decks in the world *Adapted from Flenix's Tutorial at: *http://www.minecraftforge.net/wiki/Rendering_a_Techne_Model_as_a_Block */ //TODO: Cancel rendering if not visible //Current Idea: Player.yaw/pitch trigonometry && sky light public class TileEntityFluxCableRenderer extends TileEntitySpecialRenderer { private final ResourceLocation texture; public static int blockRenderId; public static final float pixel = 1.0F/16; public TileEntityFluxCableRenderer() { blockRenderId = RenderingRegistry.getNextAvailableRenderId(); texture = new ResourceLocation(net.RPower.RPowermod.core.RPCore.modid+":textures/blocks/fluxCable.png"); } @Override public void renderTileEntityAt(TileEntity entity, double x, double y, double z, float scale) { //binding the textures Minecraft.getMinecraft().renderEngine.bindTexture(texture); GL11.glPushMatrix(); //initial location (what's up with the 0.5 and 1.5 difference I wonder) GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); GL11.glDisable(GL11.GL_CULL_FACE); drawHub(); //let LWGL know we're doing more matixy manipulation stuff //rotate to avoid model rendering upside down for (I_PipeDirection connection : ((TileEntityFluxCable)entity).connections) { int[] target = connection.getTarget(); float[] angles = {0,0,0}; if(target[1]!=0) { if((target[0]==0)&&(target[2]==0)) { angles[2]=90F; } else { angles[2]=35F; } } if((target[0]!=0)&&(target[2]!=0)) { angles[0]=45; angles[2]=45; } else { angles[0]=90; angles[2]=90; } angles[0]*=target[0]; angles[1]*=target[1]; angles[2]*=target[2]; drawConnector(angles); } //pop both sections off the render stack GL11.glPopMatrix(); //System.out.println("FOV : "+Minecraft.getMinecraft().gameSettings.fovSetting); GL11.glEnable(GL11.GL_CULL_FACE); } private void drawHub() { Tessellator tessellator = Tessellator.instance; tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //90x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //180x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); //270x tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); GL11.glRotatef(90, 0, 1, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(180, 0, 1, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(2*pixel, 2*pixel, 2*pixel, 4*pixel,1); tessellator.addVertexWithUV(-2*pixel, 2*pixel, 2*pixel, 0,1); tessellator.addVertexWithUV(-2*pixel, -2*pixel, 2*pixel, 0,12*pixel); tessellator.addVertexWithUV(2*pixel, -2*pixel, 2*pixel, 4*pixel,12*pixel); tessellator.draw(); GL11.glRotatef(90, 0, 1, 0); } private void drawRails(int size) { GL11.glPushMatrix(); GL11.glRotatef(45, 1, 0, 0); Tessellator tessellator = Tessellator.instance; drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); drawRail(size, tessellator); GL11.glRotatef(90, 1, 0, 0); GL11.glRotatef(-45, 1, 0, 0); GL11.glPopMatrix(); } private void drawRail(int size, Tessellator tessellator) { float offset=27.4F; GL11.glRotatef(45F-offset, 1, 0, 0); GL11.glRotatef(-offset, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 0.5*pixel, -2*pixel, size*pixel, 1*pixel); tessellator.addVertexWithUV(size*pixel, 0.5*pixel, -2*pixel, 0*pixel, 0*pixel); tessellator.addVertexWithUV(size*pixel, -0.5*pixel, -2*pixel, 0*pixel, 0*pixel); tessellator.addVertexWithUV(0, -0.5*pixel, -2*pixel, size*pixel, 1*pixel); tessellator.draw(); GL11.glRotatef(offset, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 0.5*pixel, -2*pixel, size*pixel, 2*pixel); tessellator.addVertexWithUV(size*pixel, 0.5*pixel, -2*pixel, 0*pixel, 1*pixel); tessellator.addVertexWithUV(size*pixel, -0.5*pixel, -2*pixel, 0*pixel, 1*pixel); tessellator.addVertexWithUV(0, -0.5*pixel, -2*pixel, size*pixel, 2*pixel); tessellator.draw(); GL11.glRotatef(-45F+offset, 1, 0, 0); } private void drawCore(int size) { GL11.glPushMatrix(); Tessellator tessellator = Tessellator.instance; tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 1*pixel, 0, size*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, 1*pixel, 0, 0*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, -1*pixel, 0, 0*pixel, 6*pixel); tessellator.addVertexWithUV(0, -1*pixel, 0, size*pixel, 6*pixel); tessellator.draw(); GL11.glRotatef(90, 1, 0, 0); tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0, 1*pixel, 0, size*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, 1*pixel, 0, 0*pixel, 8*pixel); tessellator.addVertexWithUV(size*pixel, -1*pixel, 0, 0*pixel, 6*pixel); tessellator.addVertexWithUV(0, -1*pixel, 0, size*pixel, 6*pixel); tessellator.draw(); GL11.glRotatef(90, -1, 0, 0); GL11.glPopMatrix(); } private void drawConnector(float[] angle) { int size = 8; if((angle[1]!=90)||(angle[1]!=90)) size+=3; if(((angle[0]!=90)||(angle[2]!=90))&&((angle[0]!=-90)||(angle[2]!=-90))) size+=3; GL11.glRotatef(angle[0], 1, 0, 0); GL11.glRotatef(angle[1], 0, 1, 0); GL11.glRotatef(angle[2], 0, 0, 1); drawCore(size); drawRails(size); GL11.glRotatef(-angle[2], 0, 0, 1); GL11.glRotatef(-angle[1], 0, 1, 0); GL11.glRotatef(-angle[0], 1, 0, 0); } private void adjustLightFixture(World world, int x, int y, int z, Block block) { Tessellator tess = Tessellator.instance; float brightness = block.getLightValue(world, x, y, z); int skyLight = world.getLightBrightnessForSkyBlocks(x, y, z, 0); int modulousModifier = skyLight % 65536; int divModifier = skyLight / 65536; tess.setColorOpaque_F(brightness, brightness, brightness); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, modulousModifier, divModifier); } } [spoiler=Console Output] Result of above testing: https://lh4.googleusercontent.com/-AQwAhw6jNJE/U_xeCFIR-ZI/AAAAAAAAB-Y/Ui_Nkaqezto/w854-h480-no/2014-08-26_12.13.16.png[/img] Mockups of designed behaviours: https://lh6.googleusercontent.com/-N4-qAOds6d4/U_sGZXq5OJI/AAAAAAAAB9w/vRdSYcWbflI/w854-h480-no/2014-08-25_11.43.51.png[/img] https://lh4.googleusercontent.com/-pYd_nllX6ds/U_tKtnjkPyI/AAAAAAAAB-E/qGGlsLewXi0/w854-h480-no/2014-08-25_16.38.51.png[/img]
  21. Thanks for the suggestion Whov, but since moving over to using direction Enums, I've kind of gutted the old code for now, this recode should also support "compound directions" too, or in other words, Diagonally connecting pipes. Cheers again for the suggestion of using Tessellator instead, it's proving a little hit&miss to rebuild the model but definitely worth it. I'll repost here with news of either success or failure with this recode.
  22. I'll admit that I'm loathe to do that, while it could have offload some processing to clients, it also relies on the renderer being called for the connections to be functional. I'm going to look into the tesselator now and scrap most of my old code by the way. It also adds in some interesting possibilities for efficiency.
  23. I think I'll have to swap over to the directions Enum actually, it sounds much neater and somewhat less frustrating. as for the openGL, I've been sorely tempted to, this started out as a proof of cencept, to let me see the connections that the pipes were making on the code level. also, another little update, by adding the following to the Block class, I'm getting some rather interesting results.. @Override public void onNeighborChange(IBlockAccess world, int x, int y, int z,int tileX, int tileY, int tileZ) { if(world.getBlock(tileX, tileY, tileZ).hasTileEntity(0) &&MFHelper.checkConnectable(world.getTileEntity(tileX, tileY, tileZ))) { int diffX=x-tileX; int diffY=y-tileY; int diffZ=z-tileZ; int side = 0; if (diffX!=0) side=4; if (diffZ!=0) side=2; if (diffY!=0) side=0; int sideDir=(diffX<0||diffY<0|diffZ<0)?0:1; side+=sideDir; ((TileEntityFluxCable)world.getTileEntity(x, y, z)).connections[side]=true; ((TileEntityFluxCable)world.getTileEntity(tileX, tileY, tileZ)).connections[side-=sideDir]=true; } super.onNeighborChange(world, x, y, z, tileX, tileY, tileZ); } https://lh6.googleusercontent.com/-N4-qAOds6d4/U_sGZXq5OJI/AAAAAAAAB9w/vRdSYcWbflI/w854-h480-no/2014-08-25_11.43.51.png[/img] Also, cheers Whov and Mastodon, I'll slice and dice checkConnections() myself too (11:50 am here, so plenty of the time left in the day for me)
  24. Just a head's up, the model is a lot of faces: // Date: 21/08/2014 21:03:22 // Template version 1.1 // Java generated by Techne // Keep in mind that you still need to fill in some blanks // - ZeuX package net.RPower.RPowermod.model.block; import net.RPower.RPowermod.machines.power.cable.TileEntityFluxCable; import net.RPower.RPowermod.renderers.block.TileEntityFluxCableRenderer; import net.minecraft.client.model.*; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; public class ModelFluxCableBasic extends ModelBase { //fields ModelRenderer fFaceR; ModelRenderer fFaceU; ModelRenderer fFaceD; ModelRenderer fFaceL; ModelRenderer fcoreL; ModelRenderer fcoreR; ModelRenderer lFaceB; ModelRenderer lFaceU; ModelRenderer lFaceD; ModelRenderer lFaceF; ModelRenderer lcoreL; ModelRenderer lcoreR; ModelRenderer rFaceB; ModelRenderer rFaceU; ModelRenderer rFaceD; ModelRenderer rFaceF; ModelRenderer rcoreL; ModelRenderer rcoreR; ModelRenderer coreR; ModelRenderer coreF; ModelRenderer coreL; ModelRenderer coreD; ModelRenderer coreB; ModelRenderer coreU; ModelRenderer dFaceB; ModelRenderer dFaceL; ModelRenderer dFaceR; ModelRenderer dFaceF; ModelRenderer dcoreL; ModelRenderer dcoreR; ModelRenderer uFaceB; ModelRenderer uFaceL; ModelRenderer uFaceR; ModelRenderer uFaceF; ModelRenderer ucoreL; ModelRenderer ucoreR; ModelRenderer bFaceR; ModelRenderer bFaceU; ModelRenderer bFaceD; ModelRenderer bFaceL; ModelRenderer bcoreL; ModelRenderer bcoreR; public ModelFluxCableBasic() { textureWidth = 16; textureHeight = 16; fFaceR = new ModelRenderer(this, 0, 0); fFaceR.addBox(0F, 0F, 0F, 6, 3, 0); fFaceR.setRotationPoint(-2F, 16F, -8F); fFaceR.setTextureSize(16, 16); fFaceR.mirror = true; setRotation(fFaceR, -2.356194F, -1.570796F, 0F); fFaceU = new ModelRenderer(this, 0, 0); fFaceU.addBox(0F, 0F, 0F, 6, 3, 0); fFaceU.setRotationPoint(2F, 16F, -8F); fFaceU.setTextureSize(16, 16); fFaceU.mirror = true; setRotation(fFaceU, 2.356194F, -1.570796F, 0F); fFaceD = new ModelRenderer(this, 0, 0); fFaceD.addBox(0F, 0F, 0F, 6, 3, 0); fFaceD.setRotationPoint(-2F, 16F, -8F); fFaceD.setTextureSize(16, 16); fFaceD.mirror = true; setRotation(fFaceD, -0.7853982F, -1.570796F, 0F); fFaceL = new ModelRenderer(this, 0, 0); fFaceL.addBox(0F, 0F, 0F, 6, 3, 0); fFaceL.setRotationPoint(2F, 16F, -8F); fFaceL.setTextureSize(16, 16); fFaceL.mirror = true; setRotation(fFaceL, 0.7853982F, -1.570796F, 0F); fcoreL = new ModelRenderer(this, 0, 6); fcoreL.addBox(0F, 0F, 0F, 6, 2, 0); fcoreL.setRotationPoint(-1F, 16F, -2F); fcoreL.setTextureSize(16, 16); fcoreL.mirror = true; setRotation(fcoreL, 1.570796F, 1.570796F, 0F); fcoreR = new ModelRenderer(this, 0, 6); fcoreR.addBox(0F, 0F, 0F, 6, 2, 0); fcoreR.setRotationPoint(0F, 15F, -2F); fcoreR.setTextureSize(16, 16); fcoreR.mirror = true; setRotation(fcoreR, 0F, 1.570796F, 0F); lFaceB = new ModelRenderer(this, 0, 0); lFaceB.addBox(0F, 0F, 0F, 6, 3, 0); lFaceB.setRotationPoint(2F, 16F, 2F); lFaceB.setTextureSize(16, 16); lFaceB.mirror = true; setRotation(lFaceB, -2.356194F, 0F, 0F); lFaceU = new ModelRenderer(this, 0, 0); lFaceU.addBox(0F, 0F, 0F, 6, 3, 0); lFaceU.setRotationPoint(2F, 16F, -2F); lFaceU.setTextureSize(16, 16); lFaceU.mirror = true; setRotation(lFaceU, 2.356194F, 0F, 0F); lFaceD = new ModelRenderer(this, 0, 0); lFaceD.addBox(0F, 0F, 0F, 6, 3, 0); lFaceD.setRotationPoint(2F, 16F, 2F); lFaceD.setTextureSize(16, 16); lFaceD.mirror = true; setRotation(lFaceD, -0.7853982F, 0F, 0F); lFaceF = new ModelRenderer(this, 0, 0); lFaceF.addBox(0F, 0F, 0F, 6, 3, 0); lFaceF.setRotationPoint(2F, 16F, -2F); lFaceF.setTextureSize(16, 16); lFaceF.mirror = true; setRotation(lFaceF, 0.7853982F, -0.0069813F, 0F); lcoreL = new ModelRenderer(this, 0, 6); lcoreL.addBox(0F, 0F, 0F, 6, 2, 0); lcoreL.setRotationPoint(2F, 16F, -1F); lcoreL.setTextureSize(16, 16); lcoreL.mirror = true; setRotation(lcoreL, 1.570796F, 0F, 0F); lcoreR = new ModelRenderer(this, 0, 6); lcoreR.addBox(0F, 0F, 0F, 6, 2, 0); lcoreR.setRotationPoint(2F, 15F, 0F); lcoreR.setTextureSize(16, 16); lcoreR.mirror = true; setRotation(lcoreR, 0F, 0F, 0F); rFaceB = new ModelRenderer(this, 0, 0); rFaceB.addBox(0F, 0F, 0F, 6, 3, 0); rFaceB.setRotationPoint(-8F, 16F, 2F); rFaceB.setTextureSize(16, 16); rFaceB.mirror = true; setRotation(rFaceB, -0.7853982F, 0F, 0F); rFaceU = new ModelRenderer(this, 0, 0); rFaceU.addBox(0F, 0F, 0F, 6, 3, 0); rFaceU.setRotationPoint(-8F, 14F, 0F); rFaceU.setTextureSize(16, 16); rFaceU.mirror = true; setRotation(rFaceU, 0.7853982F, 0F, 0F); rFaceD = new ModelRenderer(this, 0, 0); rFaceD.addBox(0F, 0F, 0F, 6, 3, 0); rFaceD.setRotationPoint(-8F, 18F, 0F); rFaceD.setTextureSize(16, 16); rFaceD.mirror = true; setRotation(rFaceD, -2.356194F, 0F, 0F); rFaceF = new ModelRenderer(this, 0, 0); rFaceF.addBox(0F, 0F, 0F, 6, 3, 0); rFaceF.setRotationPoint(-8F, 14F, 0F); rFaceF.setTextureSize(16, 16); rFaceF.mirror = true; setRotation(rFaceF, -0.7853982F, 0F, 0F); rcoreL = new ModelRenderer(this, 0, 6); rcoreL.addBox(0F, 0F, 0F, 6, 2, 0); rcoreL.setRotationPoint(-8F, 16F, -1F); rcoreL.setTextureSize(16, 16); rcoreL.mirror = true; setRotation(rcoreL, 1.570796F, 0F, 0F); rcoreR = new ModelRenderer(this, 0, 6); rcoreR.addBox(0F, 0F, 0F, 6, 2, 0); rcoreR.setRotationPoint(-8F, 15F, 0F); rcoreR.setTextureSize(16, 16); rcoreR.mirror = true; setRotation(rcoreR, 0F, 0F, 0F); coreR = new ModelRenderer(this, 0, 12); coreR.addBox(0F, 0F, 0F, 4, 4, 0); coreR.setRotationPoint(-2F, 14F, 2F); coreR.setTextureSize(16, 16); coreR.mirror = true; setRotation(coreR, 0F, 1.570796F, 0F); coreF = new ModelRenderer(this, 0, 12); coreF.addBox(0F, 0F, 0F, 4, 4, 0); coreF.setRotationPoint(-2F, 14F, -2F); coreF.setTextureSize(16, 16); coreF.mirror = true; setRotation(coreF, 0F, 0F, 0F); coreL = new ModelRenderer(this, 0, 12); coreL.addBox(0F, 0F, 0F, 4, 4, 0); coreL.setRotationPoint(2F, 14F, -2F); coreL.setTextureSize(16, 16); coreL.mirror = true; setRotation(coreL, 0F, -1.570796F, 0F); coreD = new ModelRenderer(this, 0, 12); coreD.addBox(0F, 0F, 0F, 4, 4, 0); coreD.setRotationPoint(2F, 18F, 2F); coreD.setTextureSize(16, 16); coreD.mirror = true; setRotation(coreD, 1.570796F, -3.141593F, 0F); coreB = new ModelRenderer(this, 0, 12); coreB.addBox(0F, 0F, 0F, 4, 4, 0); coreB.setRotationPoint(2F, 14F, 2F); coreB.setTextureSize(16, 16); coreB.mirror = true; setRotation(coreB, 0F, -3.141593F, 0F); coreU = new ModelRenderer(this, 0, 12); coreU.addBox(0F, 0F, 0F, 4, 4, 0); coreU.setRotationPoint(2F, 14F, -2F); coreU.setTextureSize(16, 16); coreU.mirror = true; setRotation(coreU, -1.570796F, 3.141593F, 0F); dFaceB = new ModelRenderer(this, 0, 0); dFaceB.addBox(0F, 0F, 0F, 6, 3, 0); dFaceB.setRotationPoint(2F, 18F, 0F); dFaceB.setTextureSize(16, 16); dFaceB.mirror = true; setRotation(dFaceB, 0.7853982F, 0F, 1.570796F); dFaceL = new ModelRenderer(this, 0, 0); dFaceL.addBox(0F, 0F, 0F, 6, 3, 0); dFaceL.setRotationPoint(0F, 18F, -2F); dFaceL.setTextureSize(16, 16); dFaceL.mirror = true; setRotation(dFaceL, 2.356194F, 0F, 1.570796F); dFaceR = new ModelRenderer(this, 0, 0); dFaceR.addBox(0F, 0F, 0F, 6, 3, 0); dFaceR.setRotationPoint(-2F, 18F, 0F); dFaceR.setTextureSize(16, 16); dFaceR.mirror = true; setRotation(dFaceR, 2.356194F, 0F, 1.570796F); dFaceF = new ModelRenderer(this, 0, 0); dFaceF.addBox(0F, 0F, 0F, 6, 3, 0); dFaceF.setRotationPoint(0F, 18F, -2F); dFaceF.setTextureSize(16, 16); dFaceF.mirror = true; setRotation(dFaceF, 0.7853982F, 0F, 1.570796F); dcoreL = new ModelRenderer(this, 0, 6); dcoreL.addBox(0F, 0F, 0F, 6, 2, 0); dcoreL.setRotationPoint(0F, 18F, -1F); dcoreL.setTextureSize(16, 16); dcoreL.mirror = true; setRotation(dcoreL, 1.570796F, 0F, 1.570796F); dcoreR = new ModelRenderer(this, 0, 6); dcoreR.addBox(0F, 0F, 0F, 6, 2, 0); dcoreR.setRotationPoint(1F, 18F, 0F); dcoreR.setTextureSize(16, 16); dcoreR.mirror = true; setRotation(dcoreR, 0F, 0F, 1.570796F); uFaceB = new ModelRenderer(this, 0, 0); uFaceB.addBox(0F, 0F, 0F, 6, 3, 0); uFaceB.setRotationPoint(2F, 8F, 0F); uFaceB.setTextureSize(16, 16); uFaceB.mirror = true; setRotation(uFaceB, 0.7853982F, 0F, 1.570796F); uFaceL = new ModelRenderer(this, 0, 0); uFaceL.addBox(0F, 0F, 0F, 6, 3, 0); uFaceL.setRotationPoint(0F, 8F, -2F); uFaceL.setTextureSize(16, 16); uFaceL.mirror = true; setRotation(uFaceL, 2.356194F, 0F, 1.570796F); uFaceR = new ModelRenderer(this, 0, 0); uFaceR.addBox(0F, 0F, 0F, 6, 3, 0); uFaceR.setRotationPoint(-2F, 8F, 0F); uFaceR.setTextureSize(16, 16); uFaceR.mirror = true; setRotation(uFaceR, 2.356194F, 0F, 1.570796F); uFaceF = new ModelRenderer(this, 0, 0); uFaceF.addBox(0F, 0F, 0F, 6, 3, 0); uFaceF.setRotationPoint(0F, 8F, -2F); uFaceF.setTextureSize(16, 16); uFaceF.mirror = true; setRotation(uFaceF, 0.7853982F, 0F, 1.570796F); ucoreL = new ModelRenderer(this, 0, 6); ucoreL.addBox(0F, 0F, 0F, 6, 2, 0); ucoreL.setRotationPoint(0F, 8F, -1F); ucoreL.setTextureSize(16, 16); ucoreL.mirror = true; setRotation(ucoreL, 1.570796F, 0F, 1.570796F); ucoreR = new ModelRenderer(this, 0, 6); ucoreR.addBox(0F, 0F, 0F, 6, 2, 0); ucoreR.setRotationPoint(1F, 8F, 0F); ucoreR.setTextureSize(16, 16); ucoreR.mirror = true; setRotation(ucoreR, 0F, 0F, 1.570796F); bFaceR = new ModelRenderer(this, 0, 0); bFaceR.addBox(0F, 0F, 0F, 6, 3, 0); bFaceR.setRotationPoint(-2F, 16F, 2F); bFaceR.setTextureSize(16, 16); bFaceR.mirror = true; setRotation(bFaceR, -2.356194F, -1.570796F, 0F); bFaceU = new ModelRenderer(this, 0, 0); bFaceU.addBox(0F, 0F, 0F, 6, 3, 0); bFaceU.setRotationPoint(2F, 16F, 2F); bFaceU.setTextureSize(16, 16); bFaceU.mirror = true; setRotation(bFaceU, 2.356194F, -1.570796F, 0F); bFaceD = new ModelRenderer(this, 0, 0); bFaceD.addBox(0F, 0F, 0F, 6, 3, 0); bFaceD.setRotationPoint(-2F, 16F, 2F); bFaceD.setTextureSize(16, 16); bFaceD.mirror = true; setRotation(bFaceD, -0.7853982F, -1.570796F, 0F); bFaceL = new ModelRenderer(this, 0, 0); bFaceL.addBox(0F, 0F, 0F, 6, 3, 0); bFaceL.setRotationPoint(2F, 16F, 2F); bFaceL.setTextureSize(16, 16); bFaceL.mirror = true; setRotation(bFaceL, 0.7853982F, -1.570796F, 0F); bcoreL = new ModelRenderer(this, 0, 6); bcoreL.addBox(0F, 0F, 0F, 6, 2, 0); bcoreL.setRotationPoint(-1F, 16F, 8F); bcoreL.setTextureSize(16, 16); bcoreL.mirror = true; setRotation(bcoreL, 1.570796F, 1.570796F, 0F); bcoreR = new ModelRenderer(this, 0, 6); bcoreR.addBox(0F, 0F, 0F, 6, 2, 0); bcoreR.setRotationPoint(0F, 15F, 8F); bcoreR.setTextureSize(16, 16); bcoreR.mirror = true; setRotation(bcoreR, 0F, 1.570796F, 0F); } public void render(TileEntity entity, float f, float f1, float f2, float f3, float f4, float f5) { boolean[] connections = {false, false, false, false, false, false}; if (entity instanceof TileEntityFluxCable) connections= ((TileEntityFluxCable)entity).connections; super.render((Entity)null, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, (Entity)null); if (connections[3]){ fFaceR.render(f5); fFaceU.render(f5); fFaceD.render(f5); fFaceL.render(f5); fcoreL.render(f5); fcoreR.render(f5); } if (connections[5]){ lFaceB.render(f5); lFaceU.render(f5); lFaceD.render(f5); lFaceF.render(f5); lcoreL.render(f5); lcoreR.render(f5); } if (connections[4]){ rFaceB.render(f5); rFaceU.render(f5); rFaceD.render(f5); rFaceF.render(f5); rcoreL.render(f5); rcoreR.render(f5); } coreR.render(f5); coreF.render(f5); coreL.render(f5); coreD.render(f5); coreB.render(f5); coreU.render(f5); if (connections[1]){ dFaceB.render(f5); dFaceL.render(f5); dFaceR.render(f5); dFaceF.render(f5); dcoreL.render(f5); dcoreR.render(f5); } if (connections[0]){ uFaceB.render(f5); uFaceL.render(f5); uFaceR.render(f5); uFaceF.render(f5); ucoreL.render(f5); ucoreR.render(f5); } if (connections[2]){ bFaceR.render(f5); bFaceU.render(f5); bFaceD.render(f5); bFaceL.render(f5); bcoreL.render(f5); bcoreR.render(f5); } } private void setRotation(ModelRenderer model, float x, float y, float z) { model.rotateAngleX = x; model.rotateAngleY = y; model.rotateAngleZ = z; } public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){ super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); } } As for binding, yes it's registered in the clientProxy in the function: @Override public void registerRenderers(){ ClientRegistry.bindTileEntitySpecialRenderer(TileEntityFluxCable.class, new TileEntityFluxCableRenderer()); } From the console output, it finds the cables on the right sides and returns "true", if I set the connections array manually, either in the code or with the onBlockActivated, I get get it to correctly display or connect to any dirction I wish without issue, it really is just the automatic connection mode. I hadn't heard of ForgeDirections though, I'll take a look at that, thanks! I was using the side-to-direction mapping that Grey's site gives, calculating the details from the (0 to 5)%2 for positive/negative switching and (0 to 5)/2 for the three axis.
  25. Sorry to bump this, but I'm still struggling to make this work. Currently it's connecting and transferrign packets perfectly in the -y direction, but none other. I've tried altering the direction code to no avail and the visual connection updates still only load after a chunk reload. I've tried both notifyBlockUpdate(x,y,z,block) and scheduleBlockUpdate(x,y,z,block,metaD), both to no avail. If anyone has any insights into this, I'd be extrememy grateful! https://lh4.googleusercontent.com/-y0Z8JIlKxcY/U_rvgRmsm6I/AAAAAAAAB9M/A2kcrAVrn5w/w854-h480-no/2014-08-25_10.02.48.png[/img] Updated Code: package net.RPower.RPowermod.machines.power.cable; import java.util.LinkedList; import java.util.Queue; import RPower.api.power.E_MFPacketType; import RPower.api.power.I_MFSink; import RPower.api.power.MFPacket; import RPower.api.power.cable.I_MFCable; import net.RPower.RPowermod.core.RPCore; import net.RPower.RPowermod.machines.power.MFHelper; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; public class TileEntityFluxCable extends TileEntity implements I_MFCable { //Connections are an array of [up, Down, North, East, West, South] public boolean[] connections = {false, false, false, false, false, false}; //whether or not the cable is lossy public boolean insulatedCable; //maximum limit the cable can carry public double packetSizeLimit; //Packets awaiting processing public Queue<MFPacket> internalBuffer; //automatically calculated. public double percentageLoss; //transfer mode, unbridged connections can only cross an intersection in straight lines (may be reserved for advanced cabling) public boolean bridgeConnections; public TileEntityFluxCable() { this(32); } public TileEntityFluxCable(double packetSize) { this(packetSize,false); } public TileEntityFluxCable(double packetSize, boolean insulated) { this(packetSize,insulated,true); } public TileEntityFluxCable(double packetSize, boolean insulated,boolean bridged) { packetSizeLimit= packetSize; insulatedCable=insulated; bridgeConnections=bridged; internalBuffer=new LinkedList<MFPacket>(); checkLoss(insulated); } private void checkLoss(boolean insulated) { if(!insulated) { percentageLoss=(packetSizeLimit/MFPacket.POWERLIMIT); } } @Override public boolean takePacket(MFPacket packet) { double excess=0; if(!insulatedCable) { excess+=(percentageLoss*packet.getBuffer()); packet.setBuffer(packet.getBuffer()-excess); } if(packet.getBuffer()>packetSizeLimit) { excess += packet.getBuffer()-packetSizeLimit; packet.setBuffer(packetSizeLimit); } powerBleed(excess); boolean result=false; result=internalBuffer.add(packet); return result; } @Override public void writeToNBT(NBTTagCompound nbtTag) { int[] connectionsInt = new int[6]; int i = 0; for (boolean side : connections) { connectionsInt[i]=connections[i]?1:0; i++; } nbtTag.setIntArray("connections", connectionsInt); nbtTag.setBoolean("insulated", insulatedCable); nbtTag.setBoolean("bridged", bridgeConnections); nbtTag.setDouble("packetLimit", packetSizeLimit); super.writeToNBT(nbtTag); }; @Override public void readFromNBT(NBTTagCompound nbtTag) { int[] connectionsInt = nbtTag.getIntArray("connections"); int i = 0; for (boolean side : connections) { connections[i]=(connectionsInt[i]==1); i++; } insulatedCable=nbtTag.getBoolean("insulated"); bridgeConnections=nbtTag.getBoolean("bridged"); packetSizeLimit=nbtTag.getDouble("packetLimit"); checkLoss(insulatedCable); super.readFromNBT(nbtTag); }; @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTag = new NBTTagCompound(); this.writeToNBT(nbtTag); //TODO: Get this damn working! return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } @Override public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } @Override public void updateEntity() { if(!internalBuffer.isEmpty()) { MFPacket packet = internalBuffer.remove(); boolean result=false; byte direction; for(int i=0; i<59;i++) { int posNeg = ((int)(Math.random()*%2==0)?1:-1; double randXvel=Math.random()*(2*posNeg); double randYvel=Math.random()*(2*posNeg); double randZvel=Math.random()*(2*posNeg); this.worldObj.spawnParticle("magicCrit", xCoord, yCoord, zCoord, randXvel, randYvel, randZvel); } switch(packet.getType()) { case RESPOND: direction = packet.getOrigin().peek(); result = (direction!=-1); result = pushPacket(packet); break; default: direction = packet.getOrigin().peek(); packet.getOrigin().add(randDir(direction)); result=pushPacket(packet); break; } } super.updateEntity(); } private byte randDir(byte initDirection) { byte result = -1; while((connectionNum()>=2)&&(result==-1||!connections[result])&&result!=initDirection) { result=(byte)(Math.random()*5); } return result; } public byte connectionNum() { byte result=0; for (Boolean connection : connections) { if(connection) result++; } return result; } public boolean checkConnections() { boolean result=false; int xDir=0, yDir=0, zDir=0; for(int dir=0; dir<=5; dir++) { int modifier=(dir%2==1)?1:-1; System.err.println("test vars: dir="+dir+", TestCase="+(dir/2)+", modifier="+modifier+","); switch(dir/2) { case 2: xDir=modifier; break; case 1: zDir=modifier; break; case 0: yDir=modifier; break; } System.out.println("testing ["+xDir+","+yDir+","+zDir+"]"); result = this.worldObj.getBlock(xCoord+xDir, yCoord+yDir, zCoord+zDir).hasTileEntity(0); if(result) result = MFHelper.checkConnectable(this.worldObj.getTileEntity(xCoord+xDir, yCoord+yDir, zCoord+zDir)); System.out.println("result of MF test was: "+result); int conDir = dir-modifier; System.err.println("conDir="+conDir); connections[conDir]=result; if(connections[conDir]) { System.out.println("Connection found!"); worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, getBlockType(), worldObj.getBlockMetadata(xCoord, yCoord, zCoord)); } } return result; } @Override public boolean pushPacket(MFPacket packet) { byte direction = packet.getOrigin().peek(); if(packet.getType()==E_MFPacketType.RESPOND) packet.getOrigin().pop(); boolean result= false; int xDir=0, yDir=0, zDir=0; int modifier=(direction%2==1)?-1:1; //up:1, down:0, x+:5, x-:4, z+:3,z-2; switch(direction/2) { case 2: xDir=modifier; break; case 1: zDir=modifier; break; case 0: yDir=modifier; break; } result = this.worldObj.getBlock(xCoord+xDir, yCoord+yDir, zCoord+zDir).hasTileEntity(0); if(result) result=this.worldObj.getTileEntity(xCoord+xDir, yCoord+yDir, zCoord+zDir)instanceof I_MFSink; if(result) result=((I_MFSink)this.worldObj.getTileEntity(xCoord+xDir, yCoord+yDir, zCoord+zDir)).takePacket(packet); if(!result) powerBleed(packet.getBuffer()); return result; } @Override public boolean canUpdate() { return true; } @Override public double flowLimit() { return packetSizeLimit; } @Override public void powerBleed(double excess) { //add power bleed to chunk atmosphere -> own effects + taint if Thaumcraft installed if(excess>0) System.err.println(""+excess+" MF bled off into atmosphere!\n"); } @Override public double getPacketLimit() { return packetSizeLimit; } @Override public boolean isInsulated() { return insulatedCable; } @Override public boolean isBridged() { return bridgeConnections; } @Override public boolean canDeBridge() { return insulatedCable; } @Override public boolean[] getConnections() { return connections; } }
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.