Working on rewriting the hopper for advanced features
Working on creating an upgraded hopper that has features for control when the hopper works, what it can handle, sorting, and direct interaction with some machine. Including a version that has a create built into it.
This commit is contained in:
parent
ce739b47bb
commit
3b1484e53c
3 changed files with 745 additions and 1 deletions
292
src/dark/assembly/machine/red/BlockAdvancedHopper.java
Normal file
292
src/dark/assembly/machine/red/BlockAdvancedHopper.java
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
package dark.assembly.machine.red;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockContainer;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.client.renderer.texture.IconRegister;
|
||||||
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.item.EntityItem;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.inventory.Container;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntityHopper;
|
||||||
|
import net.minecraft.util.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.Facing;
|
||||||
|
import net.minecraft.util.Icon;
|
||||||
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
import dark.core.common.DMCreativeTab;
|
||||||
|
import dark.core.common.DarkMain;
|
||||||
|
import dark.core.prefab.machine.BlockMachine;
|
||||||
|
|
||||||
|
public class BlockAdvancedHopper extends BlockMachine
|
||||||
|
{
|
||||||
|
private final Random rand = new Random();
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static Icon hopperIcon;
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static Icon hopperTopIcon;
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static Icon hopperInsideIcon;
|
||||||
|
|
||||||
|
public BlockAdvancedHopper(int par1)
|
||||||
|
{
|
||||||
|
super(DarkMain.CONFIGURATION, "DMHopper", Material.iron);
|
||||||
|
this.setCreativeTab(DMCreativeTab.tabAutomation);
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates the blocks bounds based on its current state. Args: world, x, y, z */
|
||||||
|
public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
|
||||||
|
{
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds all intersecting collision boxes to a list. (Be sure to only add boxes to the list if
|
||||||
|
* they intersect the mask.) Parameters: World, X, Y, Z, mask, list, colliding entity */
|
||||||
|
public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
|
||||||
|
{
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F);
|
||||||
|
super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
|
||||||
|
float f = 0.125F;
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
|
||||||
|
super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
|
||||||
|
super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
|
||||||
|
this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
|
||||||
|
super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
|
||||||
|
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY,
|
||||||
|
* hitZ, block metadata */
|
||||||
|
public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
|
||||||
|
{
|
||||||
|
int j1 = Facing.oppositeSide[par5];
|
||||||
|
|
||||||
|
if (j1 == 1)
|
||||||
|
{
|
||||||
|
j1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return j1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new instance of a block's tile entity class. Called on placing the block. */
|
||||||
|
public TileEntity createNewTileEntity(World par1World)
|
||||||
|
{
|
||||||
|
return new TileEntityAdvancedHopper();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when the block is placed in the world. */
|
||||||
|
public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack)
|
||||||
|
{
|
||||||
|
super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLivingBase, par6ItemStack);
|
||||||
|
|
||||||
|
if (par6ItemStack.hasDisplayName())
|
||||||
|
{
|
||||||
|
TileEntityAdvancedHopper tileentityhopper = getHopperTile(par1World, par2, par3, par4);
|
||||||
|
tileentityhopper.setInventoryName(par6ItemStack.getDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called whenever the block is added into the world. Args: world, x, y, z */
|
||||||
|
public void onBlockAdded(World par1World, int par2, int par3, int par4)
|
||||||
|
{
|
||||||
|
super.onBlockAdded(par1World, par2, par3, par4);
|
||||||
|
this.updateMetadata(par1World, par2, par3, par4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called upon block activation (right click on the block.) */
|
||||||
|
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
|
||||||
|
{
|
||||||
|
if (par1World.isRemote)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TileEntityAdvancedHopper tileentityhopper = getHopperTile(par1World, par2, par3, par4);
|
||||||
|
|
||||||
|
if (tileentityhopper != null)
|
||||||
|
{
|
||||||
|
par5EntityPlayer.displayGUIHopper(tileentityhopper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed
|
||||||
|
* (coordinates passed are their own) Args: x, y, z, neighbor blockID */
|
||||||
|
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
|
||||||
|
{
|
||||||
|
this.updateMetadata(par1World, par2, par3, par4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates the Metadata to include if the Hopper gets powered by Redstone or not */
|
||||||
|
private void updateMetadata(World par1World, int par2, int par3, int par4)
|
||||||
|
{
|
||||||
|
int l = par1World.getBlockMetadata(par2, par3, par4);
|
||||||
|
int i1 = getDirectionFromMetadata(l);
|
||||||
|
boolean flag = !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4);
|
||||||
|
boolean flag1 = getIsBlockNotPoweredFromMetadata(l);
|
||||||
|
|
||||||
|
if (flag != flag1)
|
||||||
|
{
|
||||||
|
par1World.setBlockMetadataWithNotify(par2, par3, par4, i1 | (flag ? 0 : 8), 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called on server worlds only when the block has been replaced by a different block ID, or the
|
||||||
|
* same block with a different metadata value, but before the new metadata value is set. Args:
|
||||||
|
* World, x, y, z, old block ID, old metadata */
|
||||||
|
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
|
||||||
|
{
|
||||||
|
TileEntityAdvancedHopper tileentityhopper = (TileEntityAdvancedHopper) par1World.getBlockTileEntity(par2, par3, par4);
|
||||||
|
|
||||||
|
if (tileentityhopper != null)
|
||||||
|
{
|
||||||
|
for (int j1 = 0; j1 < tileentityhopper.getSizeInventory(); ++j1)
|
||||||
|
{
|
||||||
|
ItemStack itemstack = tileentityhopper.getStackInSlot(j1);
|
||||||
|
|
||||||
|
if (itemstack != null)
|
||||||
|
{
|
||||||
|
float f = this.rand.nextFloat() * 0.8F + 0.1F;
|
||||||
|
float f1 = this.rand.nextFloat() * 0.8F + 0.1F;
|
||||||
|
float f2 = this.rand.nextFloat() * 0.8F + 0.1F;
|
||||||
|
|
||||||
|
while (itemstack.stackSize > 0)
|
||||||
|
{
|
||||||
|
int k1 = this.rand.nextInt(21) + 10;
|
||||||
|
|
||||||
|
if (k1 > itemstack.stackSize)
|
||||||
|
{
|
||||||
|
k1 = itemstack.stackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemstack.stackSize -= k1;
|
||||||
|
EntityItem entityitem = new EntityItem(par1World, (double) ((float) par2 + f), (double) ((float) par3 + f1), (double) ((float) par4 + f2), new ItemStack(itemstack.itemID, k1, itemstack.getItemDamage()));
|
||||||
|
|
||||||
|
if (itemstack.hasTagCompound())
|
||||||
|
{
|
||||||
|
entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
float f3 = 0.05F;
|
||||||
|
entityitem.motionX = (double) ((float) this.rand.nextGaussian() * f3);
|
||||||
|
entityitem.motionY = (double) ((float) this.rand.nextGaussian() * f3 + 0.2F);
|
||||||
|
entityitem.motionZ = (double) ((float) this.rand.nextGaussian() * f3);
|
||||||
|
par1World.spawnEntityInWorld(entityitem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
par1World.func_96440_m(par2, par3, par4, par5);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.breakBlock(par1World, par2, par3, par4, par5, par6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The type of render function that is called for this block */
|
||||||
|
public int getRenderType()
|
||||||
|
{
|
||||||
|
return 38;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If this block doesn't render as an ordinary block it will return False (examples: signs,
|
||||||
|
* buttons, stairs, etc) */
|
||||||
|
public boolean renderAsNormalBlock()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the
|
||||||
|
* shared face of two adjacent blocks and also whether the player can attach torches, redstone
|
||||||
|
* wire, etc to this block. */
|
||||||
|
public boolean isOpaqueCube()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDirectionFromMetadata(int par0)
|
||||||
|
{
|
||||||
|
return par0 & 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
/**
|
||||||
|
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
|
||||||
|
* coordinates. Args: blockAccess, x, y, z, side
|
||||||
|
*/
|
||||||
|
public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
/**
|
||||||
|
* From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
|
||||||
|
*/
|
||||||
|
public Icon getIcon(int par1, int par2)
|
||||||
|
{
|
||||||
|
return par1 == 1 ? this.hopperTopIcon : this.hopperIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getIsBlockNotPoweredFromMetadata(int par0)
|
||||||
|
{
|
||||||
|
return (par0 & 8) != 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If this returns true, then comparators facing away from this block will use the value from
|
||||||
|
* getComparatorInputOverride instead of the actual redstone signal strength. */
|
||||||
|
public boolean hasComparatorInputOverride()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If hasComparatorInputOverride returns true, the return value from this is used instead of the
|
||||||
|
* redstone signal strength when this block inputs to a comparator. */
|
||||||
|
public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5)
|
||||||
|
{
|
||||||
|
return Container.calcRedstoneFromInventory(getHopperTile(par1World, par2, par3, par4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
/**
|
||||||
|
* When this method is called, your block should register all the icons it needs with the given IconRegister. This
|
||||||
|
* is the only chance you get to register icons.
|
||||||
|
*/
|
||||||
|
public void registerIcons(IconRegister par1IconRegister)
|
||||||
|
{
|
||||||
|
this.hopperIcon = par1IconRegister.registerIcon("hopper_outside");
|
||||||
|
this.hopperTopIcon = par1IconRegister.registerIcon("hopper_top");
|
||||||
|
this.hopperInsideIcon = par1IconRegister.registerIcon("hopper_inside");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
/**
|
||||||
|
* Gets the icon name of the ItemBlock corresponding to this block. Used by hoppers.
|
||||||
|
*/
|
||||||
|
public String getItemIconName()
|
||||||
|
{
|
||||||
|
return "hopper";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TileEntityAdvancedHopper getHopperTile(IBlockAccess par0IBlockAccess, int par1, int par2, int par3)
|
||||||
|
{
|
||||||
|
return (TileEntityAdvancedHopper) par0IBlockAccess.getBlockTileEntity(par1, par2, par3);
|
||||||
|
}
|
||||||
|
}
|
425
src/dark/assembly/machine/red/TileEntityAdvancedHopper.java
Normal file
425
src/dark/assembly/machine/red/TileEntityAdvancedHopper.java
Normal file
|
@ -0,0 +1,425 @@
|
||||||
|
package dark.assembly.machine.red;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import dark.core.prefab.machine.TileEntityMachine;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockChest;
|
||||||
|
import net.minecraft.command.IEntitySelector;
|
||||||
|
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.Hopper;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntityChest;
|
||||||
|
import net.minecraft.util.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.Facing;
|
||||||
|
import net.minecraft.util.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/** Advanced version of the hopper with features such as redstone control, sorting, filtering, and
|
||||||
|
* crate version.
|
||||||
|
*
|
||||||
|
* @author DarkGuardsman */
|
||||||
|
public class TileEntityAdvancedHopper extends TileEntityMachine implements Hopper
|
||||||
|
{
|
||||||
|
/** The name that is displayed if the hopper was renamed */
|
||||||
|
private String inventoryName;
|
||||||
|
private int transferCooldown = -1;
|
||||||
|
|
||||||
|
public TileEntityAdvancedHopper()
|
||||||
|
{
|
||||||
|
this.invSlots = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner
|
||||||
|
* uses this to count ticks and creates a new spawn inside its implementation. */
|
||||||
|
@Override
|
||||||
|
public void updateEntity()
|
||||||
|
{
|
||||||
|
if (this.worldObj != null && !this.worldObj.isRemote)
|
||||||
|
{
|
||||||
|
--this.transferCooldown;
|
||||||
|
|
||||||
|
if (!this.isCoolingDown())
|
||||||
|
{
|
||||||
|
this.setTransferCooldown(0);
|
||||||
|
this.updateHopper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateHopper()
|
||||||
|
{
|
||||||
|
if (this.worldObj != null && !this.worldObj.isRemote)
|
||||||
|
{
|
||||||
|
if (!this.isCoolingDown() && BlockAdvancedHopper.getIsBlockNotPoweredFromMetadata(this.getBlockMetadata()))
|
||||||
|
{
|
||||||
|
boolean flag = this.insertItemToInventory();
|
||||||
|
flag = suckItemsIntoHopper(this) || flag;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
this.setTransferCooldown(8);
|
||||||
|
this.onInventoryChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound nbt)
|
||||||
|
{
|
||||||
|
super.readFromNBT(nbt);
|
||||||
|
if (nbt.hasKey("CustomName"))
|
||||||
|
{
|
||||||
|
this.inventoryName = nbt.getString("CustomName");
|
||||||
|
}
|
||||||
|
this.transferCooldown = nbt.getInteger("TransferCooldown");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound nbt)
|
||||||
|
{
|
||||||
|
super.writeToNBT(nbt);
|
||||||
|
nbt.setInteger("TransferCooldown", this.transferCooldown);
|
||||||
|
if (this.isInvNameLocalized())
|
||||||
|
{
|
||||||
|
nbt.setString("CustomName", this.inventoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the name of the inventory. */
|
||||||
|
@Override
|
||||||
|
public String getInvName()
|
||||||
|
{
|
||||||
|
return this.isInvNameLocalized() ? this.inventoryName : "container.hopper";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Inserts one item from the hopper into the inventory the hopper is pointing at. */
|
||||||
|
private boolean insertItemToInventory()
|
||||||
|
{
|
||||||
|
IInventory iinventory = this.getOutputInventory();
|
||||||
|
|
||||||
|
if (iinventory == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this.getSizeInventory(); ++i)
|
||||||
|
{
|
||||||
|
if (this.getStackInSlot(i) != null)
|
||||||
|
{
|
||||||
|
ItemStack itemstack = this.getStackInSlot(i).copy();
|
||||||
|
ItemStack itemstack1 = insertStack(iinventory, this.decrStackSize(i, 1), Facing.oppositeSide[BlockAdvancedHopper.getDirectionFromMetadata(this.getBlockMetadata())]);
|
||||||
|
|
||||||
|
if (itemstack1 == null || itemstack1.stackSize == 0)
|
||||||
|
{
|
||||||
|
iinventory.onInventoryChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setInventorySlotContents(i, itemstack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sucks one item into the given hopper from an inventory or EntityItem above it. */
|
||||||
|
public static boolean suckItemsIntoHopper(Hopper par0Hopper)
|
||||||
|
{
|
||||||
|
IInventory iinventory = getInventoryAboveHopper(par0Hopper);
|
||||||
|
|
||||||
|
if (iinventory != null)
|
||||||
|
{
|
||||||
|
byte b0 = 0;
|
||||||
|
|
||||||
|
if (iinventory instanceof ISidedInventory && b0 > -1)
|
||||||
|
{
|
||||||
|
ISidedInventory isidedinventory = (ISidedInventory) iinventory;
|
||||||
|
int[] aint = isidedinventory.getAccessibleSlotsFromSide(b0);
|
||||||
|
|
||||||
|
for (int i = 0; i < aint.length; ++i)
|
||||||
|
{
|
||||||
|
if (insertStackFromInventory(par0Hopper, iinventory, aint[i], b0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int j = iinventory.getSizeInventory();
|
||||||
|
|
||||||
|
for (int k = 0; k < j; ++k)
|
||||||
|
{
|
||||||
|
if (insertStackFromInventory(par0Hopper, iinventory, k, b0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EntityItem entityitem = getEntityAbove(par0Hopper.getWorldObj(), par0Hopper.getXPos(), par0Hopper.getYPos() + 1.0D, par0Hopper.getZPos());
|
||||||
|
|
||||||
|
if (entityitem != null)
|
||||||
|
{
|
||||||
|
return insertStackFromEntity(par0Hopper, entityitem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean insertStackFromInventory(Hopper par0Hopper, IInventory par1IInventory, int par2, int par3)
|
||||||
|
{
|
||||||
|
ItemStack itemstack = par1IInventory.getStackInSlot(par2);
|
||||||
|
|
||||||
|
if (itemstack != null && canExtractItemFromInventory(par1IInventory, itemstack, par2, par3))
|
||||||
|
{
|
||||||
|
ItemStack itemstack1 = itemstack.copy();
|
||||||
|
ItemStack itemstack2 = insertStack(par0Hopper, par1IInventory.decrStackSize(par2, 1), -1);
|
||||||
|
|
||||||
|
if (itemstack2 == null || itemstack2.stackSize == 0)
|
||||||
|
{
|
||||||
|
par1IInventory.onInventoryChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
par1IInventory.setInventorySlotContents(par2, itemstack1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean insertStackFromEntity(IInventory par0IInventory, EntityItem par1EntityItem)
|
||||||
|
{
|
||||||
|
boolean flag = false;
|
||||||
|
|
||||||
|
if (par1EntityItem == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ItemStack itemstack = par1EntityItem.getEntityItem().copy();
|
||||||
|
ItemStack itemstack1 = insertStack(par0IInventory, itemstack, -1);
|
||||||
|
|
||||||
|
if (itemstack1 != null && itemstack1.stackSize != 0)
|
||||||
|
{
|
||||||
|
par1EntityItem.setEntityItemStack(itemstack1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flag = true;
|
||||||
|
par1EntityItem.setDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Inserts a stack into an inventory. Args: Inventory, stack, side. Returns leftover items. */
|
||||||
|
public static ItemStack insertStack(IInventory par0IInventory, ItemStack par1ItemStack, int par2)
|
||||||
|
{
|
||||||
|
if (par0IInventory instanceof ISidedInventory && par2 > -1)
|
||||||
|
{
|
||||||
|
ISidedInventory isidedinventory = (ISidedInventory) par0IInventory;
|
||||||
|
int[] aint = isidedinventory.getAccessibleSlotsFromSide(par2);
|
||||||
|
|
||||||
|
for (int j = 0; j < aint.length && par1ItemStack != null && par1ItemStack.stackSize > 0; ++j)
|
||||||
|
{
|
||||||
|
par1ItemStack = func_102014_c(par0IInventory, par1ItemStack, aint[j], par2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int k = par0IInventory.getSizeInventory();
|
||||||
|
|
||||||
|
for (int l = 0; l < k && par1ItemStack != null && par1ItemStack.stackSize > 0; ++l)
|
||||||
|
{
|
||||||
|
par1ItemStack = func_102014_c(par0IInventory, par1ItemStack, l, par2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (par1ItemStack != null && par1ItemStack.stackSize == 0)
|
||||||
|
{
|
||||||
|
par1ItemStack = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return par1ItemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Args: inventory, item, slot, side */
|
||||||
|
private static boolean canInsertItemToInventory(IInventory par0IInventory, ItemStack par1ItemStack, int par2, int par3)
|
||||||
|
{
|
||||||
|
return !par0IInventory.isItemValidForSlot(par2, par1ItemStack) ? false : !(par0IInventory instanceof ISidedInventory) || ((ISidedInventory) par0IInventory).canInsertItem(par2, par1ItemStack, par3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canExtractItemFromInventory(IInventory par0IInventory, ItemStack par1ItemStack, int par2, int par3)
|
||||||
|
{
|
||||||
|
return !(par0IInventory instanceof ISidedInventory) || ((ISidedInventory) par0IInventory).canExtractItem(par2, par1ItemStack, par3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack func_102014_c(IInventory par0IInventory, ItemStack par1ItemStack, int par2, int par3)
|
||||||
|
{
|
||||||
|
ItemStack itemstack1 = par0IInventory.getStackInSlot(par2);
|
||||||
|
|
||||||
|
if (canInsertItemToInventory(par0IInventory, par1ItemStack, par2, par3))
|
||||||
|
{
|
||||||
|
boolean flag = false;
|
||||||
|
|
||||||
|
if (itemstack1 == null)
|
||||||
|
{
|
||||||
|
int max = Math.min(par1ItemStack.getMaxStackSize(), par0IInventory.getInventoryStackLimit());
|
||||||
|
if (max >= par1ItemStack.stackSize)
|
||||||
|
{
|
||||||
|
par0IInventory.setInventorySlotContents(par2, par1ItemStack);
|
||||||
|
par1ItemStack = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
par0IInventory.setInventorySlotContents(par2, par1ItemStack.splitStack(max));
|
||||||
|
}
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
else if (areItemStacksEqualItem(itemstack1, par1ItemStack))
|
||||||
|
{
|
||||||
|
int max = Math.min(par1ItemStack.getMaxStackSize(), par0IInventory.getInventoryStackLimit());
|
||||||
|
if (max > itemstack1.stackSize)
|
||||||
|
{
|
||||||
|
int l = Math.min(par1ItemStack.stackSize, max - itemstack1.stackSize);
|
||||||
|
par1ItemStack.stackSize -= l;
|
||||||
|
itemstack1.stackSize += l;
|
||||||
|
flag = l > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
if (par0IInventory instanceof TileEntityAdvancedHopper)
|
||||||
|
{
|
||||||
|
((TileEntityAdvancedHopper) par0IInventory).setTransferCooldown(8);
|
||||||
|
par0IInventory.onInventoryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
par0IInventory.onInventoryChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return par1ItemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the inventory the hopper is pointing at. */
|
||||||
|
private IInventory getOutputInventory()
|
||||||
|
{
|
||||||
|
int i = BlockAdvancedHopper.getDirectionFromMetadata(this.getBlockMetadata());
|
||||||
|
return getInventoryAtLocation(this.getWorldObj(), (this.xCoord + Facing.offsetsXForSide[i]), (this.yCoord + Facing.offsetsYForSide[i]), (this.zCoord + Facing.offsetsZForSide[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Looks for anything, that can hold items (like chests, furnaces, etc.) one block above the
|
||||||
|
* given hopper. */
|
||||||
|
public static IInventory getInventoryAboveHopper(Hopper par0Hopper)
|
||||||
|
{
|
||||||
|
return getInventoryAtLocation(par0Hopper.getWorldObj(), par0Hopper.getXPos(), par0Hopper.getYPos() + 1.0D, par0Hopper.getZPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityItem getEntityAbove(World par0World, double par1, double par3, double par5)
|
||||||
|
{
|
||||||
|
List list = par0World.selectEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getAABBPool().getAABB(par1, par3, par5, par1 + 1.0D, par3 + 1.0D, par5 + 1.0D), IEntitySelector.selectAnything);
|
||||||
|
return list.size() > 0 ? (EntityItem) list.get(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets an inventory at the given location to extract items into or take items from. Can find
|
||||||
|
* either a tile entity or regular entity implementing IInventory. */
|
||||||
|
public static IInventory getInventoryAtLocation(World par0World, double par1, double par3, double par5)
|
||||||
|
{
|
||||||
|
IInventory iinventory = null;
|
||||||
|
int i = MathHelper.floor_double(par1);
|
||||||
|
int j = MathHelper.floor_double(par3);
|
||||||
|
int k = MathHelper.floor_double(par5);
|
||||||
|
TileEntity tileentity = par0World.getBlockTileEntity(i, j, k);
|
||||||
|
|
||||||
|
if (tileentity != null && tileentity instanceof IInventory)
|
||||||
|
{
|
||||||
|
iinventory = (IInventory) tileentity;
|
||||||
|
|
||||||
|
if (iinventory instanceof TileEntityChest)
|
||||||
|
{
|
||||||
|
int l = par0World.getBlockId(i, j, k);
|
||||||
|
Block block = Block.blocksList[l];
|
||||||
|
|
||||||
|
if (block instanceof BlockChest)
|
||||||
|
{
|
||||||
|
iinventory = ((BlockChest) block).getInventory(par0World, i, j, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iinventory == null)
|
||||||
|
{
|
||||||
|
List list = par0World.getEntitiesWithinAABBExcludingEntity((Entity) null, AxisAlignedBB.getAABBPool().getAABB(par1, par3, par5, par1 + 1.0D, par3 + 1.0D, par5 + 1.0D), IEntitySelector.selectInventories);
|
||||||
|
|
||||||
|
if (list != null && list.size() > 0)
|
||||||
|
{
|
||||||
|
iinventory = (IInventory) list.get(par0World.rand.nextInt(list.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iinventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean areItemStacksEqualItem(ItemStack par0ItemStack, ItemStack par1ItemStack)
|
||||||
|
{
|
||||||
|
return par0ItemStack.itemID != par1ItemStack.itemID ? false : (par0ItemStack.getItemDamage() != par1ItemStack.getItemDamage() ? false : (par0ItemStack.stackSize > par0ItemStack.getMaxStackSize() ? false : ItemStack.areItemStackTagsEqual(par0ItemStack, par1ItemStack)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the world X position for this hopper entity. */
|
||||||
|
@Override
|
||||||
|
public double getXPos()
|
||||||
|
{
|
||||||
|
return this.xCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the world Y position for this hopper entity. */
|
||||||
|
@Override
|
||||||
|
public double getYPos()
|
||||||
|
{
|
||||||
|
return this.yCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the world Z position for this hopper entity. */
|
||||||
|
@Override
|
||||||
|
public double getZPos()
|
||||||
|
{
|
||||||
|
return this.zCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransferCooldown(int par1)
|
||||||
|
{
|
||||||
|
this.transferCooldown = par1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCoolingDown()
|
||||||
|
{
|
||||||
|
return this.transferCooldown > 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,35 @@
|
||||||
package dark.assembly.machine.red;
|
package dark.assembly.machine.red;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import universalelectricity.core.vector.Vector3;
|
||||||
|
import dark.core.interfaces.IMultiBlock;
|
||||||
import dark.core.prefab.machine.TileEntityMachine;
|
import dark.core.prefab.machine.TileEntityMachine;
|
||||||
|
|
||||||
public class TileEntityPistonPlus extends TileEntityMachine
|
public class TileEntityPistonPlus extends TileEntityMachine implements IMultiBlock
|
||||||
{
|
{
|
||||||
|
int extensionLimit = 1;
|
||||||
|
boolean isExtended = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActivated(EntityPlayer entityPlayer)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Vector3 placedPosition)
|
||||||
|
{
|
||||||
|
//Don't do anything here as we will handle this in the update area
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy(TileEntity callingBlock)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue