package cyano.basemetals.items;
import cyano.basemetals.BaseMetals;
import cyano.basemetals.init.Achievements;
import cyano.basemetals.init.Materials;
import cyano.basemetals.material.IMetalObject;
import cyano.basemetals.material.MetalMaterial;
import cyano.basemetals.registry.CrusherRecipeRegistry;
import cyano.basemetals.registry.recipe.ICrusherRecipe;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.*;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ItemMetalCrackHammer extends ItemTool implements IMetalObject {
private static final float attack_speed = -3.0F;
protected final MetalMaterial metal;
protected final Set<String> toolTypes;
protected final String repairOreDictName;
protected final boolean regenerates;
protected final long regenInterval = 200;
public ItemMetalCrackHammer(MetalMaterial metal) {
super(1 + Materials.getToolMaterialFor(metal).getDamageVsEntity(),attack_speed, Materials.getToolMaterialFor(metal), new HashSet<Block>());
this.metal = metal;
this.damageVsEntity = 5F + 2F * metal.getBaseAttackDamage();
this.attackSpeed = -3.5F;
this.setMaxDamage((int)(0.75 * metal.getToolDurability()));
this.efficiencyOnProperMaterial = metal.getToolEfficiency();
this.toolTypes = new HashSet<>();
toolTypes.add("crackhammer");
toolTypes.add("pickaxe");
repairOreDictName = "ingot"+metal.getCapitalizedName();
if(metal.equals(Materials.starsteel)){
regenerates = true;
} else {
regenerates = false;
}
}
@Override
public float getStrVsBlock(final ItemStack tool, final IBlockState target) {
if(isCrushableBlock(target) && canHarvestBlock(target) ){
return Math.max(1.0f, 0.5f * this.metal.getToolEfficiency());
}
return 1.0f;
}
@Override
public boolean onBlockDestroyed(final ItemStack tool, final World world,
final IBlockState target, final BlockPos coord, final EntityLivingBase player) {
if(!world.isRemote && this.canHarvestBlock(target)){
IBlockState bs = world.getBlockState(coord);
ICrusherRecipe recipe = getCrusherRecipe(bs);
if(recipe != null){
ItemStack output = recipe.getOutput().copy();
world.setBlockToAir(coord);
if(output != null){
int num = output.stackSize;
output.stackSize = 1;
for(int i = 0; i < num; i++){
world.spawnEntityInWorld(new EntityItem(world, coord.getX()+0.5, coord.getY()+0.5, coord.getZ()+0.5, output.copy()));
}
}
}
}
return super.onBlockDestroyed(tool, world, target, coord, player);
}
@Override
public EnumActionResult onItemUse(final ItemStack item, final EntityPlayer player, final World w,
final BlockPos coord, EnumHand hand, final EnumFacing facing,
final float partialX, final float partialY, final float partialZ) {
if(facing != EnumFacing.UP) return EnumActionResult.PASS;
List<EntityItem> entities = w.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(
coord.getX(),coord.getY()+1,coord.getZ(),
coord.getX()+1,coord.getY()+2,coord.getZ()+1));
boolean success = false;
for(EntityItem target : entities){
ItemStack targetItem = ((net.minecraft.entity.item.EntityItem)target).getEntityItem();
if(targetItem != null ){
ICrusherRecipe recipe = CrusherRecipeRegistry.getInstance().getRecipeForInputItem(targetItem);
if(recipe != null){
// hardness check
if(BaseMetals.enforceHardness){
if(targetItem.getItem() instanceof ItemBlock){
Block b = ((ItemBlock)targetItem.getItem()).getBlock();
if(!this.canHarvestBlock(b.getStateFromMeta(targetItem.getMetadata()))){
// cannot harvest the block, no crush for you!
return EnumActionResult.PASS;
}
}
}
// crush the item (server side only)
if(!w.isRemote) {
ItemStack output = recipe.getOutput().copy();
int count = output.stackSize;
output.stackSize = 1;
double x = target.posX;
double y = target.posY;
double z = target.posZ;
targetItem.stackSize--;
if (targetItem.stackSize <= 0) {
w.removeEntity(target);
}
for (int i = 0; i < count; i++) {
w.spawnEntityInWorld(new EntityItem(w, x, y, z, output.copy()));
}
item.damageItem(1, player);
}
success = true;
break;
}
}
}
if(success){
w.playSound(player, coord, SoundEvents.BLOCK_GRAVEL_BREAK, SoundCategory.BLOCKS, 0.5F, 0.5F + (itemRand.nextFloat() * 0.3F));
}
return success ? EnumActionResult.SUCCESS : EnumActionResult.PASS;
}
protected boolean isCrushableBlock(IBlockState block){
return getCrusherRecipe(block) != null;
}
protected boolean isCrushableBlock(Block block){
return getCrusherRecipe(block) != null;
}
protected ICrusherRecipe getCrusherRecipe(Block block){
return getCrusherRecipe(block.getDefaultState());
}
protected ICrusherRecipe getCrusherRecipe(IBlockState block){
if(block == null || Item.getItemFromBlock(block.getBlock()) == null)return null;
//return CrusherRecipeRegistry.getInstance().getRecipeForInputItem(block);
return CrusherRecipeRegistry.getInstance().getRecipeForInputItem(new ItemStack(block.getBlock(),1,block.getBlock().getMetaFromState(block)));
}
public ToolMaterial getToolMaterial() {
return this.toolMaterial;
}
@Override
public int getItemEnchantability() {
return this.toolMaterial.getEnchantability();
}
public String getToolMaterialName() {
return this.toolMaterial.toString();
}
@Override
public boolean getIsRepairable(final ItemStack intputItem, final ItemStack repairMaterial) {
List<ItemStack> acceptableItems = OreDictionary.getOres(repairOreDictName);
for(ItemStack i : acceptableItems ){
if(ItemStack.areItemsEqual(i, repairMaterial)) return true;
}
return false;
}
@Override
public int getHarvestLevel(final ItemStack item, final String typeRequested) {
if (typeRequested != null && toolTypes.contains(typeRequested)) {
if(BaseMetals.strongHammers){
return metal.getToolHarvestLevel();
}else{
return metal.getToolHarvestLevel() - 1;
}
}
return -1;
}
@Override
public Set<String> getToolClasses(final ItemStack item) {
return toolTypes;
}
@Override
public boolean hitEntity(final ItemStack item, final EntityLivingBase target, final EntityLivingBase attacker) {
super.hitEntity(item, target, attacker);
MetalToolEffects.extraEffectsOnAttack(metal,item, target, attacker);
return true;
}
@Override
public void onCreated(final ItemStack item, final World world, final EntityPlayer crafter) {
super.onCreated(item, world, crafter);
MetalToolEffects.extraEffectsOnCrafting(metal,item, world, crafter);
// achievement
crafter.addStat(Achievements.geologist, 1);
}
@Override
public void onUpdate(final ItemStack item, final World world, final Entity player, final int inventoryIndex, final boolean isHeld) {
if(regenerates && !world.isRemote && isHeld && item.getItemDamage() > 0 && world.getTotalWorldTime() % regenInterval == 0){
item.setItemDamage(item.getItemDamage() - 1);
}
}
@Override
public boolean canHarvestBlock(final IBlockState targetBS) {
Block target = targetBS.getBlock();
// go to net.minecraftforge.common.ForgeHooks.initTools(); to see all tool type strings
String toolType = target.getHarvestTool(target.getDefaultState());
if(this.toolTypes.contains(toolType) || target.getMaterial(targetBS) == Material.ROCK){
// can mine like a Pickaxe
return this.getHarvestLevel(null, "pickaxe") >= target.getHarvestLevel(target.getDefaultState());
} else if("shovel".equals(toolType) && target.getHarvestLevel(target.getDefaultState()) <= 0){
// can be dug with wooden shovel
return true;
}
// return true if block doesn't need tools
return target.getHarvestLevel(target.getDefaultState()) == -1;
}
public String getMaterialName() {
return metal.getName();
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean b){
super.addInformation(stack,player,list,b);
MetalToolEffects.addToolSpecialPropertiesToolTip(metal,list);
}
@Override
public MetalMaterial getMetalMaterial(){
return metal;
}
}