Fixed Harvest sigil in armour giving bad items

Finished optimization of compression handler.
This commit is contained in:
WayofTime 2015-03-11 19:19:17 -04:00
parent e21f6941ba
commit d7d8aedd42
8 changed files with 259 additions and 117 deletions

View file

@ -1,5 +1,5 @@
# #
#Tue Mar 03 18:39:06 EST 2015 #Wed Mar 04 17:54:09 EST 2015
mod_name=BloodMagic mod_name=BloodMagic
forge_version=10.13.2.1232 forge_version=10.13.2.1232
ccc_version=1.0.4.29 ccc_version=1.0.4.29
@ -8,5 +8,5 @@ nei_version=1.0.3.64
package_group=com.wayoftime.bloodmagic package_group=com.wayoftime.bloodmagic
mod_version=1.3.1 mod_version=1.3.1
minetweaker_version=Dev-1.7.10-3.0.9B minetweaker_version=Dev-1.7.10-3.0.9B
build_number=7
mc_version=1.7.10 mc_version=1.7.10
build_number=8

View file

@ -9,11 +9,7 @@ import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper; import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
public class StorageBlockCraftingManager public class StorageBlockCraftingManager
@ -28,96 +24,97 @@ public class StorageBlockCraftingManager
public void addStorageBlockRecipes() public void addStorageBlockRecipes()
{ {
this.recipes = new StorageBlockCraftingRecipeAssimilator().getPackingOptions(); this.recipes = new StorageBlockCraftingRecipeAssimilator().getPackingRecipes();
List<IRecipe> tempRecipeList = new LinkedList(); System.out.println("Total number of compression recipes: " + this.recipes.size());
// List<IRecipe> tempRecipeList = new LinkedList();
World world = DimensionManager.getWorld(0); //
// World world = DimensionManager.getWorld(0);
for(Object obj : this.recipes) //
{ // for(Object obj : this.recipes)
if(obj instanceof IRecipe) // {
{ // if(obj instanceof IRecipe)
IRecipe recipe = (IRecipe)obj; // {
ItemStack outputStack = recipe.getRecipeOutput(); // IRecipe recipe = (IRecipe)obj;
if(outputStack == null || outputStack.getItem() == null) // ItemStack outputStack = recipe.getRecipeOutput();
{ // if(outputStack == null || outputStack.getItem() == null)
continue; // {
} // continue;
// }
if(recipe instanceof ShapedRecipes) //
{ // if(recipe instanceof ShapedRecipes)
ShapedRecipes sRecipe = (ShapedRecipes)recipe; // {
ItemStack[] input = sRecipe.recipeItems; // ShapedRecipes sRecipe = (ShapedRecipes)recipe;
// ItemStack[] input = sRecipe.recipeItems;
if(outputStack.stackSize == 1 && (input.length == 9 || input.length == 4)) //
{ // if(outputStack.stackSize == 1 && (input.length == 9 || input.length == 4))
tempRecipeList.add(recipe); // {
}else if((outputStack.stackSize == 9 || outputStack.stackSize == 4) && input.length == 1) // tempRecipeList.add(recipe);
{ // }else if((outputStack.stackSize == 9 || outputStack.stackSize == 4) && input.length == 1)
tempRecipeList.add(recipe); // {
} // tempRecipeList.add(recipe);
} // }
else if(recipe instanceof ShapelessRecipes) // }
{ // else if(recipe instanceof ShapelessRecipes)
ShapelessRecipes sRecipe = (ShapelessRecipes)recipe; // {
List input = sRecipe.recipeItems; // ShapelessRecipes sRecipe = (ShapelessRecipes)recipe;
// List input = sRecipe.recipeItems;
if(outputStack.stackSize == 1 && (input.size() == 9 || input.size() == 4)) //
{ // if(outputStack.stackSize == 1 && (input.size() == 9 || input.size() == 4))
Object obj1 = input.get(0); // {
if(obj1 != null) // Object obj1 = input.get(0);
{ // if(obj1 != null)
boolean allMatch = true; // {
for(Object obj2 : input) // boolean allMatch = true;
{ // for(Object obj2 : input)
if(obj2 == null || !obj2.equals(obj1)) // {
{ // if(obj2 == null || !obj2.equals(obj1))
allMatch = false; // {
break; // allMatch = false;
} // break;
} // }
if(allMatch) // }
{ // if(allMatch)
tempRecipeList.add(recipe); // {
} // tempRecipeList.add(recipe);
} // }
// }
}else if((outputStack.stackSize == 9 || outputStack.stackSize == 4) && input.size() == 1) //
{ // }else if((outputStack.stackSize == 9 || outputStack.stackSize == 4) && input.size() == 1)
tempRecipeList.add(recipe); // {
} // tempRecipeList.add(recipe);
} // }
else if((outputStack.stackSize == 1 && (recipe.getRecipeSize() == 9 || recipe.getRecipeSize() == 4)) || ((outputStack.stackSize == 9 || outputStack.stackSize == 4) && recipe.getRecipeSize() == 1)) // }
{ // else if((outputStack.stackSize == 1 && (recipe.getRecipeSize() == 9 || recipe.getRecipeSize() == 4)) || ((outputStack.stackSize == 9 || outputStack.stackSize == 4) && recipe.getRecipeSize() == 1))
tempRecipeList.add(recipe); // {
continue; // tempRecipeList.add(recipe);
} // continue;
} // }
} // }
// }
List<IRecipe> tempRecipeList2 = new LinkedList(); //
// List<IRecipe> tempRecipeList2 = new LinkedList();
for(Object obj : tempRecipeList) //
{ // for(Object obj : tempRecipeList)
if(obj instanceof IRecipe) // {
{ // if(obj instanceof IRecipe)
IRecipe recipe = (IRecipe)obj; // {
ItemStack outputStack = recipe.getRecipeOutput(); // IRecipe recipe = (IRecipe)obj;
if(outputStack == null || outputStack.getItem() == null) // ItemStack outputStack = recipe.getRecipeOutput();
{ // if(outputStack == null || outputStack.getItem() == null)
continue; // {
} // continue;
// }
if(isResultStackReversible(outputStack, 2, world, tempRecipeList) || isResultStackReversible(outputStack, 3, world, tempRecipeList)) //
{ // if(isResultStackReversible(outputStack, 2, world, tempRecipeList) || isResultStackReversible(outputStack, 3, world, tempRecipeList))
tempRecipeList2.add(recipe); // {
AlchemicalWizardry.logger.info("Now adding recipe for " + outputStack + " to the compression handler."); // tempRecipeList2.add(recipe);
} // AlchemicalWizardry.logger.info("Now adding recipe for " + outputStack + " to the compression handler.");
} // }
} // }
// }
this.recipes = tempRecipeList2; //
// this.recipes = tempRecipeList2;
} }
private static boolean isResultStackReversible(ItemStack stack, int gridSize, World world, List list) private static boolean isResultStackReversible(ItemStack stack, int gridSize, World world, List list)

View file

@ -3,42 +3,119 @@ package WayofTime.alchemicalWizardry.common.compress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container; import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe;
public class StorageBlockCraftingRecipeAssimilator public class StorageBlockCraftingRecipeAssimilator {
{ public List<IRecipe> getPackingRecipes() {
public List<IRecipe> getPackingOptions() // grab all recipes potentially suitable for packing or unpacking
{
List<IRecipe> packingRecipes = new ArrayList<IRecipe>(); List<PackingRecipe> packingRecipes = new LinkedList<PackingRecipe>();
List<IRecipe> unpackingRecipes = new ArrayList<IRecipe>(); List<IRecipe> unpackingRecipes = new ArrayList<IRecipe>();
List<IRecipe> returnedRecipes = new ArrayList();
for (IRecipe recipe : getCraftingRecipes()) { for (IRecipe recipe : getCraftingRecipes()) {
ItemStack output = recipe.getRecipeOutput(); ItemStack output = recipe.getRecipeOutput();
if (output == null || output.getItem() == null) continue; if (output == null || output.getItem() == null) continue;
if (output.stackSize == 1 && isPossiblePackingRecipe(recipe)) { if (output.stackSize == 1) {
packingRecipes.add(recipe); PackingRecipe packingRecipe = getPackingRecipe(recipe);
if (packingRecipe != null) {
packingRecipes.add(packingRecipe);
}
} else if ((output.stackSize == 4 || output.stackSize == 9) && recipe.getRecipeSize() == 1) { } else if ((output.stackSize == 4 || output.stackSize == 9) && recipe.getRecipeSize() == 1) {
unpackingRecipes.add(recipe); unpackingRecipes.add(recipe);
} }
} }
packingRecipes.addAll(unpackingRecipes); // grab all packing recipes which accept the output of any of the unpacking recipes
return packingRecipes; Container container = makeDummyContainer();
InventoryCrafting inventoryUnpack = new InventoryCrafting(container, 2, 2);
InventoryCrafting inventory2x2 = new InventoryCrafting(container, 2, 2);
InventoryCrafting inventory3x3 = new InventoryCrafting(container, 3, 3);
World world = null; // TODO: use a proper dummy world?
List<IRecipe> ret = new ArrayList<IRecipe>();
for (IRecipe recipeUnpack : unpackingRecipes) {
ItemStack unpacked = recipeUnpack.getRecipeOutput();
InventoryCrafting inventory = null;
for (Iterator<PackingRecipe> it = packingRecipes.iterator(); it.hasNext(); ) {
PackingRecipe recipePack = it.next();
// check if the packing recipe accepts the unpacking recipe's output
boolean matched = false;
if (recipePack.possibleInputs != null) { // the recipe could be parsed, use its inputs directly since that's faster
// verify recipe size
if (recipePack.inputCount != unpacked.stackSize) continue;
// check if any of the input options matches the unpacked item stack
for (ItemStack stack : recipePack.possibleInputs) {
if (areInputsIdentical(unpacked, stack)) {
matched = true;
break;
}
}
} else { // unknown IRecipe, check through the recipe conventionally
// verify recipe size for 3x3 to skip anything smaller quickly
if (unpacked.stackSize == 9 && recipePack.recipe.getRecipeSize() < 9) continue;
// initialize inventory late, but only once per unpack recipe
if (inventory == null) {
if (unpacked.stackSize == 4) {
inventory = inventory2x2;
} else {
inventory = inventory3x3;
}
for (int i = 0; i < unpacked.stackSize; i++) {
inventory.setInventorySlotContents(i, unpacked.copy());
}
}
// check if the packing recipe accepts the unpacked item stack
matched = recipePack.recipe.matches(inventory, world);
}
if (matched) {
// check if the unpacking recipe accepts the packing recipe's output
ItemStack packOutput = recipePack.recipe.getRecipeOutput();
inventoryUnpack.setInventorySlotContents(0, packOutput.copy());
if (recipeUnpack.matches(inventoryUnpack, world)) {
ret.add(recipePack.recipe);
AlchemicalWizardry.logger.info("Adding the following recipe to the Compression Handler: " + packOutput);
it.remove();
}
}
}
}
return ret;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -55,8 +132,8 @@ public class StorageBlockCraftingRecipeAssimilator
}; };
} }
private boolean isPossiblePackingRecipe(IRecipe recipe) { private PackingRecipe getPackingRecipe(IRecipe recipe) {
if (recipe.getRecipeSize() < 4) return false; if (recipe.getRecipeSize() < 4) return null;
List<?> inputs; List<?> inputs;
@ -69,14 +146,35 @@ public class StorageBlockCraftingRecipeAssimilator
} else if (recipe instanceof ShapelessOreRecipe) { } else if (recipe instanceof ShapelessOreRecipe) {
inputs = ((ShapelessOreRecipe) recipe).getInput(); inputs = ((ShapelessOreRecipe) recipe).getInput();
} else { } else {
return true; return new PackingRecipe(recipe, null, -1);
} }
return areInputsIdentical(inputs); // check if the recipe inputs are size 4 or 9
int count = 0;
for (Object o : inputs) {
if (o != null) count++;
}
if (count != 4 && count != 9) return null;
// grab identical inputs
List<ItemStack> identicalInputs = getIdenticalInputs(inputs);
if (identicalInputs == null) return null;
return new PackingRecipe(recipe, identicalInputs, count);
} }
/**
* Determine the item stacks from the provided inputs which are suitable for every input element.
*
* @param inputs List of all inputs, null elements are being ignored.
* @return List List of all options.
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private boolean areInputsIdentical(List<?> inputs) { private List<ItemStack> getIdenticalInputs(List<?> inputs) {
List<ItemStack> options = null; List<ItemStack> options = null;
for (Object input : inputs) { for (Object input : inputs) {
@ -89,7 +187,7 @@ public class StorageBlockCraftingRecipeAssimilator
} else if (input instanceof List) { } else if (input instanceof List) {
offers = (List<ItemStack>) input; offers = (List<ItemStack>) input;
if (offers.isEmpty()) return false; if (offers.isEmpty()) return null;
} else { } else {
throw new RuntimeException("invalid input: "+input.getClass()); throw new RuntimeException("invalid input: "+input.getClass());
} }
@ -113,12 +211,12 @@ public class StorageBlockCraftingRecipeAssimilator
if (!found) { if (!found) {
it.remove(); it.remove();
if (options.isEmpty()) return false; if (options.isEmpty()) return null;
} }
} }
} }
return true; return options;
} }
private boolean areInputsIdentical(ItemStack a, ItemStack b) { private boolean areInputsIdentical(ItemStack a, ItemStack b) {
@ -129,4 +227,16 @@ public class StorageBlockCraftingRecipeAssimilator
return dmgA == dmgB || dmgA == OreDictionary.WILDCARD_VALUE || dmgB == OreDictionary.WILDCARD_VALUE; return dmgA == dmgB || dmgA == OreDictionary.WILDCARD_VALUE || dmgB == OreDictionary.WILDCARD_VALUE;
} }
private static class PackingRecipe {
PackingRecipe(IRecipe recipe, List<ItemStack> possibleInputs, int inputCount) {
this.recipe = recipe;
this.possibleInputs = possibleInputs;
this.inputCount = inputCount;
}
final IRecipe recipe;
final List<ItemStack> possibleInputs;
final int inputCount;
}
} }

View file

@ -106,7 +106,7 @@ public class BoundAxe extends ItemAxe implements IBindable
@Override @Override
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{ {
if (EnergyItems.checkAndSetItemOwner(par1ItemStack, par3EntityPlayer) || par3EntityPlayer.isSneaking()) if (!EnergyItems.checkAndSetItemOwner(par1ItemStack, par3EntityPlayer) || par3EntityPlayer.isSneaking())
{ {
this.setActivated(par1ItemStack, !getActivated(par1ItemStack)); this.setActivated(par1ItemStack, !getActivated(par1ItemStack));
par1ItemStack.getTagCompound().setInteger("worldTimeDelay", (int) (par2World.getWorldTime() - 1) % 200); par1ItemStack.getTagCompound().setInteger("worldTimeDelay", (int) (par2World.getWorldTime() - 1) % 200);

View file

@ -49,6 +49,7 @@ public class ItemBloodLightSigil extends EnergyItems implements IHolding
@Override @Override
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{ {
System.out.println("Being called");
if(!EnergyItems.checkAndSetItemOwner(par1ItemStack, par2EntityPlayer) || !EnergyItems.syphonBatteries(par1ItemStack, par2EntityPlayer, getEnergyUsed())) if(!EnergyItems.checkAndSetItemOwner(par1ItemStack, par2EntityPlayer) || !EnergyItems.syphonBatteries(par1ItemStack, par2EntityPlayer, getEnergyUsed()))
{ {
return true; return true;

View file

@ -185,6 +185,10 @@ public class ItemHarvestSigil extends EnergyItems implements IHolding, ArmourUpg
@Override @Override
public void onArmourUpdate(World world, EntityPlayer player, ItemStack thisItemStack) public void onArmourUpdate(World world, EntityPlayer player, ItemStack thisItemStack)
{ {
if(world.isRemote)
{
return;
}
int range = 3; int range = 3;
int verticalRange = 1; int verticalRange = 1;
int posX = (int) Math.round(player.posX - 0.5f); int posX = (int) Math.round(player.posX - 0.5f);

View file

@ -171,6 +171,10 @@ public class ItemPackRatSigil extends EnergyItems implements IHolding, ArmourUpg
@Override @Override
public void onArmourUpdate(World world, EntityPlayer player, ItemStack thisItemStack) public void onArmourUpdate(World world, EntityPlayer player, ItemStack thisItemStack)
{ {
if(world.isRemote)
{
return;
}
ItemStack stack = CompressionRegistry.compressInventory(player.inventory.mainInventory, world); ItemStack stack = CompressionRegistry.compressInventory(player.inventory.mainInventory, world);
if(stack != null) if(stack != null)
{ {

View file

@ -95,11 +95,37 @@ public class SigilOfHolding extends EnergyItems
} }
} }
} }
@Override
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (checkAndSetItemOwner(par1ItemStack, par2EntityPlayer))
{
int currentSlot = this.getSelectedSlot(par1ItemStack);
ItemStack[] inv = getInternalInventory(par1ItemStack);
if (inv == null)
{
return false;
}
ItemStack itemUsed = inv[currentSlot];
if (itemUsed == null)
{
return false;
}
itemUsed.getItem().onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10);
saveInternalInventory(par1ItemStack, inv);
}
return true;
}
@Override @Override
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{ {
//TODO Might be a good idea to have this item need to be in the player's first slot
if (checkAndSetItemOwner(par1ItemStack, par3EntityPlayer)) if (checkAndSetItemOwner(par1ItemStack, par3EntityPlayer))
{ {
if (par3EntityPlayer.isSneaking()) if (par3EntityPlayer.isSneaking())