Update TileAutoWorkbench.java
This commit is contained in:
parent
bda4de6024
commit
903dd33568
1 changed files with 183 additions and 328 deletions
|
@ -9,393 +9,235 @@
|
|||
|
||||
package buildcraft.factory;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryCraftResult;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import net.minecraftforge.common.ISidedInventory;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
|
||||
import buildcraft.api.core.Position;
|
||||
import buildcraft.api.inventory.ISpecialInventory;
|
||||
import buildcraft.core.inventory.TransactorRoundRobin;
|
||||
import buildcraft.core.proxy.CoreProxy;
|
||||
import buildcraft.core.utils.CraftingHelper;
|
||||
import buildcraft.core.utils.SidedInventoryAdapter;
|
||||
import buildcraft.core.utils.Utils;
|
||||
|
||||
public class TileAutoWorkbench extends TileEntity implements ISpecialInventory {
|
||||
|
||||
private ItemStack stackList[] = new ItemStack[9];
|
||||
private IRecipe currentRecipe = null;
|
||||
|
||||
class LocalInventoryCrafting extends InventoryCrafting {
|
||||
|
||||
public LocalInventoryCrafting() {
|
||||
super(new Container() {
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public boolean isUsableByPlayer(EntityPlayer entityplayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public boolean canInteractWith(EntityPlayer entityplayer) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}, 3, 3);
|
||||
// TODO Auto-generated constructor stub
|
||||
private IInventory craftResult = new InventoryCraftResult();
|
||||
|
||||
private InventoryCrafting crafting = new InventoryCrafting(new Container() {
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer entityplayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCraftMatrixChanged(IInventory inventory) {}
|
||||
}, 3, 3);
|
||||
|
||||
@Override
|
||||
public void onInventoryChanged() {
|
||||
craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(crafting, this.worldObj));
|
||||
super.onInventoryChanged();
|
||||
}
|
||||
|
||||
public IRecipe getCurrentRecipe() {
|
||||
|
||||
return currentRecipe ;
|
||||
|
||||
public IInventory getCraftResult() {
|
||||
return this.craftResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeInventory() {
|
||||
|
||||
return stackList.length;
|
||||
return this.crafting.getSizeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int i) {
|
||||
return stackList[i];
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
return this.crafting.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int slotId, int count) {
|
||||
if (stackList[slotId] == null)
|
||||
return null;
|
||||
if (stackList[slotId].stackSize > count)
|
||||
return stackList[slotId].splitStack(count);
|
||||
ItemStack stack = stackList[slotId];
|
||||
stackList[slotId] = null;
|
||||
return stack;
|
||||
public ItemStack decrStackSize(int slot, int amount) {
|
||||
ItemStack item = this.crafting.decrStackSize(slot, amount);
|
||||
this.onInventoryChanged();
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int i, ItemStack itemstack) {
|
||||
stackList[i] = itemstack;
|
||||
public void setInventorySlotContents(int slot, ItemStack stack) {
|
||||
this.crafting.setInventorySlotContents(slot, stack);
|
||||
this.onInventoryChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlotOnClosing(int slot) {
|
||||
if (this.stackList[slot] == null)
|
||||
return null;
|
||||
|
||||
ItemStack stackToTake = this.stackList[slot];
|
||||
this.stackList[slot] = null;
|
||||
return stackToTake;
|
||||
return this.crafting.getStackInSlotOnClosing(slot);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getInvName() {
|
||||
|
||||
return "";
|
||||
return "AutoCrafting";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit() {
|
||||
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
|
||||
return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this;
|
||||
public boolean isUseableByPlayer(EntityPlayer player) {
|
||||
return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbttagcompound) {
|
||||
super.readFromNBT(nbttagcompound);
|
||||
|
||||
Utils.readStacksFromNBT(nbttagcompound, "stackList", stackList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound nbttagcompound) {
|
||||
super.writeToNBT(nbttagcompound);
|
||||
|
||||
Utils.writeStacksToNBT(nbttagcompound, "stackList", stackList);
|
||||
}
|
||||
|
||||
class StackPointer {
|
||||
|
||||
IInventory inventory;
|
||||
int index;
|
||||
ItemStack item;
|
||||
}
|
||||
|
||||
public ItemStack findRecipe() {
|
||||
InventoryCrafting craftMatrix = new LocalInventoryCrafting();
|
||||
|
||||
for (int i = 0; i < getSizeInventory(); ++i) {
|
||||
ItemStack stack = getStackInSlot(i);
|
||||
|
||||
craftMatrix.setInventorySlotContents(i, stack);
|
||||
}
|
||||
|
||||
if(this.currentRecipe == null || !this.currentRecipe.matches(craftMatrix, worldObj))
|
||||
currentRecipe = CraftingHelper.findMatchingRecipe(craftMatrix, worldObj);
|
||||
|
||||
if(currentRecipe!=null)
|
||||
return currentRecipe.getCraftingResult(craftMatrix);
|
||||
return null;
|
||||
}
|
||||
|
||||
public ItemStack extractItem(boolean doRemove, boolean removeRecipe) {
|
||||
InventoryCrafting craftMatrix = new LocalInventoryCrafting();
|
||||
|
||||
LinkedList<StackPointer> pointerList = new LinkedList<StackPointer>();
|
||||
|
||||
int itemsToLeave = (removeRecipe ? 0 : 1);
|
||||
|
||||
for (int i = 0; i < getSizeInventory(); ++i) {
|
||||
ItemStack stack = getStackInSlot(i);
|
||||
|
||||
if (stack != null) {
|
||||
if (stack.stackSize <= itemsToLeave) {
|
||||
StackPointer pointer = getNearbyItem(stack);
|
||||
|
||||
if (pointer == null) {
|
||||
resetPointers(pointerList);
|
||||
|
||||
return null;
|
||||
} else {
|
||||
pointerList.add(pointer);
|
||||
}
|
||||
} else {
|
||||
StackPointer pointer = new StackPointer();
|
||||
pointer.inventory = this;
|
||||
pointer.item = this.decrStackSize(i, 1);
|
||||
pointer.index = i;
|
||||
stack = pointer.item;
|
||||
|
||||
pointerList.add(pointer);
|
||||
|
||||
public void refilFromNeibour(){
|
||||
//pre-compute to see if there are enough items
|
||||
{
|
||||
ItemStack[] required = new ItemStack[this.getSizeInventory()];
|
||||
|
||||
for (int slot = 0; slot < this.getSizeInventory(); slot++){
|
||||
ItemStack item = this.getStackInSlot(slot);
|
||||
|
||||
if (item != null && item.stackSize == 1){
|
||||
required[slot] = item.copy();
|
||||
}
|
||||
}
|
||||
|
||||
craftMatrix.setInventorySlotContents(i, stack);
|
||||
}
|
||||
|
||||
if(this.currentRecipe == null || !this.currentRecipe.matches(craftMatrix, worldObj))
|
||||
currentRecipe = buildcraft.core.utils.CraftingHelper.findMatchingRecipe(craftMatrix, worldObj);
|
||||
|
||||
|
||||
ItemStack resultStack = null;
|
||||
if(currentRecipe != null) {
|
||||
resultStack = currentRecipe.getCraftingResult(craftMatrix);
|
||||
}
|
||||
|
||||
if (resultStack == null || !doRemove) {
|
||||
resetPointers(pointerList);
|
||||
} else {
|
||||
for (StackPointer p : pointerList) {
|
||||
// replace with the container where appropriate
|
||||
|
||||
if (p.item.getItem().getContainerItem() != null) {
|
||||
ItemStack newStack = p.item.getItem().getContainerItemStack(p.item);
|
||||
|
||||
if (p.item.isItemStackDamageable()) {
|
||||
if (newStack.getItemDamage() >= p.item.getMaxDamage()) {
|
||||
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(CoreProxy.proxy.getBuildCraftPlayer(worldObj, xCoord, yCoord, zCoord),
|
||||
newStack));
|
||||
this.worldObj.playSoundAtEntity(CoreProxy.proxy.getBuildCraftPlayer(worldObj, xCoord, yCoord, zCoord), "random.break", 0.8F,
|
||||
0.8F + this.worldObj.rand.nextFloat() * 0.4F);
|
||||
newStack = null;
|
||||
}
|
||||
}
|
||||
|
||||
p.inventory.setInventorySlotContents(p.index, newStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultStack;
|
||||
}
|
||||
|
||||
public void resetPointers(LinkedList<StackPointer> pointers) {
|
||||
for (StackPointer p : pointers) {
|
||||
ItemStack item = p.inventory.getStackInSlot(p.index);
|
||||
|
||||
if (item == null) {
|
||||
p.inventory.setInventorySlotContents(p.index, p.item);
|
||||
} else {
|
||||
p.inventory.getStackInSlot(p.index).stackSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StackPointer getNearbyItem(ItemStack stack) {
|
||||
StackPointer pointer = null;
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.WEST);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.EAST);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.UP);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.NORTH);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.SOUTH);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(stack, ForgeDirection.UNKNOWN);
|
||||
}
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
public StackPointer getNearbyItemFromOrientation(ItemStack itemStack, ForgeDirection direction) {
|
||||
TileEntity tile = worldObj.getBlockTileEntity(xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ);
|
||||
|
||||
if (tile instanceof ISpecialInventory) {
|
||||
// Don't get stuff out of ISpecialInventory for now / we wouldn't
|
||||
// know how to put it back... And it's not clear if we want to
|
||||
// have workbenches automatically getting things from one another.
|
||||
return null;
|
||||
}
|
||||
|
||||
IInventory inventory = null;
|
||||
if (tile instanceof ISidedInventory){
|
||||
inventory = new SidedInventoryAdapter((ISidedInventory) tile, direction.getOpposite());
|
||||
} else if (tile instanceof IInventory) {
|
||||
inventory = Utils.getInventory((IInventory) tile);
|
||||
}
|
||||
|
||||
if (inventory == null) return null;
|
||||
|
||||
for (int j = 0; j < inventory.getSizeInventory(); ++j) {
|
||||
ItemStack stack = inventory.getStackInSlot(j);
|
||||
|
||||
if (stack != null) {
|
||||
if (stack.stackSize > 0) {
|
||||
if (stack.itemID == itemStack.itemID) {
|
||||
if (!stack.isItemStackDamageable()) {
|
||||
if (stack.itemID == itemStack.itemID && stack.getItemDamage() == itemStack.getItemDamage()) {
|
||||
inventory.decrStackSize(j, 1);
|
||||
|
||||
StackPointer result = new StackPointer();
|
||||
result.inventory = inventory;
|
||||
result.index = j;
|
||||
result.item = stack;
|
||||
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
if (stack.itemID == itemStack.itemID) {
|
||||
inventory.decrStackSize(j, 1);
|
||||
|
||||
StackPointer result = new StackPointer();
|
||||
result.inventory = inventory;
|
||||
result.index = j;
|
||||
result.item = stack;
|
||||
|
||||
return result;
|
||||
|
||||
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS){
|
||||
TileEntity tileEntity = this.worldObj.getBlockTileEntity(side.offsetX + this.xCoord, side.offsetY + this.yCoord, side.offsetZ + this.zCoord);
|
||||
|
||||
if (tileEntity instanceof IInventory){
|
||||
IInventory inventory = (IInventory) tileEntity;
|
||||
|
||||
ItemStack remaining = null;
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++){
|
||||
ItemStack item = inventory.getStackInSlot(slot);
|
||||
|
||||
if (item != null){
|
||||
remaining = item.copy();
|
||||
|
||||
for (int index = 0; index < required.length; index++){
|
||||
if (required[index] != null && item.isItemEqual(required[index])){
|
||||
required[index] = null;
|
||||
|
||||
if (remaining.stackSize == 1){
|
||||
remaining = null;
|
||||
break;
|
||||
}else{
|
||||
remaining.stackSize--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = 0; index < required.length; index++){
|
||||
if (required[index] != null) return;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public StackPointer getNearbyItem(int itemId, int damage) {
|
||||
StackPointer pointer = null;
|
||||
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.WEST);
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.EAST);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.UP);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.NORTH);
|
||||
}
|
||||
|
||||
if (pointer == null) {
|
||||
pointer = getNearbyItemFromOrientation(itemId, damage, ForgeDirection.SOUTH);
|
||||
}
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
public StackPointer getNearbyItemFromOrientation(int itemId, int damage, ForgeDirection orientation) {
|
||||
Position p = new Position(xCoord, yCoord, zCoord, orientation);
|
||||
p.moveForwards(1.0);
|
||||
|
||||
TileEntity tile = worldObj.getBlockTileEntity((int) p.x, (int) p.y, (int) p.z);
|
||||
|
||||
if (tile instanceof ISpecialInventory) {
|
||||
// Don't get stuff out of ISpecialInventory for now / we wouldn't
|
||||
// know how to put it back... And it's not clear if we want to
|
||||
// have workbenches automatically getting things from one another.
|
||||
} else if (tile instanceof IInventory) {
|
||||
IInventory inventory = Utils.getInventory((IInventory) tile);
|
||||
|
||||
for (int j = 0; j < inventory.getSizeInventory(); ++j) {
|
||||
ItemStack stack = inventory.getStackInSlot(j);
|
||||
|
||||
if (stack != null && stack.stackSize > 0 && stack.itemID == itemId && stack.getItemDamage() == damage) {
|
||||
inventory.decrStackSize(j, 1);
|
||||
|
||||
StackPointer result = new StackPointer();
|
||||
result.inventory = inventory;
|
||||
result.index = j;
|
||||
result.item = stack;
|
||||
|
||||
return result;
|
||||
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS){
|
||||
TileEntity tileEntity = this.worldObj.getBlockTileEntity(side.offsetX + this.xCoord, side.offsetY + this.yCoord, side.offsetZ + this.zCoord);
|
||||
|
||||
/*
|
||||
* FIXME: make this support ISidedInvontory. That means forge's and vanilla's implementation
|
||||
* perhaps have this work with ISpecialInvenotry?
|
||||
*/
|
||||
|
||||
if (tileEntity instanceof IInventory){
|
||||
IInventory inventory = (IInventory) tileEntity;
|
||||
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++){
|
||||
ItemStack item = inventory.getStackInSlot(slot);
|
||||
|
||||
if (item != null){
|
||||
boolean refilAll = false;
|
||||
|
||||
for (int slot1 = 0; slot1 < this.getSizeInventory(); slot1++){
|
||||
ItemStack item1 = this.getStackInSlot(slot1);
|
||||
if (item1 != null && item1.stackSize == 1 && item.isItemEqual(item1)){
|
||||
item1.stackSize++;
|
||||
inventory.decrStackSize(slot, 1);
|
||||
|
||||
if (slot1 == this.getSizeInventory() - 1) refilAll = true;
|
||||
}else{
|
||||
refilAll = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (refilAll) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void craft(){
|
||||
for (int slot = 0; slot < this.getSizeInventory(); slot++){
|
||||
ItemStack item = this.getStackInSlot(slot);
|
||||
|
||||
if (item != null){
|
||||
this.decrStackSize(slot, 1);
|
||||
|
||||
if (item.getItem().hasContainerItem()){
|
||||
ItemStack item2 = item.getItem().getContainerItemStack(item);
|
||||
|
||||
return null;
|
||||
if (item2.isItemStackDamageable() && item2.getItemDamage() > item2.getMaxDamage()){
|
||||
this.worldObj.playSoundAtEntity(CoreProxy.proxy.getBuildCraftPlayer(worldObj, xCoord, yCoord, zCoord), "random.break", 0.8F,
|
||||
0.8F + this.worldObj.rand.nextFloat() * 0.4F);
|
||||
|
||||
item2 = null;
|
||||
}
|
||||
|
||||
this.crafting.setInventorySlotContents(slot, item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canCraft() {
|
||||
if (this.craftResult.getStackInSlot(0) == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < this.getSizeInventory(); slot++){
|
||||
ItemStack stack = this.getStackInSlot(slot);
|
||||
|
||||
if (stack != null && stack.stackSize <= 1){
|
||||
if (!stack.getItem().hasContainerItem()){
|
||||
ItemStack item = stack.getItem().getContainerItemStack(stack);
|
||||
|
||||
if (item == null || item.stackSize <= 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openChest() {
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
super.readFromNBT(nbt);
|
||||
|
||||
Utils.readStacksFromNBT(nbt, "stackList", this);
|
||||
this.onInventoryChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChest() {
|
||||
public void writeToNBT(NBTTagCompound nbt) {
|
||||
super.writeToNBT(nbt);
|
||||
|
||||
Utils.writeStacksToNBT(nbt, "stackList", this);
|
||||
}
|
||||
|
||||
/* ISPECIALINVENTORY */
|
||||
public void openChest() {}
|
||||
public void closeChest() {}
|
||||
|
||||
@Override
|
||||
public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) {
|
||||
return new TransactorRoundRobin(this).add(stack, from, doAdd).stackSize;
|
||||
|
@ -403,21 +245,34 @@ public class TileAutoWorkbench extends TileEntity implements ISpecialInventory {
|
|||
|
||||
@Override
|
||||
public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) {
|
||||
return new ItemStack[] { extractItem(doRemove, false) };
|
||||
ItemStack item = null;
|
||||
ItemStack result = this.craftResult.getStackInSlot(0);
|
||||
|
||||
if (result != null){
|
||||
if (!this.canCraft()){
|
||||
this.refilFromNeibour();
|
||||
|
||||
if (!this.canCraft()){
|
||||
return new ItemStack[0];
|
||||
}
|
||||
}
|
||||
|
||||
this.craft();
|
||||
item = result.copy();
|
||||
}else{
|
||||
return new ItemStack[0];
|
||||
}
|
||||
|
||||
return new ItemStack[] { item };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvNameLocalized()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
public boolean isInvNameLocalized(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStackValidForSlot(int i, ItemStack itemstack)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
public boolean isStackValidForSlot(int slot, ItemStack stack){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue