2014-06-06 15:16:45 +00:00
package joshie.alchemicalWizardy ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.Iterator ;
import java.util.Map ;
import java.util.Map.Entry ;
import net.minecraft.block.Block ;
import net.minecraft.inventory.InventoryCrafting ;
import net.minecraft.item.Item ;
import net.minecraft.item.ItemStack ;
import net.minecraft.item.crafting.IRecipe ;
import net.minecraft.item.crafting.ShapedRecipes ;
import net.minecraft.world.World ;
import net.minecraftforge.oredict.OreDictionary ;
import WayofTime.alchemicalWizardry.api.items.interfaces.IBloodOrb ;
/** Shaped Blood Orb Recipe Handler by joshie **/
public class ShapedBloodOrbRecipe implements IRecipe {
private static final int MAX_CRAFT_GRID_WIDTH = 3 ;
private static final int MAX_CRAFT_GRID_HEIGHT = 3 ;
private ItemStack output = null ;
private Object [ ] input = null ;
2014-06-23 00:51:02 +00:00
public int width = 0 ;
public int height = 0 ;
2014-06-06 15:16:45 +00:00
private boolean mirrored = true ;
public ShapedBloodOrbRecipe ( Block result , Object . . . recipe ) {
this ( new ItemStack ( result ) , recipe ) ;
}
public ShapedBloodOrbRecipe ( Item result , Object . . . recipe ) {
this ( new ItemStack ( result ) , recipe ) ;
}
public ShapedBloodOrbRecipe ( ItemStack result , Object . . . recipe ) {
output = result . copy ( ) ;
String shape = " " ;
int idx = 0 ;
if ( recipe [ idx ] instanceof Boolean ) {
mirrored = ( Boolean ) recipe [ idx ] ;
if ( recipe [ idx + 1 ] instanceof Object [ ] ) {
recipe = ( Object [ ] ) recipe [ idx + 1 ] ;
} else {
idx = 1 ;
}
}
if ( recipe [ idx ] instanceof String [ ] ) {
String [ ] parts = ( ( String [ ] ) recipe [ idx + + ] ) ;
for ( String s : parts ) {
width = s . length ( ) ;
shape + = s ;
}
height = parts . length ;
} else {
while ( recipe [ idx ] instanceof String ) {
String s = ( String ) recipe [ idx + + ] ;
shape + = s ;
width = s . length ( ) ;
height + + ;
}
}
if ( width * height ! = shape . length ( ) ) {
String ret = " Invalid shaped ore recipe: " ;
for ( Object tmp : recipe ) {
ret + = tmp + " , " ;
}
ret + = output ;
throw new RuntimeException ( ret ) ;
}
HashMap < Character , Object > itemMap = new HashMap < Character , Object > ( ) ;
for ( ; idx < recipe . length ; idx + = 2 ) {
Character chr = ( Character ) recipe [ idx ] ;
Object in = recipe [ idx + 1 ] ;
if ( in instanceof IBloodOrb | | ( in instanceof ItemStack & & ( ( ItemStack ) in ) . getItem ( ) instanceof IBloodOrb ) ) { //If the item is an instanceof IBloodOrb then save the level of the orb
if ( in instanceof ItemStack ) itemMap . put ( chr , ( Integer ) ( ( ( IBloodOrb ) ( ( ItemStack ) in ) . getItem ( ) ) . getOrbLevel ( ) ) ) ;
else itemMap . put ( chr , ( Integer ) ( ( ( IBloodOrb ) in ) . getOrbLevel ( ) ) ) ;
} else if ( in instanceof ItemStack ) {
itemMap . put ( chr , ( ( ItemStack ) in ) . copy ( ) ) ;
} else if ( in instanceof Item ) {
itemMap . put ( chr , new ItemStack ( ( Item ) in ) ) ;
} else if ( in instanceof Block ) {
itemMap . put ( chr , new ItemStack ( ( Block ) in , 1 , OreDictionary . WILDCARD_VALUE ) ) ;
} else if ( in instanceof String ) {
itemMap . put ( chr , OreDictionary . getOres ( ( String ) in ) ) ;
} else {
String ret = " Invalid shaped ore recipe: " ;
for ( Object tmp : recipe ) {
ret + = tmp + " , " ;
}
ret + = output ;
throw new RuntimeException ( ret ) ;
}
}
input = new Object [ width * height ] ;
int x = 0 ;
for ( char chr : shape . toCharArray ( ) ) {
input [ x + + ] = itemMap . get ( chr ) ;
}
}
ShapedBloodOrbRecipe ( ShapedRecipes recipe , Map < ItemStack , String > replacements ) {
output = recipe . getRecipeOutput ( ) ;
width = recipe . recipeWidth ;
height = recipe . recipeHeight ;
input = new Object [ recipe . recipeItems . length ] ;
for ( int i = 0 ; i < input . length ; i + + ) {
ItemStack ingred = recipe . recipeItems [ i ] ;
if ( ingred = = null )
continue ;
input [ i ] = recipe . recipeItems [ i ] ;
for ( Entry < ItemStack , String > replace : replacements . entrySet ( ) ) {
if ( OreDictionary . itemMatches ( replace . getKey ( ) , ingred , true ) ) {
input [ i ] = OreDictionary . getOres ( replace . getValue ( ) ) ;
break ;
}
}
}
}
@Override
public ItemStack getCraftingResult ( InventoryCrafting var1 ) {
return output . copy ( ) ;
}
@Override
public int getRecipeSize ( ) {
return input . length ;
}
@Override
public ItemStack getRecipeOutput ( ) {
return output ;
}
@Override
public boolean matches ( InventoryCrafting inv , World world ) {
for ( int x = 0 ; x < = MAX_CRAFT_GRID_WIDTH - width ; x + + ) {
for ( int y = 0 ; y < = MAX_CRAFT_GRID_HEIGHT - height ; + + y ) {
if ( checkMatch ( inv , x , y , false ) ) {
return true ;
}
if ( mirrored & & checkMatch ( inv , x , y , true ) ) {
return true ;
}
}
}
return false ;
}
@SuppressWarnings ( " unchecked " )
private boolean checkMatch ( InventoryCrafting inv , int startX , int startY , boolean mirror ) {
for ( int x = 0 ; x < MAX_CRAFT_GRID_WIDTH ; x + + ) {
for ( int y = 0 ; y < MAX_CRAFT_GRID_HEIGHT ; y + + ) {
int subX = x - startX ;
int subY = y - startY ;
Object target = null ;
if ( subX > = 0 & & subY > = 0 & & subX < width & & subY < height ) {
if ( mirror ) {
target = input [ width - subX - 1 + subY * width ] ;
} else {
target = input [ subX + subY * width ] ;
}
}
ItemStack slot = inv . getStackInRowAndColumn ( x , y ) ;
//If target is integer, then we should be check the blood orb value of the item instead
if ( target instanceof Integer ) {
if ( slot ! = null & & slot . getItem ( ) instanceof IBloodOrb ) {
IBloodOrb orb = ( IBloodOrb ) slot . getItem ( ) ;
if ( orb . getOrbLevel ( ) < ( Integer ) target ) {
return false ;
}
} else return false ;
} else if ( target instanceof ItemStack ) {
if ( ! OreDictionary . itemMatches ( ( ItemStack ) target , slot , false ) ) {
return false ;
}
} else if ( target instanceof ArrayList ) {
boolean matched = false ;
Iterator < ItemStack > itr = ( ( ArrayList < ItemStack > ) target ) . iterator ( ) ;
while ( itr . hasNext ( ) & & ! matched ) {
matched = OreDictionary . itemMatches ( itr . next ( ) , slot , false ) ;
}
if ( ! matched ) {
return false ;
}
} else if ( target = = null & & slot ! = null ) {
return false ;
}
}
}
return true ;
}
public ShapedBloodOrbRecipe setMirrored ( boolean mirror ) {
mirrored = mirror ;
return this ;
}
public Object [ ] getInput ( ) {
return this . input ;
}
}