Conveyor belts now work as part of mechanical network

This commit is contained in:
Calclavia 2014-01-18 15:08:12 +08:00
parent 8cab946411
commit 1b01df9e72
13 changed files with 578 additions and 479 deletions

View file

@ -3,19 +3,26 @@ 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; import resonantinduction.mechanical.network.IMechanicalConnector;
/** An interface applied to the tile entity of a conveyor belt /**
* @Author DarkGuardsman */ * An interface applied to the tile entity of a conveyor belt
public interface IBelt extends IConnector<IBeltNetwork> *
* @Author DarkGuardsman
*/
public interface IBelt extends IMechanicalConnector
{ {
/** 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 */ *
public List<Entity> getAffectedEntities(); * @return list of entities in the belts are of effect
*/
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 */ *
public void ignoreEntity(Entity entity); * @param entity
*/
public void ignoreEntity(Entity entity);
} }

View file

@ -1,15 +0,0 @@
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

@ -2,8 +2,8 @@ package resonantinduction.mechanical;
import resonantinduction.mechanical.gear.PartGear; import resonantinduction.mechanical.gear.PartGear;
import codechicken.multipart.MultiPartRegistry; import codechicken.multipart.MultiPartRegistry;
import codechicken.multipart.MultipartGenerator;
import codechicken.multipart.MultiPartRegistry.IPartFactory; import codechicken.multipart.MultiPartRegistry.IPartFactory;
import codechicken.multipart.MultipartGenerator;
import codechicken.multipart.TMultiPart; import codechicken.multipart.TMultiPart;
public class MultipartMechanical implements IPartFactory public class MultipartMechanical implements IPartFactory
@ -15,7 +15,8 @@ public class MultipartMechanical implements IPartFactory
public MultipartMechanical() public MultipartMechanical()
{ {
MultiPartRegistry.registerParts(this, PART_TYPES); MultiPartRegistry.registerParts(this, PART_TYPES);
MultipartGenerator.registerTrait("resonantinduction.mechanical.network.IMechanical", "resonantinduction.mechanical.gear.TraitMechanical"); MultipartGenerator.registerTrait("resonantinduction.mechanical.network.IMechanical", "resonantinduction.mechanical.trait.TraitMechanical");
MultipartGenerator.registerTrait("resonantinduction.mechanical.network.IMechanicalConnector", "resonantinduction.mechanical.trait.TraitMechanicalConnector");
} }
@Override @Override

View file

@ -1,160 +0,0 @@
package resonantinduction.mechanical.belt;
import net.minecraft.tileentity.TileEntity;
import resonantinduction.api.IBelt;
import resonantinduction.api.IBeltNetwork;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import resonantinduction.mechanical.network.MechanicalNetwork;
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. */
IMechanicalNetwork newNetwork = new MechanicalNetwork();
for (IConnector node : finder.closedSet)
{
//TODO: Fix this
/* if (node instanceof IMechanicalConnector)
{
newNetwork.addConnector((IMechanicalConnector) 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

@ -3,7 +3,6 @@ package resonantinduction.mechanical.belt;
import java.util.List; import java.util.List;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@ -33,6 +32,43 @@ public class BlockConveyorBelt extends BlockRI
this.setBlockBounds(0, 0, 0, 1, 0.3f, 1); this.setBlockBounds(0, 0, 0, 1, 0.3f, 1);
} }
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
TileEntity t = world.getBlockTileEntity(x, y, z);
if (t != null && t instanceof TileConveyorBelt)
{
TileConveyorBelt tileEntity = (TileConveyorBelt) t;
System.out.println(world.isRemote + " : " + tileEntity.getNetwork());
}
return false;
}
@Override
public void onBlockAdded(World world, int x, int y, int z)
{
TileEntity t = world.getBlockTileEntity(x, y, z);
if (t != null && t instanceof TileConveyorBelt)
{
TileConveyorBelt tileEntity = (TileConveyorBelt) t;
tileEntity.refresh();
}
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int par5)
{
TileEntity t = world.getBlockTileEntity(x, y, z);
if (t != null && t instanceof TileConveyorBelt)
{
TileConveyorBelt tileEntity = (TileConveyorBelt) t;
tileEntity.refresh();
}
}
@Override @Override
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z)
{ {
@ -80,21 +116,20 @@ public class BlockConveyorBelt extends BlockRI
@Override @Override
public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
{ {
TileEntity t = world.getBlockTileEntity(x, y, z); TileEntity t = world.getBlockTileEntity(x, y, z);
if (t != null && t instanceof TileConveyorBelt) if (t != null && t instanceof TileConveyorBelt)
{ {
TileConveyorBelt tileEntity = (TileConveyorBelt) t; TileConveyorBelt tile = (TileConveyorBelt) t;
if (tileEntity.getSlant() == SlantType.UP || tileEntity.getSlant() == SlantType.DOWN) if (tile.getSlant() == SlantType.UP || tile.getSlant() == SlantType.DOWN)
{ {
AxisAlignedBB boundBottom = AxisAlignedBB.getAABBPool().getAABB(x, y, z, x + 1, y + 0.3, z + 1); AxisAlignedBB boundBottom = AxisAlignedBB.getAABBPool().getAABB(x, y, z, x + 1, y + 0.3, z + 1);
AxisAlignedBB boundTop = null; AxisAlignedBB boundTop = null;
ForgeDirection direction = tileEntity.getDirection(); ForgeDirection direction = tile.getDirection();
if (tileEntity.getSlant() == SlantType.UP) if (tile.getSlant() == SlantType.UP)
{ {
if (direction.offsetX > 0) if (direction.offsetX > 0)
{ {
@ -113,7 +148,7 @@ public class BlockConveyorBelt extends BlockRI
boundTop = AxisAlignedBB.getAABBPool().getAABB(x, y, z, x + 1, y + 0.8, z + (float) direction.offsetZ / -2); boundTop = AxisAlignedBB.getAABBPool().getAABB(x, y, z, x + 1, y + 0.8, z + (float) direction.offsetZ / -2);
} }
} }
else if (tileEntity.getSlant() == SlantType.DOWN) else if (tile.getSlant() == SlantType.DOWN)
{ {
if (direction.offsetX > 0) if (direction.offsetX > 0)
{ {
@ -145,7 +180,7 @@ public class BlockConveyorBelt extends BlockRI
return; return;
} }
if (tileEntity.getSlant() == SlantType.TOP) if (tile.getSlant() == SlantType.TOP)
{ {
AxisAlignedBB newBounds = AxisAlignedBB.getAABBPool().getAABB(x, y + 0.68, z, x + 1, y + 0.98, z + 1); AxisAlignedBB newBounds = AxisAlignedBB.getAABBPool().getAABB(x, y + 0.68, z, x + 1, y + 0.98, z + 1);
@ -237,7 +272,7 @@ public class BlockConveyorBelt extends BlockRI
return true; return true;
} }
/** Moves the entity if the conductor is powered. */ /** Moves the entity if the belt is powered. */
@Override @Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
{ {
@ -246,83 +281,80 @@ public class BlockConveyorBelt extends BlockRI
if (tileEntity instanceof TileConveyorBelt) if (tileEntity instanceof TileConveyorBelt)
{ {
TileConveyorBelt tile = (TileConveyorBelt) tileEntity; TileConveyorBelt tile = (TileConveyorBelt) tileEntity;
if (tile.IgnoreList.contains(entity))
if (tile.ignoreList.contains(entity))
{ {
return; return;
} }
if (!world.isBlockIndirectlyGettingPowered(x, y, z)) if (!world.isBlockIndirectlyGettingPowered(x, y, z))
{ {
float acceleration = tile.acceleration; float maxSpeed = tile.getMoveVelocity() / 20;
float maxSpeed = tile.maxSpeed;
SlantType slantType = tile.getSlant(); if (maxSpeed > 0)
ForgeDirection direction = tile.getDirection(); {
SlantType slantType = tile.getSlant();
ForgeDirection direction = tile.getDirection();
if (entity instanceof EntityLiving) if (slantType == SlantType.UP)
{
acceleration *= 5;
maxSpeed *= 10;
}
if (slantType == SlantType.UP)
{
if (entity.motionY < 0.2)
{ {
entity.addVelocity(0, 0.2, 0); if (entity.motionY < 0.2)
{
entity.addVelocity(0, 0.2, 0);
}
} }
} else if (slantType == SlantType.DOWN)
else if (slantType == SlantType.DOWN)
{
if (entity.motionY > -0.1)
{ {
entity.addVelocity(0, -0.1, 0); if (entity.motionY > -0.1)
{
entity.addVelocity(0, -0.1, 0);
}
} }
}
// Move the entity based on the conveyor belt's direction.
entity.addVelocity(direction.offsetX * acceleration, 0, direction.offsetZ * acceleration);
if (direction.offsetX != 0 && Math.abs(entity.motionX) > maxSpeed)
{
entity.motionX = direction.offsetX * maxSpeed;
entity.motionZ = 0;
}
if (direction.offsetZ != 0 && Math.abs(entity.motionZ) > maxSpeed)
{
entity.motionZ = direction.offsetZ * maxSpeed;
entity.motionX = 0;
}
entity.motionY += 0.0125f;
if (entity instanceof EntityItem)
{
if (direction.offsetX != 0) if (direction.offsetX != 0)
{ {
double difference = (z + 0.5) - entity.posZ; entity.motionX = direction.offsetX * maxSpeed;
entity.motionZ += difference * 0.1; entity.motionZ = 0;
// entity.posZ = z + 0.5;
} }
else if (direction.offsetZ != 0)
if (direction.offsetZ != 0)
{ {
double difference = (x + 0.5) - entity.posX; entity.motionZ = direction.offsetZ * maxSpeed;
entity.motionX += difference * 0.1; entity.motionX = 0;
// /entity.posX = x + 0.5;
} }
((EntityItem) entity).age++; entity.motionY += 0.0125f;
boolean foundSneaking = false; if (entity instanceof EntityItem)
for (EntityPlayer player : (List<EntityPlayer>) world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1)))
{ {
if (player.isSneaking()) if (direction.offsetX != 0)
foundSneaking = true; {
} double difference = (z + 0.5) - entity.posZ;
entity.motionZ += difference * 0.1;
// entity.posZ = z + 0.5;
}
else if (direction.offsetZ != 0)
{
double difference = (x + 0.5) - entity.posX;
entity.motionX += difference * 0.1;
// /entity.posX = x + 0.5;
}
if (foundSneaking) ((EntityItem) entity).age++;
((EntityItem) entity).delayBeforeCanPickup = 0;
else boolean foundSneaking = false;
((EntityItem) entity).delayBeforeCanPickup = 20; for (EntityPlayer player : (List<EntityPlayer>) world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1)))
entity.onGround = false; {
if (player.isSneaking())
foundSneaking = true;
}
if (foundSneaking)
((EntityItem) entity).delayBeforeCanPickup = 0;
else
((EntityItem) entity).delayBeforeCanPickup = 20;
entity.onGround = false;
}
} }
} }
} }

View file

@ -102,7 +102,7 @@ public class RenderConveyorBelt extends TileEntitySpecialRenderer implements ICu
bindTexture(name); bindTexture(name);
GL11.glRotatef(180, 0f, 1f, 0f); GL11.glRotatef(180, 0f, 1f, 0f);
GL11.glTranslatef(0f, -0.68f, 0f); GL11.glTranslatef(0f, -0.68f, 0f);
MODEL.render(0.0625f, (float) Math.toRadians(tileEntity.wheelRotation), false, false, false, false); MODEL.render(0.0625f, (float) Math.toRadians(tileEntity.getNetwork().getRotation()), false, false, false, false);
} }
} }
else else
@ -124,7 +124,7 @@ public class RenderConveyorBelt extends TileEntitySpecialRenderer implements ICu
} }
ResourceLocation name = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "belt/frame" + frame + ".png"); ResourceLocation name = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "belt/frame" + frame + ".png");
bindTexture(name); bindTexture(name);
MODEL.render(0.0625F, (float) Math.toRadians(tileEntity.wheelRotation), false, false, false, true); MODEL.render(0.0625F, (float) Math.toRadians(tileEntity.getNetwork().getRotation()), false, false, false, true);
} }

View file

@ -12,9 +12,12 @@ 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.mechanical.Mechanical; import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import resonantinduction.mechanical.network.MechanicalNetwork;
import universalelectricity.api.vector.Vector3; import universalelectricity.api.vector.Vector3;
import calclavia.lib.network.IPacketReceiverWithID; import calclavia.lib.network.IPacketReceiverWithID;
import calclavia.lib.prefab.tile.IRotatable; import calclavia.lib.prefab.tile.IRotatable;
@ -22,235 +25,293 @@ import calclavia.lib.prefab.tile.TileAdvanced;
import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataInput;
/** Conveyer belt TileEntity that allows entities of all kinds to be moved import cpw.mods.fml.common.network.PacketDispatcher;
/**
* 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 TileAdvanced implements IMechanicalConnector, IBelt, IRotatable, IPacketReceiverWithID
{ {
public enum SlantType
{
NONE, UP, DOWN, TOP
}
public enum SlantType /**
{ * Static constants.
NONE, */
UP, public static final int MAX_FRAME = 13;
DOWN, public static final int MAX_SLANT_FRAME = 23;
TOP public static final int PACKET_SLANT = Mechanical.contentRegistry.getNextPacketID();
} public static final int PACKET_REFRESH = Mechanical.contentRegistry.getNextPacketID();
/** Acceleration of entities on the belt */
public static final float ACCELERATION = 0.01f;
public static final int MAX_FRAME = 13; private IMechanicalNetwork network;
public static final int MAX_SLANT_FRAME = 23;
/** Packet name to ID the packet containing info on the angle of the belt */
public static final String slantPacketID = "slantPacket";
/** Acceleration of entities on the belt */
public final float acceleration = 0.01f;
/** max speed of entities on the belt */
public final float maxSpeed = 0.1f;
/** Current rotation of the model wheels */
public float wheelRotation = 0;
/** Frame count for texture animation from 0 - maxFrame */
private int animFrame = 0;
private SlantType slantType = SlantType.NONE;
/** Entities that are ignored allowing for other tiles to interact with them */
public List<Entity> IgnoreList = new ArrayList<Entity>();
private boolean functioning;
@Override /** The mechanical connections this connector has made */
public void updateEntity() protected Object[] connections = new Object[6];
{
super.updateEntity();
/* PROCESSES IGNORE LIST AND REMOVES UNNEED ENTRIES */
Iterator<Entity> it = this.IgnoreList.iterator();
while (it.hasNext())
{
if (!this.getAffectedEntities().contains(it.next()))
{
it.remove();
}
}
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)
{
this.worldObj.playSound(this.xCoord, this.yCoord, this.zCoord, "mods.assemblyline.conveyor", 0.5f, 0.7f, true);
}
this.wheelRotation = (40 + this.wheelRotation) % 360;
float wheelRotPct = wheelRotation / 360f; /** Frame count for texture animation from 0 - maxFrame */
private int animationFrame = 0;
// Sync the animation. Slant belts are slower. private SlantType slantType = SlantType.NONE;
if (this.getSlant() == SlantType.NONE || this.getSlant() == SlantType.TOP)
{
this.animFrame = (int) (wheelRotPct * MAX_FRAME);
if (this.animFrame < 0)
this.animFrame = 0;
if (this.animFrame > MAX_FRAME)
this.animFrame = MAX_FRAME;
}
else
{
this.animFrame = (int) (wheelRotPct * MAX_SLANT_FRAME);
if (this.animFrame < 0)
this.animFrame = 0;
if (this.animFrame > MAX_SLANT_FRAME)
this.animFrame = MAX_SLANT_FRAME;
}
}
} /** Entities that are ignored allowing for other tiles to interact with them */
public List<Entity> ignoreList = new ArrayList<Entity>();
@Override private boolean markRefresh = true;
public Packet getDescriptionPacket()
{
if (this.slantType != SlantType.NONE)
{
return ResonantInduction.PACKET_TILE.getPacket(this, slantPacketID, true, this.slantType.ordinal());
}
return super.getDescriptionPacket();
}
@Override @Override
public boolean onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra) public void updateEntity()
{ {
if (this.worldObj.isRemote) super.updateEntity();
{
try
{
if (id == 0)
{
this.functioning = data.readBoolean();
this.slantType = SlantType.values()[data.readInt()];
return true;
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return false;
}
public SlantType getSlant() /* PROCESSES IGNORE LIST AND REMOVES UNNEED ENTRIES */
{ Iterator<Entity> it = this.ignoreList.iterator();
return slantType; while (it.hasNext())
} {
if (!this.getAffectedEntities().contains(it.next()))
{
it.remove();
}
}
public void setSlant(SlantType slantType) if (this.worldObj.isRemote)
{ {
if (slantType == null) 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)
{ {
slantType = SlantType.NONE; this.worldObj.playSound(this.xCoord, this.yCoord, this.zCoord, "mods.assemblyline.conveyor", 0.5f, 0.7f, true);
} }
this.slantType = slantType;
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override double wheelRotPct = getNetwork().getRotation() / Math.PI;
public void setDirection(ForgeDirection facingDirection)
{
this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, facingDirection.ordinal(), 3);
}
@Override // Sync the animation. Slant belts are slower.
public ForgeDirection getDirection() if (this.getSlant() == SlantType.NONE || this.getSlant() == SlantType.TOP)
{ {
return ForgeDirection.getOrientation(this.getBlockMetadata()); this.animationFrame = (int) (wheelRotPct * MAX_FRAME);
} if (this.animationFrame < 0)
this.animationFrame = 0;
if (this.animationFrame > MAX_FRAME)
this.animationFrame = MAX_FRAME;
}
else
{
this.animationFrame = (int) (wheelRotPct * MAX_SLANT_FRAME);
if (this.animationFrame < 0)
this.animationFrame = 0;
if (this.animationFrame > MAX_SLANT_FRAME)
this.animationFrame = MAX_SLANT_FRAME;
}
}
else
{
if (markRefresh)
{
sendRefreshPacket();
}
}
@Override }
public List<Entity> getAffectedEntities()
{
return worldObj.getEntitiesWithinAABB(Entity.class, AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord, this.zCoord, this.xCoord + 1, this.yCoord + 1, this.zCoord + 1));
}
public int getAnimationFrame() @Override
{ public Packet getDescriptionPacket()
return this.animFrame; {
} if (this.slantType != SlantType.NONE)
{
return ResonantInduction.PACKET_TILE.getPacket(this, PACKET_SLANT, this.slantType.ordinal());
}
return super.getDescriptionPacket();
}
/** NBT Data */ public void sendRefreshPacket()
@Override {
public void readFromNBT(NBTTagCompound nbt) PacketDispatcher.sendPacketToAllPlayers(ResonantInduction.PACKET_TILE.getPacket(this, PACKET_REFRESH));
{ }
super.readFromNBT(nbt);
this.slantType = SlantType.values()[nbt.getByte("slant")];
}
/** Writes a tile entity to NBT. */ @Override
@Override public boolean onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra)
public void writeToNBT(NBTTagCompound nbt) {
{ if (this.worldObj.isRemote)
super.writeToNBT(nbt); {
nbt.setByte("slant", (byte) this.slantType.ordinal()); try
} {
if (id == PACKET_SLANT)
{
this.slantType = SlantType.values()[data.readInt()];
return true;
}
else if (id == PACKET_REFRESH)
{
refresh();
return true;
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return false;
}
@Override public SlantType getSlant()
public void ignoreEntity(Entity entity) {
{ return slantType;
if (!this.IgnoreList.contains(entity)) }
{
this.IgnoreList.add(entity);
}
}
@Override public void setSlant(SlantType slantType)
public boolean canConnect(ForgeDirection direction) {
{ if (slantType == null)
return direction == ForgeDirection.DOWN; {
} slantType = SlantType.NONE;
}
this.slantType = slantType;
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
public void refresh() @Override
{ public void setDirection(ForgeDirection facingDirection)
if (this.worldObj != null && !this.worldObj.isRemote) {
{ this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, facingDirection.ordinal(), 3);
Vector3 face = new Vector3(this).modifyPositionFromSide(this.getDirection()); }
Vector3 back = new Vector3(this).modifyPositionFromSide(this.getDirection().getOpposite());
TileEntity front, rear;
if (this.slantType == SlantType.DOWN)
{
face.translate(new Vector3(0, -1, 0));
back.translate(new Vector3(0, 1, 0));
}
else if (this.slantType == SlantType.UP)
{
face.translate(new Vector3(0, 1, 0));
back.translate(new Vector3(0, -1, 0));
}
else
{
return;
}
front = face.getTileEntity(this.worldObj);
rear = back.getTileEntity(this.worldObj);
if (front instanceof IBelt)
{
this.getNetwork().merge(((IBelt) front).getNetwork());
}
if (rear instanceof IBelt)
{
this.getNetwork().merge(((IBelt) rear).getNetwork());
}
} @Override
} public ForgeDirection getDirection()
{
return ForgeDirection.getOrientation(this.getBlockMetadata());
}
@Override @Override
public Object[] getConnections() public List<Entity> getAffectedEntities()
{ {
// TODO Auto-generated method stub return worldObj.getEntitiesWithinAABB(Entity.class, AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord, this.zCoord, this.xCoord + 1, this.yCoord + 1, this.zCoord + 1));
return null; }
}
@Override public int getAnimationFrame()
public IBeltNetwork getNetwork() {
{ return this.animationFrame;
// TODO Auto-generated method stub }
return null;
}
@Override /** NBT Data */
public void setNetwork(IBeltNetwork network) @Override
{ public void readFromNBT(NBTTagCompound nbt)
// TODO Auto-generated method stub {
super.readFromNBT(nbt);
this.slantType = SlantType.values()[nbt.getByte("slant")];
}
/** Writes a tile entity to NBT. */
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setByte("slant", (byte) this.slantType.ordinal());
}
@Override
public void ignoreEntity(Entity entity)
{
if (!this.ignoreList.contains(entity))
{
this.ignoreList.add(entity);
}
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return direction == ForgeDirection.DOWN;
}
public void refresh()
{
boolean didRefresh = false;
for (int i = 2; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
Vector3 pos = new Vector3(this).modifyPositionFromSide(dir);
TileEntity tile = pos.getTileEntity(this.worldObj);
if (dir == this.getDirection() || dir == this.getDirection().getOpposite())
{
if (tile instanceof IBelt)
{
connections[dir.ordinal()] = tile;
this.getNetwork().merge(((IBelt) tile).getNetwork());
didRefresh = true;
}
}
else if (tile instanceof IMechanical)
{
// TODO: Fix split connection in network.
// connections[dir.ordinal()] = tile;
}
}
if (didRefresh)
{
if (!worldObj.isRemote)
{
markRefresh = true;
}
}
}
@Override
public void invalidate()
{
this.getNetwork().split(this);
super.invalidate();
}
public float getMoveVelocity()
{
return Math.max(this.getNetwork().getAngularVelocity(), this.getNetwork().getPrevAngularVelocity());
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
return this.getNetwork().onReceiveEnergy(torque, angularVelocity);
}
@Override
public Object[] getConnections()
{
return connections;
}
@Override
public IMechanicalNetwork getNetwork()
{
if (this.network == null)
{
this.network = new MechanicalNetwork();
this.network.addConnector(this);
}
return this.network;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
this.network = network;
}
@Override
public boolean sendNetworkPacket(long torque, float angularVelocity)
{
return false;
}
@Override
public float getResistance()
{
return 0.5f;
}
}
} }

View file

@ -36,7 +36,7 @@ import cpw.mods.fml.relauncher.SideOnly;
* @author Calclavia * @author Calclavia
* *
*/ */
public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanical, IMechanicalConnector public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanicalConnector
{ {
public static Cuboid6[][] oBoxes = new Cuboid6[6][2]; public static Cuboid6[][] oBoxes = new Cuboid6[6][2];
@ -54,6 +54,9 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
private IMechanicalNetwork network; private IMechanicalNetwork network;
/** The mechanical connections this connector has made */
protected Object[] connections = new Object[6];
/** Side of the block this is placed on */ /** Side of the block this is placed on */
public ForgeDirection placementSide; public ForgeDirection placementSide;
@ -68,9 +71,6 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
/** When true, it will start marking nearby gears for update */ /** When true, it will start marking nearby gears for update */
public boolean markRotationUpdate = true; public boolean markRotationUpdate = true;
/** The mechanical connections this gear has made */
protected Object[] connections = new Object[6];
private int manualCrankTime = 0; private int manualCrankTime = 0;
public void preparePlacement(int side, int itemDamage) public void preparePlacement(int side, int itemDamage)
@ -226,6 +226,10 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
else if (tile instanceof IMechanical) else if (tile instanceof IMechanical)
{ {
connections[this.placementSide.getOpposite().ordinal()] = tile; connections[this.placementSide.getOpposite().ordinal()] = tile;
if (tile instanceof IMechanicalConnector)
{
getNetwork().merge(((IMechanicalConnector) tile).getNetwork());
}
} }
/** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */ /** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */
@ -262,6 +266,11 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
} }
getNetwork().reconstruct(); getNetwork().reconstruct();
if (!world().isRemote)
{
sendRefreshPacket();
}
} }
@Override @Override
@ -290,7 +299,7 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
@Override @Override
public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item) public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item)
{ {
System.out.println(world().isRemote + " : " + this.getNetwork().getAngularVelocity()); System.out.println(world().isRemote + ": " + getNetwork());
if (player.isSneaking()) if (player.isSneaking())
{ {
this.manualCrankTime = 20; this.manualCrankTime = 20;
@ -303,7 +312,7 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
{ {
if (!world().isRemote && doReceive) if (!world().isRemote && doReceive)
{ {
getNetwork().applyEnergy(torque, angularVelocity); getNetwork().onReceiveEnergy(torque, angularVelocity);
markRotationUpdate = true; markRotationUpdate = true;
} }
@ -336,12 +345,22 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
} }
@Override @Override
public void sendNetworkPacket(long torque, float angularVelocity) public boolean sendNetworkPacket(long torque, float angularVelocity)
{ {
if (tile() != null) if (tile() != null)
{ {
tile().getWriteStream(this).writeByte(0).writeLong(torque).writeFloat(angularVelocity).writeBoolean(isClockwise); tile().getWriteStream(this).writeByte(0).writeLong(torque).writeFloat(angularVelocity).writeBoolean(isClockwise);
} }
return true;
}
public void sendRefreshPacket()
{
if (tile() != null)
{
tile().getWriteStream(this).writeByte(1);
}
} }
public void read(MCDataInput packet, int packetID) public void read(MCDataInput packet, int packetID)
@ -352,6 +371,10 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
isClockwise = packet.readBoolean(); isClockwise = packet.readBoolean();
markRotationUpdate = true; markRotationUpdate = true;
} }
else if (packetID == 1)
{
this.refresh();
}
} }
@Override @Override

View file

@ -12,8 +12,10 @@ public interface IMechanicalConnector extends IMechanical, IConnector<IMechanica
{ {
/** /**
* Uses this connector to send a packet to the client. * Uses this connector to send a packet to the client.
*
* @return True if the packet was successfully sent.
*/ */
public void sendNetworkPacket(long torque, float angularVelocity); public boolean sendNetworkPacket(long torque, float angularVelocity);
/** /**
* The percentage of resistance caused by this connector. * The percentage of resistance caused by this connector.

View file

@ -16,6 +16,8 @@ public interface IMechanicalNetwork extends INetwork<IMechanicalNetwork, IMechan
*/ */
public long getPower(); public long getPower();
public void setPower(long torque, float angularVelocity);
/** Torque applied by the network at the given speed */ /** Torque applied by the network at the given speed */
public long getTorque(); public long getTorque();
@ -33,7 +35,10 @@ public interface IMechanicalNetwork extends INetwork<IMechanicalNetwork, IMechan
/** Called to rebuild the network */ /** Called to rebuild the network */
public void reconstruct(); public void reconstruct();
public void applyEnergy(long torque, float angularVelocity); public long onReceiveEnergy(long torque, float angularVelocity);
public void setPower(long readLong, float readFloat); /**
* @return The current rotation value of the network.
*/
public float getRotation();
} }

View file

@ -38,6 +38,10 @@ public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanicalCo
/** The cached resistance caused by all connectors */ /** The cached resistance caused by all connectors */
private float connectorResistance = 0; private float connectorResistance = 0;
/** The current rotation of the network */
private float rotation = 0;
private long lastRotateTime;
/** The direction in which a conductor is placed relative to a specific conductor. */ /** The direction in which a conductor is placed relative to a specific conductor. */
protected final HashMap<Object, EnumSet<ForgeDirection>> handlerDirectionMap = new LinkedHashMap<Object, EnumSet<ForgeDirection>>(); protected final HashMap<Object, EnumSet<ForgeDirection>> handlerDirectionMap = new LinkedHashMap<Object, EnumSet<ForgeDirection>>();
@ -79,8 +83,10 @@ public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanicalCo
*/ */
for (IMechanicalConnector connector : this.getConnectors()) for (IMechanicalConnector connector : this.getConnectors())
{ {
connector.sendNetworkPacket(torque, angularVelocity); if (connector.sendNetworkPacket(torque, angularVelocity))
break; {
break;
}
} }
} }
@ -109,11 +115,12 @@ public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanicalCo
* Note: Server side only. * Note: Server side only.
*/ */
@Override @Override
public void applyEnergy(long torque, float angularVelocity) public long onReceiveEnergy(long torque, float angularVelocity)
{ {
this.torque += Math.abs(torque); this.torque += torque;
this.angularVelocity += Math.abs(angularVelocity); this.angularVelocity += angularVelocity;
NetworkTickHandler.addNetwork(this); NetworkTickHandler.addNetwork(this);
return (long) (torque * angularVelocity);
} }
@Override @Override
@ -337,4 +344,24 @@ public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanicalCo
} }
} }
@Override
public float getRotation()
{
long deltaTime = System.currentTimeMillis() - lastRotateTime;
if (deltaTime > 1)
{
rotation = (float) (((angularVelocity) * ((float) deltaTime / 1000f) + rotation) % Math.PI);
lastRotateTime = System.currentTimeMillis();
}
return rotation;
}
@Override
public String toString()
{
return this.getClass().getSimpleName() + "[" + this.hashCode() + ", Handlers: " + getNodes().size() + ", Connectors: " + getConnectors().size() + ", Power:" + getPower() + "]";
}
} }

View file

@ -1,10 +1,10 @@
package resonantinduction.mechanical.gear; package resonantinduction.mechanical.trait;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechanical; import resonantinduction.mechanical.network.IMechanical;
import net.minecraftforge.common.ForgeDirection;
import codechicken.multipart.TMultiPart; import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart; import codechicken.multipart.TileMultipart;

View file

@ -0,0 +1,116 @@
package resonantinduction.mechanical.trait;
import java.util.HashSet;
import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart;
public class TraitMechanicalConnector extends TileMultipart implements IMechanicalConnector
{
public Set<IMechanicalConnector> mechanicalConnectorInterfaces = new HashSet<IMechanicalConnector>();
@Override
public void copyFrom(TileMultipart that)
{
super.copyFrom(that);
if (that instanceof TraitMechanicalConnector)
{
this.mechanicalConnectorInterfaces = ((TraitMechanicalConnector) that).mechanicalConnectorInterfaces;
}
}
@Override
public void bindPart(TMultiPart part)
{
super.bindPart(part);
if (part instanceof IMechanicalConnector)
{
this.mechanicalConnectorInterfaces.add((IMechanicalConnector) part);
}
}
@Override
public void partRemoved(TMultiPart part, int p)
{
super.partRemoved(part, p);
if (part instanceof IMechanicalConnector)
{
this.mechanicalConnectorInterfaces.remove(part);
}
}
@Override
public void clearParts()
{
super.clearParts();
this.mechanicalConnectorInterfaces.clear();
}
@Override
public boolean canConnect(ForgeDirection direction)
{
for (IMechanicalConnector connector : this.mechanicalConnectorInterfaces)
{
if (connector.canConnect(direction.getOpposite()))
{
return true;
}
}
return false;
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
TMultiPart part = this.partMap(from.ordinal());
if (part != null)
{
if (this.mechanicalConnectorInterfaces.contains(part))
{
return ((IMechanicalConnector) part).onReceiveEnergy(from, torque, angularVelocity, doReceive);
}
}
return 0;
}
@Override
public Object[] getConnections()
{
return null;
}
@Override
public IMechanicalNetwork getNetwork()
{
return null;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
}
@Override
public boolean sendNetworkPacket(long torque, float angularVelocity)
{
return false;
}
@Override
public float getResistance()
{
return 0;
}
}