Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package WayofTime.alchemicalWizardry.api.alchemy;

import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

public class AlchemyRecipe {

public static final int MAX_INPUT_SLOTS = 5;

private final ItemStack output;
private final ItemStack[] recipe;
private final int bloodOrbLevel;
Expand All @@ -19,87 +20,75 @@ public AlchemyRecipe(ItemStack output, int amountNeeded, ItemStack[] recipe, int
}

public boolean doesRecipeMatch(ItemStack[] items, int slottedBloodOrbLevel) {
return getSlotUsage(items, slottedBloodOrbLevel) != null;
}

/**
* Matches the recipe against the input slots and returns how many items have to be taken from each slot, or null if
* the recipe does not match. Duplicate ingredients may come from a single slot holding a large enough stack, and
* every non-empty slot has to be part of the recipe.
*/
public int[] getSlotUsage(ItemStack[] items, int slottedBloodOrbLevel) {
if (slottedBloodOrbLevel < bloodOrbLevel) {
return false;
return null;
}

ItemStack[] recipe;

if (items.length < 5) {
return false;
if (items.length < MAX_INPUT_SLOTS) {
return null;
}

if (this.recipe.length != 5) {
ItemStack[] newRecipe = new ItemStack[5];
int[] usage = new int[MAX_INPUT_SLOTS];

for (int i = 0; i < 5; i++) {
if (i + 1 > this.recipe.length) {
newRecipe[i] = null;
} else {
newRecipe[i] = this.recipe[i];
// ponytail: wildcard ingredients are assigned last so they cannot steal a slot an exact ingredient needs.
// A full assignment search would only be needed for ingredients overlapping in more complex ways.
for (int pass = 0; pass < 2; pass++) {
for (ItemStack ingredient : recipe) {
if (ingredient == null) {
continue;
}
}

recipe = newRecipe;
} else {
recipe = this.recipe;
}

boolean[] checkList = new boolean[5];

for (int i = 0; i < 5; i++) {
checkList[i] = false;
}

for (int i = 0; i < 5; i++) {
ItemStack recipeItemStack = recipe[i];

if (recipeItemStack == null) {
continue;
}

boolean test = false;
boolean isWildcard = ingredient.getItemDamage() == OreDictionary.WILDCARD_VALUE;

for (int j = 0; j < 5; j++) {
if (checkList[j]) {
if (isWildcard != (pass == 1)) {
continue;
}

ItemStack checkedItemStack = items[j];

if (checkedItemStack == null) {
continue;
if (!assignIngredient(items, usage, ingredient)) {
return null;
}
}
}

boolean quickTest = false;
for (int i = 0; i < MAX_INPUT_SLOTS; i++) {
if (items[i] != null && usage[i] == 0) {
return null;
}
}

if (recipeItemStack.getItem() instanceof ItemBlock) {
if (checkedItemStack.getItem() instanceof ItemBlock) {
quickTest = true;
}
} else if (!(checkedItemStack.getItem() instanceof ItemBlock)) {
quickTest = true;
}
return usage;
}

if (!quickTest) {
continue;
}
private static boolean assignIngredient(ItemStack[] items, int[] usage, ItemStack ingredient) {
for (int i = 0; i < MAX_INPUT_SLOTS; i++) {
ItemStack slotStack = items[i];

if ((checkedItemStack.getItemDamage() == recipeItemStack.getItemDamage()
|| OreDictionary.WILDCARD_VALUE == recipeItemStack.getItemDamage())
&& checkedItemStack.getItem() == recipeItemStack.getItem()) {
test = true;
checkList[j] = true;
break;
}
if (slotStack == null || slotStack.stackSize - usage[i] <= 0) {
continue;
}

if (!test) {
return false;
if (matches(slotStack, ingredient)) {
usage[i]++;
return true;
}
}

return true;
return false;
}

private static boolean matches(ItemStack slotStack, ItemStack ingredient) {
return slotStack.getItem() == ingredient.getItem()
&& (ingredient.getItemDamage() == OreDictionary.WILDCARD_VALUE
|| slotStack.getItemDamage() == ingredient.getItemDamage());
}

public ItemStack getResult() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static void registerRecipe(ItemStack output, int amountNeeded, ItemStack[
recipes.add(new AlchemyRecipe(output, amountNeeded, recipe, bloodOrbLevel));
}

public static ItemStack getResult(ItemStack[] recipe, ItemStack bloodOrb) {
public static AlchemyRecipe findRecipe(ItemStack[] recipe, ItemStack bloodOrb) {
if (bloodOrb == null) {
return null;
}
Expand All @@ -28,31 +28,23 @@ public static ItemStack getResult(ItemStack[] recipe, ItemStack bloodOrb) {

for (AlchemyRecipe ar : recipes) {
if (ar.doesRecipeMatch(recipe, bloodOrbLevel)) {
return (ar.getResult());
return ar;
}
}

return null;
}

public static int getAmountNeeded(ItemStack[] recipe, ItemStack bloodOrb) {
if (bloodOrb == null) {
return 0;
}

if (!(bloodOrb.getItem() instanceof IBloodOrb)) {
return 0;
}
public static ItemStack getResult(ItemStack[] recipe, ItemStack bloodOrb) {
AlchemyRecipe ar = findRecipe(recipe, bloodOrb);

int bloodOrbLevel = ((IBloodOrb) bloodOrb.getItem()).getOrbLevel();
return ar == null ? null : ar.getResult();
}

for (AlchemyRecipe ar : recipes) {
if (ar.doesRecipeMatch(recipe, bloodOrbLevel)) {
return (ar.getAmountNeeded());
}
}
public static int getAmountNeeded(ItemStack[] recipe, ItemStack bloodOrb) {
AlchemyRecipe ar = findRecipe(recipe, bloodOrb);

return 0;
return ar == null ? 0 : ar.getAmountNeeded();
}

public static ItemStack[] getRecipeForItemStack(ItemStack itemStack) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.OreDictionary;

import WayofTime.alchemicalWizardry.ModItems;
import WayofTime.alchemicalWizardry.api.alchemy.AlchemicalPotionCreationHandler;
Expand Down Expand Up @@ -582,11 +581,7 @@ public void updateEntity() {
progress = 0;
this.setInventorySlotContents(6, getResultingItemStack());

ItemStack[] composedRecipe = new ItemStack[5];

System.arraycopy(inv, 1, composedRecipe, 0, 5);

this.decrementSlots(this.getRecipeForItems(composedRecipe, inv[0]));
this.consumeIngredients();

if (worldObj != null) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
Expand Down Expand Up @@ -623,11 +618,7 @@ && getResultingItemStack().stackSize
result.stackSize += getStackInSlot(6).stackSize;
this.setInventorySlotContents(6, result);

ItemStack[] composedRecipe = new ItemStack[5];

System.arraycopy(inv, 1, composedRecipe, 0, 5);

this.decrementSlots(this.getRecipeForItems(composedRecipe, inv[0]));
this.consumeIngredients();

if (worldObj != null) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
Expand All @@ -637,54 +628,40 @@ && getResultingItemStack().stackSize
}
}

public void decrementSlots(ItemStack[] recipe) {
boolean[] decrementedList = new boolean[] { false, false, false, false, false };
public void consumeIngredients() {
ItemStack[] composedRecipe = new ItemStack[AlchemyRecipe.MAX_INPUT_SLOTS];

for (int i = 0; i < (Math.min(recipe.length, 5)); i++) {
ItemStack decStack = recipe[i];
System.arraycopy(inv, 1, composedRecipe, 0, AlchemyRecipe.MAX_INPUT_SLOTS);

if (decStack == null) {
continue;
}
AlchemyRecipe recipe = AlchemyRecipeRegistry.findRecipe(composedRecipe, inv[0]);

for (int j = 0; j < 5; j++) {
ItemStack testStack = this.getStackInSlot(j + 1);

if (testStack != null
&& (testStack.isItemEqual(decStack) || (testStack.getItem() == decStack.getItem()
&& decStack.getItemDamage() == OreDictionary.WILDCARD_VALUE))
&& !(decrementedList[j])) {
if (testStack.getItem() != null && testStack.getItem().hasContainerItem(testStack)) {
this.inv[j + 1] = testStack.getItem().getContainerItem(testStack);
} else {
this.decrStackSize(j + 1, 1);
}

decrementedList[j] = true;
break;
}
}
if (recipe == null) {
return;
}
}

public ItemStack[] getRecipeForItems(ItemStack[] recipe, ItemStack bloodOrb) {
if (bloodOrb == null) {
return null;
}
int[] usage = recipe.getSlotUsage(composedRecipe, ((IBloodOrb) inv[0].getItem()).getOrbLevel());

if (!(bloodOrb.getItem() instanceof IBloodOrb)) {
return null;
if (usage == null) {
return;
}

int bloodOrbLevel = ((IBloodOrb) bloodOrb.getItem()).getOrbLevel();
for (int i = 0; i < usage.length; i++) {
if (usage[i] <= 0) {
continue;
}

ItemStack slotStack = this.getStackInSlot(i + 1);

for (AlchemyRecipe ar : AlchemyRecipeRegistry.recipes) {
if (ar.doesRecipeMatch(recipe, bloodOrbLevel)) {
return ar.getRecipe();
if (slotStack == null) {
continue;
}
}

return null;
if (slotStack.getItem().hasContainerItem(slotStack) && slotStack.stackSize == usage[i]) {
this.inv[i + 1] = slotStack.getItem().getContainerItem(slotStack);
} else {
this.decrStackSize(i + 1, usage[i]);
}
}
}

public int getSpeedIncrease() {
Expand Down