ACT needs to support recipes with variable outputs

For example, ChristmasCraft Gifts that use input item NBT to determine
the output item.
This commit is contained in:
CovertJaguar 2013-12-13 15:22:21 -08:00
parent d443f279a6
commit 35611e0bf7

View file

@ -265,7 +265,7 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
internalInventoryCrafting = new InternalInventoryCrafting(); internalInventoryCrafting = new InternalInventoryCrafting();
internalPlayer = new InternalPlayer(); internalPlayer = new InternalPlayer();
craftSlot = new SlotCrafting(internalPlayer, internalInventoryCrafting, craftResult, 0, 0, 0); craftSlot = new SlotCrafting(internalPlayer, internalInventoryCrafting, craftResult, 0, 0, 0);
updateCraftingResults(); updateRecipe();
} }
if (!CoreProxy.proxy.isSimulating(worldObj)) { if (!CoreProxy.proxy.isSimulating(worldObj)) {
return; return;
@ -273,25 +273,18 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
if (lastMode == ActionMachineControl.Mode.Off) { if (lastMode == ActionMachineControl.Mode.Off) {
return; return;
} }
updateCraftingResults(); updateRecipe();
findIngredients(); searchNeighborsForIngredients();
locateAndBindIngredients();
updateRecipeOutputDisplay();
justCrafted = false; justCrafted = false;
tick++; tick++;
tick = tick % recentEnergy.length; tick = tick % recentEnergy.length;
recentEnergy[tick] = 0.0f; recentEnergy[tick] = 0.0f;
if (craftResult.getStackInSlot(0) != null) { if (canCraftAndOutput()) {
internalInventoryCrafting.tempStacks = new InventoryCopy(storageSlots).getItemStacks(); if (storedEnergy >= getRequiredEnergy()) {
internalInventoryCrafting.hitCount = new int[internalInventoryCrafting.tempStacks.length]; craftItem();
if (hasIngredients() && InvUtils.isRoomForStack(craftResult.getStackInSlot(0), ForgeDirection.UP, invOutput)) { justCrafted = true;
if (storedEnergy >= getRequiredEnergy()) {
craftItem();
justCrafted = true;
}
} else {
craftable = false;
internalInventoryCrafting.tempStacks = null;
internalInventoryCrafting.hitCount = null;
storedEnergy = 0;
} }
} else { } else {
craftable = false; craftable = false;
@ -301,7 +294,18 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
} }
} }
private boolean hasIngredients() { private boolean canCraftAndOutput() {
if (!hasIngredients())
return false;
ItemStack output = getRecipeOutput();
if (output == null)
return false;
return InvUtils.isRoomForStack(output, ForgeDirection.UP, invOutput);
}
private void locateAndBindIngredients() {
internalInventoryCrafting.tempStacks = new InventoryCopy(storageSlots).getItemStacks();
internalInventoryCrafting.hitCount = new int[internalInventoryCrafting.tempStacks.length];
ItemStack[] tempStorage = internalInventoryCrafting.tempStacks; ItemStack[] tempStorage = internalInventoryCrafting.tempStacks;
for (int j = 0; j < craftingSlots.getSizeInventory(); j++) { for (int j = 0; j < craftingSlots.getSizeInventory(); j++) {
if (craftingSlots.getStackInSlot(j) == null) { if (craftingSlots.getStackInSlot(j) == null) {
@ -319,15 +323,18 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
break; break;
} }
} }
if (!matchedStorage) { if (!matchedStorage)
return false; return;
}
} }
return currentRecipe.matches(internalInventoryCrafting, worldObj); }
private boolean hasIngredients() {
return currentRecipe != null && currentRecipe.matches(internalInventoryCrafting, worldObj);
} }
private void craftItem() { private void craftItem() {
craftSlot.onPickupFromSlot(internalPlayer, craftResult.getStackInSlot(0)); ItemStack recipeOutput = getRecipeOutput();
craftSlot.onPickupFromSlot(internalPlayer, recipeOutput);
ItemStack[] tempStorage = internalInventoryCrafting.tempStacks; ItemStack[] tempStorage = internalInventoryCrafting.tempStacks;
for (int i = 0; i < tempStorage.length; i++) { for (int i = 0; i < tempStorage.length; i++) {
if (tempStorage[i] != null && tempStorage[i].stackSize <= 0) { if (tempStorage[i] != null && tempStorage[i].stackSize <= 0) {
@ -336,7 +343,7 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
storageSlots.getItemStacks()[i] = tempStorage[i]; storageSlots.getItemStacks()[i] = tempStorage[i];
} }
storedEnergy -= getRequiredEnergy(); storedEnergy -= getRequiredEnergy();
List<ItemStack> outputs = Lists.newArrayList(craftResult.getStackInSlot(0).copy()); List<ItemStack> outputs = Lists.newArrayList(recipeOutput.copy());
for (int i = 0; i < internalPlayer.inventory.mainInventory.length; i++) { for (int i = 0; i < internalPlayer.inventory.mainInventory.length; i++) {
if (internalPlayer.inventory.mainInventory[i] != null) { if (internalPlayer.inventory.mainInventory[i] != null) {
outputs.add(internalPlayer.inventory.mainInventory[i]); outputs.add(internalPlayer.inventory.mainInventory[i]);
@ -354,7 +361,7 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
} }
} }
private void findIngredients() { private void searchNeighborsForIngredients() {
if (cache == null) { if (cache == null) {
cache = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false); cache = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false);
} }
@ -380,14 +387,14 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
public void updateCraftingMatrix(int slot, ItemStack stack) { public void updateCraftingMatrix(int slot, ItemStack stack) {
craftingSlots.setInventorySlotContents(slot, stack); craftingSlots.setInventorySlotContents(slot, stack);
updateCraftingResults(); updateRecipe();
if (CoreProxy.proxy.isRenderWorld(worldObj)) { if (CoreProxy.proxy.isRenderWorld(worldObj)) {
PacketSlotChange packet = new PacketSlotChange(PacketIds.ADVANCED_WORKBENCH_SETSLOT, xCoord, yCoord, zCoord, slot, stack); PacketSlotChange packet = new PacketSlotChange(PacketIds.ADVANCED_WORKBENCH_SETSLOT, xCoord, yCoord, zCoord, slot, stack);
CoreProxy.proxy.sendToServer(packet.getPacket()); CoreProxy.proxy.sendToServer(packet.getPacket());
} }
} }
private void updateCraftingResults() { private void updateRecipe() {
if (internalInventoryCrafting == null) { if (internalInventoryCrafting == null) {
return; return;
} }
@ -395,16 +402,31 @@ public class TileAdvancedCraftingTable extends TileEntity implements IInventory,
if (this.currentRecipe == null || !this.currentRecipe.matches(internalInventoryCrafting, worldObj)) { if (this.currentRecipe == null || !this.currentRecipe.matches(internalInventoryCrafting, worldObj)) {
currentRecipe = CraftingHelper.findMatchingRecipe(internalInventoryCrafting, worldObj); currentRecipe = CraftingHelper.findMatchingRecipe(internalInventoryCrafting, worldObj);
} }
ItemStack resultStack = null;
if (currentRecipe != null) {
resultStack = currentRecipe.getCraftingResult(internalInventoryCrafting);
}
craftResult.setInventorySlotContents(0, resultStack);
internalInventoryCrafting.recipeUpdate(false); internalInventoryCrafting.recipeUpdate(false);
onInventoryChanged(); onInventoryChanged();
} }
private void updateRecipeOutputDisplay() {
if (internalInventoryCrafting == null || currentRecipe == null) {
return;
}
ItemStack resultStack = getRecipeOutput();
if (resultStack == null) {
internalInventoryCrafting.recipeUpdate(true);
resultStack = getRecipeOutput();
internalInventoryCrafting.recipeUpdate(false);
}
craftResult.setInventorySlotContents(0, resultStack);
onInventoryChanged();
}
private ItemStack getRecipeOutput() {
if (internalInventoryCrafting == null || currentRecipe == null) {
return null;
}
return currentRecipe.getCraftingResult(internalInventoryCrafting);
}
public IInventory getCraftingSlots() { public IInventory getCraftingSlots() {
return craftingSlots; return craftingSlots;
} }