assemblyline/src/main/java/assemblyline/common/machine/TileEntityManipulator.java
2022-10-26 19:42:44 +02:00

313 lines
14 KiB
Java

package assemblyline.common.machine;
import assemblyline.api.IManipulator;
import assemblyline.common.block.BlockCrate;
import assemblyline.common.block.TileEntityCrate;
import assemblyline.common.machine.imprinter.TileEntityFilterable;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import universalelectricity.core.vector.Vector3;
import universalelectricity.prefab.implement.IRedstoneReceptor;
import universalelectricity.prefab.implement.IRotatable;
import universalelectricity.prefab.multiblock.TileEntityMulti;
public class TileEntityManipulator
extends TileEntityFilterable
implements IRotatable,
IRedstoneReceptor,
IManipulator {
public boolean selfPulse = false;
private boolean isOutput = false;
private boolean isRedstonePowered = false;
public boolean isOutput() {
return this.isOutput;
}
public void setOutput(boolean isOutput) {
this.isOutput = isOutput;
if (!this.worldObj.isRemote) {
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
public void toggleOutput() {
this.setOutput(!this.isOutput());
}
@Override
protected void onUpdate() {
if (!this.worldObj.isRemote) {
if (this.ticks % 20L == 0L) {
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
if (!this.isDisabled() && this.isRunning()) {
if (!this.isOutput) {
this.inject();
} else {
if (this.selfPulse && this.ticks % 10L == 0L) {
this.isRedstonePowered = true;
}
if (this.isRedstonePowered) {
this.eject();
}
}
}
}
}
@Override
public void inject() {
Vector3 inputPosition = new Vector3(this);
Vector3 outputUp = new Vector3(this);
outputUp.modifyPositionFromSide(ForgeDirection.UP);
Vector3 outputDown = new Vector3(this);
outputDown.modifyPositionFromSide(ForgeDirection.DOWN);
Vector3 outputPosition = new Vector3(this);
outputPosition.modifyPositionFromSide(this.getDirection().getOpposite());
if (outputPosition.getTileEntity((IBlockAccess)this.worldObj) instanceof TileEntityManipulator && ((TileEntityManipulator)outputPosition.getTileEntity((IBlockAccess)this.worldObj)).getDirection() == this.getDirection().getOpposite()) {
return;
}
AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox((double)inputPosition.x, (double)inputPosition.y, (double)inputPosition.z, (double)(inputPosition.x + 1.0), (double)(inputPosition.y + 1.0), (double)(inputPosition.z + 1.0));
List<EntityItem> itemsInBound = this.worldObj.getEntitiesWithinAABB(EntityItem.class, bounds);
for (EntityItem entity : itemsInBound) {
if (entity.isDead) continue;
ItemStack remainingStack = entity.getEntityItem().copy();
if (this.getFilter() != null && !this.isFiltering(remainingStack)) continue;
if ((remainingStack = this.tryPlaceInPosition(remainingStack, outputUp, ForgeDirection.DOWN)) != null) {
remainingStack = this.tryPlaceInPosition(remainingStack, outputDown, ForgeDirection.UP);
}
if (remainingStack != null) {
remainingStack = this.tryPlaceInPosition(remainingStack, outputPosition, this.getDirection().getOpposite());
}
if (remainingStack != null && remainingStack.stackSize > 0) {
this.throwItem(outputPosition, remainingStack);
}
entity.setDead();
}
}
@Override
public void eject() {
this.onPowerOff();
Vector3 inputUp = new Vector3(this);
inputUp.modifyPositionFromSide(ForgeDirection.UP);
Vector3 inputDown = new Vector3(this);
inputDown.modifyPositionFromSide(ForgeDirection.DOWN);
Vector3 inputPosition = new Vector3(this);
inputPosition.modifyPositionFromSide(this.getDirection().getOpposite());
Vector3 outputPosition = new Vector3(this);
outputPosition.modifyPositionFromSide(this.getDirection());
ItemStack itemStack = this.tryGrabFromPosition(inputUp, ForgeDirection.DOWN);
if (itemStack == null) {
itemStack = this.tryGrabFromPosition(inputDown, ForgeDirection.UP);
}
if (itemStack == null) {
itemStack = this.tryGrabFromPosition(inputPosition, this.getDirection().getOpposite());
}
if (itemStack != null && itemStack.stackSize > 0) {
this.throwItem(outputPosition, itemStack);
}
}
public void throwItem(Vector3 outputPosition, ItemStack items) {
if (!this.worldObj.isRemote) {
EntityItem entityItem = new EntityItem(this.worldObj, outputPosition.x + 0.5, outputPosition.y + 0.8, outputPosition.z + 0.5, items);
entityItem.motionX = 0.0;
entityItem.motionZ = 0.0;
entityItem.motionY /= 5.0;
entityItem.delayBeforeCanPickup = 20;
this.worldObj.spawnEntityInWorld((Entity)entityItem);
}
}
private ItemStack tryPlaceInPosition(ItemStack itemStack, Vector3 position, ForgeDirection direction) {
TileEntity tileEntity = position.getTileEntity((IBlockAccess)this.worldObj);
if (tileEntity != null && itemStack != null) {
if (tileEntity instanceof TileEntityMulti) {
Vector3 mainBlockPosition = ((TileEntityMulti)tileEntity).mainBlockPosition;
if (mainBlockPosition != null && !(mainBlockPosition.getTileEntity((IBlockAccess)this.worldObj) instanceof TileEntityMulti)) {
return this.tryPlaceInPosition(itemStack, mainBlockPosition, direction);
}
} else if (tileEntity instanceof TileEntityChest) {
TileEntityChest[] chests = new TileEntityChest[]{(TileEntityChest)tileEntity, null};
for (int i = 2; i < 6; ++i) {
ForgeDirection searchDirection = ForgeDirection.getOrientation((int)i);
Vector3 searchPosition = position.clone();
searchPosition.modifyPositionFromSide(searchDirection);
if (searchPosition.getTileEntity((IBlockAccess)this.worldObj) == null || searchPosition.getTileEntity((IBlockAccess)this.worldObj).getClass() != chests[0].getClass()) continue;
chests[1] = (TileEntityChest)searchPosition.getTileEntity((IBlockAccess)this.worldObj);
break;
}
for (TileEntityChest chest : chests) {
if (chest == null) continue;
for (int i = 0; i < chest.getSizeInventory(); ++i) {
if ((itemStack = this.addStackToInventory(i, (IInventory)chest, itemStack)) != null) continue;
return null;
}
}
} else {
if (tileEntity instanceof TileEntityCrate) {
return BlockCrate.putIn((TileEntityCrate)tileEntity, itemStack);
}
if (tileEntity instanceof ISidedInventory) {
int startIndex;
ISidedInventory inventory = (ISidedInventory)tileEntity;
for (int i : inventory.getAccessibleSlotsFromSide(direction.ordinal())) {
if ((itemStack = this.addStackToInventory(i, (IInventory)inventory, itemStack)) != null) continue;
return null;
}
} else if (tileEntity instanceof IInventory) {
IInventory inventory = (IInventory)tileEntity;
for (int i = 0; i < inventory.getSizeInventory(); ++i) {
if ((itemStack = this.addStackToInventory(i, inventory, itemStack)) != null) continue;
return null;
}
}
}
}
if (itemStack.stackSize <= 0) {
return null;
}
return itemStack;
}
public ItemStack addStackToInventory(int slotIndex, IInventory inventory, ItemStack itemStack) {
if (inventory.getSizeInventory() > slotIndex) {
ItemStack stackInInventory = inventory.getStackInSlot(slotIndex);
if (stackInInventory == null) {
inventory.setInventorySlotContents(slotIndex, itemStack);
if (inventory.getStackInSlot(slotIndex) == null) {
return itemStack;
}
return null;
}
if (stackInInventory.isItemEqual(itemStack) && stackInInventory.isStackable()) {
stackInInventory = stackInInventory.copy();
int stackLim = Math.min(inventory.getInventoryStackLimit(), itemStack.getMaxStackSize());
int rejectedAmount = Math.max(stackInInventory.stackSize + itemStack.stackSize - stackLim, 0);
stackInInventory.stackSize = Math.min(Math.max(stackInInventory.stackSize + itemStack.stackSize - rejectedAmount, 0), inventory.getInventoryStackLimit());
itemStack.stackSize = rejectedAmount;
inventory.setInventorySlotContents(slotIndex, stackInInventory);
}
}
if (itemStack.stackSize <= 0) {
return null;
}
return itemStack;
}
private ItemStack tryGrabFromPosition(Vector3 position, ForgeDirection direction) {
ItemStack returnStack;
block6: {
TileEntity tileEntity;
block9: {
int startIndex;
block8: {
block7: {
returnStack = null;
tileEntity = position.getTileEntity((IBlockAccess)this.worldObj);
if (tileEntity == null) break block6;
if (!(tileEntity instanceof TileEntityMulti)) break block7;
Vector3 mainBlockPosition = ((TileEntityMulti)tileEntity).mainBlockPosition;
if (mainBlockPosition != null && !(mainBlockPosition.getTileEntity((IBlockAccess)this.worldObj) instanceof TileEntityMulti)) {
return this.tryGrabFromPosition(mainBlockPosition, direction);
}
break block6;
}
if (!(tileEntity instanceof TileEntityChest)) break block8;
TileEntityChest[] chests = new TileEntityChest[]{(TileEntityChest)tileEntity, null};
for (int i = 2; i < 6; ++i) {
ForgeDirection searchDirection = ForgeDirection.getOrientation((int)i);
Vector3 searchPosition = position.clone();
searchPosition.modifyPositionFromSide(searchDirection);
if (searchPosition.getTileEntity((IBlockAccess)this.worldObj) == null || searchPosition.getTileEntity((IBlockAccess)this.worldObj).getClass() != chests[0].getClass()) continue;
chests[1] = (TileEntityChest)searchPosition.getTileEntity((IBlockAccess)this.worldObj);
break;
}
for (TileEntityChest chest : chests) {
if (chest == null) continue;
for (int i = 0; i < chest.getSizeInventory(); ++i) {
ItemStack itemStack = this.removeStackFromInventory(i, (IInventory)chest);
if (itemStack == null) continue;
returnStack = itemStack;
break block6;
}
}
break block6;
}
if (!(tileEntity instanceof ISidedInventory)) break block9;
ISidedInventory inventory = (ISidedInventory)tileEntity;
for (int i : inventory.getAccessibleSlotsFromSide(direction.ordinal())) {
ItemStack itemStack = this.removeStackFromInventory(i, (IInventory)inventory);
if (itemStack == null) continue;
returnStack = itemStack;
break block6;
}
break block6;
}
if (!(tileEntity instanceof IInventory)) break block6;
IInventory inventory = (IInventory)tileEntity;
for (int i = 0; i < inventory.getSizeInventory(); ++i) {
ItemStack itemStack = this.removeStackFromInventory(i, inventory);
if (itemStack == null) continue;
returnStack = itemStack;
break;
}
}
return returnStack;
}
public ItemStack removeStackFromInventory(int slotIndex, IInventory inventory) {
if (inventory.getStackInSlot(slotIndex) != null) {
ItemStack itemStack = inventory.getStackInSlot(slotIndex).copy();
if (this.getFilter() == null || this.isFiltering(itemStack)) {
itemStack.stackSize = 1;
inventory.decrStackSize(slotIndex, 1);
return itemStack;
}
}
return null;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
this.isOutput = nbt.getBoolean("isOutput");
this.selfPulse = nbt.getBoolean("selfpulse");
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setBoolean("isOutput", this.isOutput);
nbt.setBoolean("selfpulse", this.selfPulse);
}
@Override
public void onPowerOn() {
this.isRedstonePowered = true;
}
@Override
public void onPowerOff() {
this.isRedstonePowered = false;
}
@Override
public boolean canConnect(ForgeDirection dir) {
return dir != this.getDirection();
}
}