More work on mechanical networks

This commit is contained in:
DarkGuardsman 2014-01-14 15:13:39 -05:00
parent 026ecfff34
commit 95ce03ee48
11 changed files with 633 additions and 293 deletions

View file

@ -3,21 +3,19 @@ package resonantinduction.api;
import java.util.List; import java.util.List;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import universalelectricity.api.net.IConnector;
/** An interface applied to the tile entity of a conveyor belt */ /** An interface applied to the tile entity of a conveyor belt
public interface IBelt * @Author DarkGuardsman */
public interface IBelt extends IConnector<IBeltNetwork>
{ {
/** /** Used to get a list of entities the belt exerts an effect upon.
* Used to get a list of entities the belt exerts an effect upon.
* *
* @return list of entities in the belts are of effect * @return list of entities in the belts are of effect */
*/
public List<Entity> getAffectedEntities(); public List<Entity> getAffectedEntities();
/** /** Adds and entity to the ignore list so its not moved has to be done every 20 ticks
* Adds and entity to the ignore list so its not moved has to be done every 20 ticks
* *
* @param entity * @param entity */
*/
public void ignoreEntity(Entity entity); public void ignoreEntity(Entity entity);
} }

View file

@ -0,0 +1,15 @@
package resonantinduction.api;
import net.minecraft.tileentity.TileEntity;
import universalelectricity.api.net.INetwork;
public interface IBeltNetwork extends INetwork<IBeltNetwork, IBelt, TileEntity>
{
/** Frame of animation the belts all share */
public int frame();
/** Speed to apply to each entity */
public float speed();
public void reconstruct();
}

View file

@ -11,6 +11,7 @@ import calclavia.lib.prefab.tile.TileElectrical;
* @author Calclavia */ * @author Calclavia */
public class TileGenerator extends TileElectrical implements IMechMachine public class TileGenerator extends TileElectrical implements IMechMachine
{ {
//P = \tau \times 2 \pi \times \omega
private long power; private long power;
/** Generator turns KE -> EE. Inverted one will turn EE -> KE. */ /** Generator turns KE -> EE. Inverted one will turn EE -> KE. */
@ -40,7 +41,7 @@ public class TileGenerator extends TileElectrical implements IMechMachine
private boolean isFunctioning() private boolean isFunctioning()
{ {
return true; return this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
} }
@Override @Override
@ -48,4 +49,11 @@ public class TileGenerator extends TileElectrical implements IMechMachine
{ {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public int getForceSide(ForgeDirection side)
{
// TODO Auto-generated method stub
return 0;
}
} }

View file

@ -0,0 +1,160 @@
package resonantinduction.mechanical.belt;
import net.minecraft.tileentity.TileEntity;
import resonantinduction.api.IBelt;
import resonantinduction.api.IBeltNetwork;
import resonantinduction.mechanical.network.IMechConnector;
import resonantinduction.mechanical.network.IMechNetwork;
import resonantinduction.mechanical.network.MechNetwork;
import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network;
/** Network used to update belts in a uniform way
*
* @author DarkGuardsman */
public class BeltNetwork extends Network<IBeltNetwork, IBelt, TileEntity> implements IBeltNetwork
{
@Override
public boolean canUpdate()
{
// TODO Auto-generated method stub
return false;
}
@Override
public boolean continueUpdate()
{
// TODO Auto-generated method stub
return false;
}
@Override
public void update()
{
// TODO Auto-generated method stub
}
@Override
public IBeltNetwork merge(IBeltNetwork network)
{
if (network.getClass().isAssignableFrom(this.getClass()) && network != this)
{
BeltNetwork newNetwork = new BeltNetwork();
newNetwork.getConnectors().addAll(this.getConnectors());
newNetwork.getConnectors().addAll(network.getConnectors());
network.getConnectors().clear();
network.getNodes().clear();
this.getConnectors().clear();
this.getNodes().clear();
newNetwork.reconstruct();
return newNetwork;
}
return null;
}
@Override
public void split(IBelt splitPoint)
{
this.removeConnector(splitPoint);
this.reconstruct();
/** Loop through the connected blocks and attempt to see if there are connections between the
* two points elsewhere. */
Object[] connectedBlocks = splitPoint.getConnections();
for (int i = 0; i < connectedBlocks.length; i++)
{
Object connectedBlockA = connectedBlocks[i];
if (connectedBlockA instanceof IBelt)
{
for (int ii = 0; ii < connectedBlocks.length; ii++)
{
final Object connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IBelt)
{
ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint);
finder.findNodes((IConnector) connectedBlockA);
if (finder.results.size() <= 0)
{
try
{
/** The connections A and B are not connected anymore. Give them both
* a new common network. */
IBeltNetwork newNetwork = new BeltNetwork();
for (IConnector node : finder.closedSet)
{
if (node != splitPoint && node instanceof IBelt)
{
newNetwork.addConnector((IBelt) node);
}
}
newNetwork.reconstruct();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
}
@Override
public void split(IBelt connectorA, IBelt connectorB)
{
/** Check if connectorA connects with connectorB. */
ConnectionPathfinder finder = new ConnectionPathfinder(connectorB);
finder.findNodes(connectorA);
if (finder.results.size() <= 0)
{
/** The connections A and B are not connected anymore. Give them both a new common
* network. */
IMechNetwork newNetwork = new MechNetwork();
for (IConnector node : finder.closedSet)
{
if (node instanceof IMechConnector)
{
newNetwork.addConnector((IMechConnector) node);
}
}
newNetwork.reconstruct();
}
}
@Override
public int frame()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public float speed()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public void reconstruct()
{
// TODO Auto-generated method stub
}
}

View file

@ -250,7 +250,7 @@ public class BlockConveyorBelt extends BlockRI
{ {
return; return;
} }
if (tile.isFunctioning() && !world.isBlockIndirectlyGettingPowered(x, y, z)) if (!world.isBlockIndirectlyGettingPowered(x, y, z))
{ {
float acceleration = tile.acceleration; float acceleration = tile.acceleration;
float maxSpeed = tile.maxSpeed; float maxSpeed = tile.maxSpeed;

View file

@ -5,33 +5,35 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import resonantinduction.api.IBelt; import resonantinduction.api.IBelt;
import resonantinduction.api.IBeltNetwork;
import resonantinduction.core.ResonantInduction; import resonantinduction.core.ResonantInduction;
import resonantinduction.core.prefab.tile.TileAssembly;
import resonantinduction.mechanical.Mechanical; import resonantinduction.mechanical.Mechanical;
import universalelectricity.api.vector.Vector3; import universalelectricity.api.vector.Vector3;
import calclavia.lib.network.IPacketReceiverWithID;
import calclavia.lib.prefab.tile.IRotatable; import calclavia.lib.prefab.tile.IRotatable;
import calclavia.lib.prefab.tile.TileAdvanced;
import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.Player; /** Conveyer belt TileEntity that allows entities of all kinds to be moved
/**
* Conveyer belt TileEntity that allows entities of all kinds to be moved
* *
* @author DarkGuardsman * @author DarkGuardsman */
*/ public class TileConveyorBelt extends TileAdvanced implements IBelt, IRotatable, IPacketReceiverWithID
public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
{ {
public enum SlantType public enum SlantType
{ {
NONE, UP, DOWN, TOP NONE,
UP,
DOWN,
TOP
} }
public static final int MAX_FRAME = 13; public static final int MAX_FRAME = 13;
@ -49,11 +51,7 @@ public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
private SlantType slantType = SlantType.NONE; private SlantType slantType = SlantType.NONE;
/** Entities that are ignored allowing for other tiles to interact with them */ /** Entities that are ignored allowing for other tiles to interact with them */
public List<Entity> IgnoreList = new ArrayList<Entity>(); public List<Entity> IgnoreList = new ArrayList<Entity>();
private boolean functioning;
public TileConveyorBelt()
{
super(1);
}
@Override @Override
public void updateEntity() public void updateEntity()
@ -68,7 +66,7 @@ public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
it.remove(); it.remove();
} }
} }
if (this.worldObj.isRemote && this.isFunctioning()) if (this.worldObj.isRemote)
{ {
if (this.ticks % 10 == 0 && this.worldObj.isRemote && this.worldObj.getBlockId(this.xCoord - 1, this.yCoord, this.zCoord) != Mechanical.blockConveyorBelt.blockID && this.worldObj.getBlockId(xCoord, yCoord, zCoord - 1) != Mechanical.blockConveyorBelt.blockID) if (this.ticks % 10 == 0 && this.worldObj.isRemote && this.worldObj.getBlockId(this.xCoord - 1, this.yCoord, this.zCoord) != Mechanical.blockConveyorBelt.blockID && this.worldObj.getBlockId(xCoord, yCoord, zCoord - 1) != Mechanical.blockConveyorBelt.blockID)
{ {
@ -99,33 +97,27 @@ public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
} }
@Override
public boolean canFunction()
{
return super.canFunction() && !this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord);
}
@Override @Override
public Packet getDescriptionPacket() public Packet getDescriptionPacket()
{ {
if (this.slantType != SlantType.NONE) if (this.slantType != SlantType.NONE)
{ {
return ResonantInduction.PACKET_TILE.getPacket(this, slantPacketID, this.isFunctioning(), this.slantType.ordinal()); return ResonantInduction.PACKET_TILE.getPacket(this, slantPacketID, true, this.slantType.ordinal());
} }
return super.getDescriptionPacket(); return super.getDescriptionPacket();
} }
@Override @Override
public boolean simplePacket(String id, ByteArrayDataInput dis, Player player) public boolean onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra)
{ {
if (!super.simplePacket(id, dis, player) && this.worldObj.isRemote) if (this.worldObj.isRemote)
{ {
try try
{ {
if (id.equalsIgnoreCase(slantPacketID)) if (id == 0)
{ {
this.functioning = dis.readBoolean(); this.functioning = data.readBoolean();
this.slantType = SlantType.values()[dis.readInt()]; this.slantType = SlantType.values()[data.readInt()];
return true; return true;
} }
} }
@ -206,10 +198,8 @@ public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
return direction == ForgeDirection.DOWN; return direction == ForgeDirection.DOWN;
} }
@Override
public void refresh() public void refresh()
{ {
super.refresh();
if (this.worldObj != null && !this.worldObj.isRemote) if (this.worldObj != null && !this.worldObj.isRemote)
{ {
Vector3 face = new Vector3(this).modifyPositionFromSide(this.getDirection()); Vector3 face = new Vector3(this).modifyPositionFromSide(this.getDirection());
@ -231,24 +221,36 @@ public class TileConveyorBelt extends TileAssembly implements IBelt, IRotatable
} }
front = face.getTileEntity(this.worldObj); front = face.getTileEntity(this.worldObj);
rear = back.getTileEntity(this.worldObj); rear = back.getTileEntity(this.worldObj);
if (front instanceof TileAssembly) if (front instanceof IBelt)
{ {
this.getTileNetwork().mergeNetwork(((TileAssembly) front).getTileNetwork(), this); this.getNetwork().merge(((IBelt) front).getNetwork());
this.connectedTiles.add(front);
} }
if (rear instanceof TileAssembly) if (rear instanceof IBelt)
{ {
this.getTileNetwork().mergeNetwork(((TileAssembly) rear).getTileNetwork(), this); this.getNetwork().merge(((IBelt) rear).getNetwork());
this.connectedTiles.add(rear);
} }
} }
} }
@Override @Override
public int getWattLoad() public Object[] getConnections()
{ {
return 5; // TODO Auto-generated method stub
return null;
} }
@Override
public IBeltNetwork getNetwork()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void setNetwork(IBeltNetwork network)
{
// TODO Auto-generated method stub
}
} }

View file

@ -217,18 +217,6 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
return "resonant_induction_gear"; return "resonant_induction_gear";
} }
@Override
public long getTorque()
{
return this.torque;
}
@Override
public void setTorque(long torque)
{
this.torque = torque;
}
@Override @Override
public Object[] getConnections() public Object[] getConnections()
{ {
@ -258,4 +246,11 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechConnector; return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechConnector;
} }
@Override
public int getResistance()
{
// TODO Auto-generated method stub
return 0;
}
} }

View file

@ -2,15 +2,10 @@ package resonantinduction.mechanical.network;
import universalelectricity.api.net.IConnector; import universalelectricity.api.net.IConnector;
/** /** For the mechanical network.
* For the mechanical network.
* *
* @author Calclavia * @author Calclavia */
*
*/
public interface IMechConnector extends IConnector<IMechNetwork> public interface IMechConnector extends IConnector<IMechNetwork>
{ {
public long getTorque(); public int getResistance();
public void setTorque(long torque);
} }

View file

@ -8,7 +8,9 @@ import universalelectricity.api.net.IConnectable;
* @author Darkguardsman */ * @author Darkguardsman */
public interface IMechMachine extends IConnectable public interface IMechMachine extends IConnectable
{ {
/** Called by the network when its torque value changes. Force is not given since the network /** Called by the network when its torque value changes. */
* operates on a can move or can't move setup. Speed is given as a represent */
public void onTorqueChange(ForgeDirection side, int speed); public void onTorqueChange(ForgeDirection side, int speed);
/** Gets the force on the side, zero is ignored, neg is input force, pos is output force */
public int getForceSide(ForgeDirection side);
} }

View file

@ -7,9 +7,12 @@ import universalelectricity.api.net.INetwork;
* @author DarkGuardsman */ * @author DarkGuardsman */
public interface IMechNetwork extends INetwork<IMechNetwork, IMechConnector, IMechMachine> public interface IMechNetwork extends INetwork<IMechNetwork, IMechConnector, IMechMachine>
{ {
public int getForce(); /** Power applied by the network at the given speed */
public int getRotSpeed();
public int getTorque(); public int getTorque();
/** Rotation of the the network in a single update */
public int getRotationPerTick();
/** Called to rebuild the network */
public void reconstruct();
} }

View file

@ -1,14 +1,28 @@
package resonantinduction.mechanical.network; package resonantinduction.mechanical.network;
import universalelectricity.core.net.Network; import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/** import net.minecraftforge.common.ForgeDirection;
* @author Calclavia import universalelectricity.api.CompatibilityModule;
import universalelectricity.api.energy.IConductor;
import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network;
import universalelectricity.core.net.NetworkTickHandler;
/** Simple network to translate speed and force using mechanical rotation
* *
*/ * @author DarkGuardsman */
public class MechNetwork extends Network<IMechNetwork, IMechConnector, IMechMachine> implements IMechNetwork public class MechNetwork extends Network<IMechNetwork, IMechConnector, IMechMachine> implements IMechNetwork
{ {
private long energyBuffer; private int force = 0;
private int speed = 0;
private int resistance = 0;
private HashMap<IMechMachine, ForceWrapper[]> forceMap = new HashMap<IMechMachine, ForceWrapper[]>();
@Override @Override
public void update() public void update()
@ -16,6 +30,74 @@ public class MechNetwork extends Network<IMechNetwork, IMechConnector, IMechMach
} }
@Override
public void reconstruct()
{
if (this.getConnectors().size() > 0)
{
// Reset all values related to wires
this.getNodes().clear();
this.forceMap.clear();
this.resistance = 0;
this.force = 0;
this.speed = 0;
// Iterate threw list of wires
Iterator<IMechConnector> it = this.getConnectors().iterator();
while (it.hasNext())
{
IMechConnector conductor = it.next();
if (conductor != null)
{
this.reconstructConductor(conductor);
}
else
{
it.remove();
}
}
if (this.getNodes().size() > 0)
{
NetworkTickHandler.addNetwork(this);
}
}
}
/** Segmented out call so overriding can be done when conductors are reconstructed. */
protected void reconstructConductor(IMechConnector conductor)
{
conductor.setNetwork(this);
for (int i = 0; i < conductor.getConnections().length; i++)
{
reconstructHandler(conductor.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite());
}
this.resistance += conductor.getResistance();
}
/** Segmented out call so overriding can be done when machines are reconstructed. */
protected void reconstructHandler(Object obj, ForgeDirection side)
{
if (obj != null && !(obj instanceof IMechConnector))
{
if (obj instanceof IMechMachine)
{
ForceWrapper[] set = this.forceMap.get((IMechMachine)obj);
if (set == null)
{
set = new ForceWrapper[6];
}
this.getNodes().add((IMechMachine) obj);
set[side.ordinal()] = new ForceWrapper(((IMechMachine) obj).getForceSide(side.getOpposite()),((IMechMachine) obj).getForceSide(side.getOpposite()));
this.forceMap.put((IMechMachine) obj, set);
}
}
}
@Override @Override
public boolean canUpdate() public boolean canUpdate()
{ {
@ -28,49 +110,129 @@ public class MechNetwork extends Network<IMechNetwork, IMechConnector, IMechMach
return true; return true;
} }
public void addTorque(long energy) @Override
public IMechNetwork merge(IMechNetwork network)
{ {
this.energyBuffer += energy; if (network.getClass().isAssignableFrom(this.getClass()) && network != this)
{
MechNetwork newNetwork = new MechNetwork();
newNetwork.getConnectors().addAll(this.getConnectors());
newNetwork.getConnectors().addAll(network.getConnectors());
network.getConnectors().clear();
network.getNodes().clear();
this.getConnectors().clear();
this.getNodes().clear();
newNetwork.reconstruct();
return newNetwork;
}
return null;
} }
@Override @Override
public void split(IMechConnector connection) public void split(IMechConnector splitPoint)
{ {
this.removeConnector(splitPoint);
this.reconstruct();
/** Loop through the connected blocks and attempt to see if there are connections between the
* two points elsewhere. */
Object[] connectedBlocks = splitPoint.getConnections();
for (int i = 0; i < connectedBlocks.length; i++)
{
Object connectedBlockA = connectedBlocks[i];
if (connectedBlockA instanceof IMechConnector)
{
for (int ii = 0; ii < connectedBlocks.length; ii++)
{
final Object connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechConnector)
{
ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint);
finder.findNodes((IConnector) connectedBlockA);
if (finder.results.size() <= 0)
{
try
{
/** The connections A and B are not connected anymore. Give them both
* a new common network. */
IMechNetwork newNetwork = new MechNetwork();
for (IConnector node : finder.closedSet)
{
if (node != splitPoint && node instanceof IMechConnector)
{
newNetwork.addConnector((IMechConnector) node);
}
}
newNetwork.reconstruct();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
} }
@Override @Override
public void split(IMechConnector connectorA, IMechConnector connectorB) public void split(IMechConnector connectorA, IMechConnector connectorB)
{ {
this.reconstruct();
/** Check if connectorA connects with connectorB. */
ConnectionPathfinder finder = new ConnectionPathfinder(connectorB);
finder.findNodes(connectorA);
if (finder.results.size() <= 0)
{
/** The connections A and B are not connected anymore. Give them both a new common
* network. */
IMechNetwork newNetwork = new MechNetwork();
for (IConnector node : finder.closedSet)
{
if (node instanceof IMechConnector)
{
newNetwork.addConnector((IMechConnector) node);
}
} }
@Override newNetwork.reconstruct();
public IMechNetwork merge(IMechNetwork network)
{
// TODO Auto-generated method stub
return null;
} }
@Override
public int getForce()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public int getRotSpeed()
{
// TODO Auto-generated method stub
return 0;
} }
@Override @Override
public int getTorque() public int getTorque()
{ {
// TODO Auto-generated method stub return this.force;
return 0; }
@Override
public int getRotationPerTick()
{
return this.speed;
}
public static class ForceWrapper
{
public int force = 0;
public int speed = 0;
public ForceWrapper(int force, int speed)
{
this.force = force;
this.speed = speed;
}
} }
} }