resonant-induction/archive/java/resonantinduction/old/transport/logistic/TileEntityManipulator.java
2014-01-11 17:44:07 +08:00

282 lines
7.5 KiB
Java

package resonantinduction.old.transport.logistic;
import java.util.List;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.core.prefab.tile.TileEntityFilterable;
import resonantinduction.old.api.IManipulator;
import resonantinduction.old.transport.imprinter.ItemImprinter;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.network.PacketHandler;
import calclavia.lib.prefab.tile.IRotatable;
import calclavia.lib.utility.InvInteractionHelper;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.Player;
public class TileEntityManipulator extends TileEntityFilterable implements IRotatable, IManipulator
{
/** True to auto output items with a redstone pulse */
private boolean selfPulse = false;
/** True if outputting items */
private boolean isOutput = false;
/** True if is currently powered by redstone */
private boolean isRedstonePowered = false;
/** The class that interacts with inventories for this machine */
private InvInteractionHelper invExtractionHelper;
public TileEntityManipulator()
{
super(10);
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote)
{
if (this.isFunctioning())
{
if (!this.isOutput)
{
this.enject();
}
else
{
this.isRedstonePowered = this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
if (this.isSelfPulse() && this.ticks % 10 == 0)
{
this.isRedstonePowered = true;
}
/** Finds the connected inventory and outputs the items upon a redstone pulse. */
if (this.isRedstonePowered)
{
this.inject();
}
}
}
}
}
/**
* Find items going into the manipulator and input them into an inventory behind this
* manipulator.
*/
@Override
public void enject()
{
Vector3 inputPosition = new Vector3(this);
/** output location up */
Vector3 outputUp = new Vector3(this);
outputUp.modifyPositionFromSide(ForgeDirection.UP);
/** output location down */
Vector3 outputDown = new Vector3(this);
outputDown.modifyPositionFromSide(ForgeDirection.DOWN);
/** output location facing */
Vector3 outputPosition = new Vector3(this);
outputPosition.modifyPositionFromSide(this.getDirection().getOpposite());
this.consumePower(1, true);
/** Prevents manipulators from spamming and duping items. */
if (outputPosition.getTileEntity(this.worldObj) instanceof TileEntityManipulator)
{
if (((TileEntityManipulator) outputPosition.getTileEntity(this.worldObj)).getDirection() == this.getDirection().getOpposite())
{
return;
}
}
AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(inputPosition.x, inputPosition.y, inputPosition.z, inputPosition.x + 1, inputPosition.y + 1, inputPosition.z + 1);
List<EntityItem> itemsInBound = this.worldObj.getEntitiesWithinAABB(EntityItem.class, bounds);
for (EntityItem entity : itemsInBound)
{
if (entity.isDead)
continue;
/**
* Try top first, then bottom, then the sides to see if it is possible to insert the
* item into a inventory.
*/
ItemStack remainingStack = entity.getEntityItem().copy();
if (this.getFilter() == null || this.isFiltering(remainingStack))
{
remainingStack = invHelper().tryPlaceInPosition(remainingStack, outputUp, ForgeDirection.UP);
if (remainingStack != null)
{
remainingStack = invHelper().tryPlaceInPosition(remainingStack, outputDown, ForgeDirection.DOWN);
}
if (remainingStack != null)
{
remainingStack = invHelper().tryPlaceInPosition(remainingStack, outputPosition, this.getDirection().getOpposite());
}
if (remainingStack != null && remainingStack.stackSize > 0)
{
invHelper().throwItem(outputPosition, remainingStack);
}
entity.setDead();
}
}
}
/** Inject items */
@Override
public void inject()
{
this.isRedstonePowered = false;
/** input location up */
Vector3 inputUp = new Vector3(this).modifyPositionFromSide(ForgeDirection.UP);
/** input location down */
Vector3 inputDown = new Vector3(this).modifyPositionFromSide(ForgeDirection.DOWN);
/** input location facing */
Vector3 inputPosition = new Vector3(this).modifyPositionFromSide(this.getDirection().getOpposite());
/** output location facing */
Vector3 outputPosition = new Vector3(this).modifyPositionFromSide(this.getDirection());
this.consumePower(1, true);
ItemStack itemStack = invHelper().tryGrabFromPosition(inputUp, ForgeDirection.UP, 1);
if (itemStack == null)
{
itemStack = invHelper().tryGrabFromPosition(inputDown, ForgeDirection.DOWN, 1);
}
if (itemStack == null)
{
itemStack = invHelper().tryGrabFromPosition(inputPosition, this.getDirection().getOpposite(), 1);
}
if (itemStack != null)
{
if (itemStack.stackSize > 0)
{
invHelper().throwItem(outputPosition, itemStack);
}
}
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.isOutput = nbt.getBoolean("isOutput");
this.setSelfPulse(nbt.getBoolean("selfpulse"));
}
/** Writes a tile entity to NBT. */
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("isOutput", this.isOutput);
nbt.setBoolean("selfpulse", this.isSelfPulse());
}
@Override
public Packet getDescriptionPacket()
{
return PacketHandler.instance().getTilePacket(this.getChannel(), "manipulator", this, this.functioning, this.isInverted(), this.isSelfPulse(), this.isOutput());
}
@Override
public boolean simplePacket(String id, ByteArrayDataInput dis, Player player)
{
try
{
if (this.worldObj.isRemote && !super.simplePacket(id, dis, player))
{
if (id.equalsIgnoreCase("manipulator"))
{
this.functioning = dis.readBoolean();
this.setInverted(dis.readBoolean());
this.setSelfPulse(dis.readBoolean());
this.setOutput(dis.readBoolean());
return true;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
@Override
public boolean canConnect(ForgeDirection dir)
{
return dir != this.getDirection();
}
public boolean isSelfPulse()
{
return selfPulse;
}
public void setSelfPulse(boolean selfPulse)
{
this.selfPulse = selfPulse;
}
/** Gets the class that managed extracting and placing items into inventories */
public InvInteractionHelper invHelper()
{
if (invExtractionHelper == null || invExtractionHelper.world != this.worldObj)
{
this.invExtractionHelper = new InvInteractionHelper(this.worldObj, new Vector3(this), this.getFilter() != null ? ItemImprinter.getFilters(getFilter()) : null, this.isInverted());
}
return invExtractionHelper;
}
@Override
public void setFilter(ItemStack filter)
{
super.setFilter(filter);
/* Reset inv Helper's filters */
this.invHelper().setFilter(this.getFilter() != null ? ItemImprinter.getFilters(this.getFilter()) : null, this.isInverted());
}
/** Is this manipulator set to output items */
public boolean isOutput()
{
return this.isOutput;
}
/** True to output items */
public void setOutput(boolean isOutput)
{
this.isOutput = isOutput;
if (!this.worldObj.isRemote)
{
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
/** Inverts the current output state */
public void toggleOutput()
{
this.setOutput(!this.isOutput());
}
@Override
public int getExtraLoad()
{
return 1;
}
}