/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [May 20, 2014, 10:56:14 PM (GMT)]
*/
package vazkii.botania.common.item.equipment.tool.terrasteel;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.block.material.Material;
import net.minecraft.client.resources.I18n;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.RecipeSorter;
import net.minecraftforge.oredict.RecipeSorter.Category;
import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.item.ISequentialBreaker;
import vazkii.botania.api.mana.IManaGivingItem;
import vazkii.botania.api.mana.IManaItem;
import vazkii.botania.api.sound.BotaniaSoundEvents;
import vazkii.botania.common.achievement.ModAchievements;
import vazkii.botania.common.core.helper.ItemNBTHelper;
import vazkii.botania.common.crafting.recipe.TerraPickTippingRecipe;
import vazkii.botania.common.item.ItemTemperanceStone;
import vazkii.botania.common.item.ModItems;
import vazkii.botania.common.item.equipment.tool.ToolCommons;
import vazkii.botania.common.item.equipment.tool.manasteel.ItemManasteelPick;
import vazkii.botania.common.item.relic.ItemLokiRing;
import vazkii.botania.common.item.relic.ItemThorRing;
import vazkii.botania.common.lib.LibItemNames;
public class ItemTerraPick extends ItemManasteelPick implements IManaItem, ISequentialBreaker {
private static final String TAG_ENABLED = "enabled";
private static final String TAG_MANA = "mana";
private static final String TAG_TIPPED = "tipped";
private static final int MAX_MANA = Integer.MAX_VALUE;
private static final int MANA_PER_DAMAGE = 100;
private static final List<Material> MATERIALS = Arrays.asList(Material.ROCK, Material.IRON, Material.ICE, Material.GLASS, Material.PISTON, Material.ANVIL, Material.GRASS, Material.GROUND, Material.SAND, Material.SNOW, Material.CRAFTED_SNOW, Material.CLAY);
public static final int[] LEVELS = new int[] {
0, 10000, 1000000, 10000000, 100000000, 1000000000
};
private static final int[] CREATIVE_MANA = new int[] {
10000 - 1, 1000000 - 1, 10000000 - 1, 100000000 - 1, 1000000000 - 1, MAX_MANA - 1
};
public ItemTerraPick() {
super(BotaniaAPI.terrasteelToolMaterial, LibItemNames.TERRA_PICK);
GameRegistry.addRecipe(new TerraPickTippingRecipe());
RecipeSorter.register("botania:terraPickTipping", TerraPickTippingRecipe.class, Category.SHAPELESS, "");
addPropertyOverride(new ResourceLocation("botania", "tipped"), (itemStack, world, entityLivingBase) -> isTipped(itemStack) ? 1 : 0);
addPropertyOverride(new ResourceLocation("botania", "enabled"), (itemStack, world, entityLivingBase) -> isEnabled(itemStack) ? 1 : 0);
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(@Nonnull Item item, CreativeTabs tab, NonNullList<ItemStack> list) {
for(int mana : CREATIVE_MANA) {
ItemStack stack = new ItemStack(item);
setMana(stack, mana);
list.add(stack);
}
}
@SideOnly(Side.CLIENT)
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer player, List<String> stacks, boolean par4) {
String rank = I18n.format("botania.rank" + getLevel(par1ItemStack));
String rankFormat = I18n.format("botaniamisc.toolRank", rank);
stacks.add(rankFormat.replaceAll("&", "\u00a7"));
if(getMana(par1ItemStack) == Integer.MAX_VALUE)
stacks.add(TextFormatting.RED + I18n.format("botaniamisc.getALife"));
}
@Nonnull
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) {
ItemStack stack = player.getHeldItem(hand);
getMana(stack);
int level = getLevel(stack);
if(level != 0) {
setEnabled(stack, !isEnabled(stack));
if(!world.isRemote)
world.playSound(null, player.posX, player.posY, player.posZ, BotaniaSoundEvents.terraPickMode, SoundCategory.PLAYERS, 0.5F, 0.4F);
}
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
}
@Nonnull
@Override
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float sx, float sy, float sz) {
return player.isSneaking() ? super.onItemUse(player, world, pos, hand, side, sx, sy, sz)
: EnumActionResult.PASS;
}
@Override
public void onUpdate(ItemStack par1ItemStack, World world, Entity par3Entity, int par4, boolean par5) {
super.onUpdate(par1ItemStack, world, par3Entity, par4, par5);
if(isEnabled(par1ItemStack)) {
int level = getLevel(par1ItemStack);
if(level == 0)
setEnabled(par1ItemStack, false);
else if(par3Entity instanceof EntityPlayer && !((EntityPlayer) par3Entity).isSwingInProgress)
addMana(par1ItemStack, -level);
}
}
@Override
public boolean onBlockStartBreak(ItemStack stack, BlockPos pos, EntityPlayer player) {
RayTraceResult raycast = ToolCommons.raytraceFromEntity(player.world, player, true, 10);
if(!player.world.isRemote && raycast != null) {
breakOtherBlock(player, stack, pos, pos, raycast.sideHit);
ItemLokiRing.breakOnAllCursors(player, this, stack, pos, raycast.sideHit);
// ^ Doable with API access through the IInternalMethodHandler.
}
return false;
}
@Override
public int getManaPerDmg() {
return MANA_PER_DAMAGE;
}
@Override
public void breakOtherBlock(EntityPlayer player, ItemStack stack, BlockPos pos, BlockPos originPos, EnumFacing side) {
if(!isEnabled(stack))
return;
World world = player.world;
Material mat = world.getBlockState(pos).getMaterial();
if(!MATERIALS.contains(mat))
return;
if(world.isAirBlock(pos))
return;
int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack);
boolean silk = EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0;
boolean thor = ItemThorRing.getThorRing(player) != null;
boolean doX = thor || side.getFrontOffsetX() == 0;
boolean doY = thor || side.getFrontOffsetY() == 0;
boolean doZ = thor || side.getFrontOffsetZ() == 0;
int origLevel = getLevel(stack);
int level = origLevel + (thor ? 1 : 0);
if(ItemTemperanceStone.hasTemperanceActive(player) && level > 2)
level = 2;
int range = level - 1;
int rangeY = Math.max(1, range);
if(range == 0 && level != 1)
return;
Vec3i beginDiff = new Vec3i(doX ? -range : 0, doY ? -1 : 0, doZ ? -range : 0);
Vec3i endDiff = new Vec3i(doX ? range : 0, doY ? rangeY * 2 - 1 : 0, doZ ? range : 0);
ToolCommons.removeBlocksInIteration(player, stack, world, pos, beginDiff, endDiff, null, MATERIALS, silk, fortune, isTipped(stack));
if(origLevel == 5)
player.addStat(ModAchievements.rankSSPick, 1);
}
@Override
public int getEntityLifespan(ItemStack itemStack, World world) {
return Integer.MAX_VALUE;
}
public static boolean isTipped(ItemStack stack) {
return ItemNBTHelper.getBoolean(stack, TAG_TIPPED, false);
}
public static void setTipped(ItemStack stack) {
ItemNBTHelper.setBoolean(stack, TAG_TIPPED, true);
}
public static boolean isEnabled(ItemStack stack) {
return ItemNBTHelper.getBoolean(stack, TAG_ENABLED, false);
}
void setEnabled(ItemStack stack, boolean enabled) {
ItemNBTHelper.setBoolean(stack, TAG_ENABLED, enabled);
}
public static void setMana(ItemStack stack, int mana) {
ItemNBTHelper.setInt(stack, TAG_MANA, mana);
}
@Override
public int getMana(ItemStack stack) {
return getMana_(stack);
}
public static int getMana_(ItemStack stack) {
return ItemNBTHelper.getInt(stack, TAG_MANA, 0);
}
public static int getLevel(ItemStack stack) {
int mana = getMana_(stack);
for(int i = LEVELS.length - 1; i > 0; i--)
if(mana >= LEVELS[i])
return i;
return 0;
}
@Override
public int getMaxMana(ItemStack stack) {
return MAX_MANA;
}
@Override
public void addMana(ItemStack stack, int mana) {
setMana(stack, Math.min(getMana(stack) + mana, MAX_MANA));
}
@Override
public boolean canReceiveManaFromPool(ItemStack stack, TileEntity pool) {
return true;
}
@Override
public boolean canReceiveManaFromItem(ItemStack stack, ItemStack otherStack) {
return !(otherStack.getItem() instanceof IManaGivingItem);
}
@Override
public boolean canExportManaToPool(ItemStack stack, TileEntity pool) {
return false;
}
@Override
public boolean canExportManaToItem(ItemStack stack, ItemStack otherStack) {
return false;
}
@Override
public boolean isNoExport(ItemStack stack) {
return true;
}
@Override
public boolean getIsRepairable(ItemStack par1ItemStack, @Nonnull ItemStack par2ItemStack) {
return par2ItemStack.getItem() == ModItems.manaResource && par2ItemStack.getItemDamage() == 4 ? true : super.getIsRepairable(par1ItemStack, par2ItemStack);
}
@Override
public boolean disposeOfTrashBlocks(ItemStack stack) {
return isTipped(stack);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack before, @Nonnull ItemStack after, boolean slotChanged) {
return after.getItem() != this || isEnabled(before) != isEnabled(after);
}
}