/**
Copyright (C) <2015> <coolAlias>
This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package zeldaswordskills.block;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockGlass;
import net.minecraft.block.ITileEntityProvider;
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.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.Event.Result;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import zeldaswordskills.api.block.BlockWeight;
import zeldaswordskills.api.block.IExplodable;
import zeldaswordskills.api.block.IHookable;
import zeldaswordskills.api.block.IQuakeBlock;
import zeldaswordskills.api.block.ISmashable;
import zeldaswordskills.api.block.IWhipBlock;
import zeldaswordskills.block.tileentity.TileEntityCeramicJar;
import zeldaswordskills.client.render.block.RenderTileEntityCeramicJar;
import zeldaswordskills.creativetab.ZSSCreativeTabs;
import zeldaswordskills.entity.projectile.EntityBoomerang;
import zeldaswordskills.entity.projectile.EntityCeramicJar;
import zeldaswordskills.entity.projectile.EntityHookShot;
import zeldaswordskills.entity.projectile.EntityWhip;
import zeldaswordskills.ref.Config;
import zeldaswordskills.ref.Sounds;
import zeldaswordskills.util.PlayerUtils;
import zeldaswordskills.util.TargetUtils;
import zeldaswordskills.util.WorldUtils;
import zeldaswordskills.world.gen.DungeonLootLists;
public class BlockCeramicJar extends Block implements IExplodable, IHookable, IQuakeBlock, ISmashable, ISpecialRenderer, ITileEntityProvider, IWhipBlock
{
/** Prevents inventory from dropping when block is picked up */
private static boolean keepInventory;
public BlockCeramicJar() {
super(ZSSBlockMaterials.adventureClay);
disableStats();
setBlockUnbreakable();
setStepSound(soundTypeStone);
setCreativeTab(ZSSCreativeTabs.tabBlocks);
setBlockBounds(0.25F, 0.0F, 0.25F, 0.6875F, 0.6875F, 0.6875F);
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return new TileEntityCeramicJar();
}
@Override
public Result canDestroyBlock(HookshotType type, World world, BlockPos pos, EnumFacing face) {
return Result.ALLOW;
}
@Override
public Result canGrabBlock(HookshotType type, World world, BlockPos pos, EnumFacing face) {
return Result.DENY;
}
@Override
public Material getHookableMaterial(HookshotType type, World world, BlockPos pos, EnumFacing face) {
return Material.clay;
}
@Override
public void handleQuakeEffect(World world, BlockPos pos, IBlockState state, EntityPlayer player) {
if (!world.isRemote) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
}
@Override
public BlockWeight getSmashWeight(EntityPlayer player, ItemStack stack, IBlockState state, EnumFacing face) {
return BlockWeight.VERY_LIGHT;
}
@Override
public Result onSmashed(World world, EntityPlayer player, ItemStack stack, BlockPos pos, IBlockState state, EnumFacing face) {
if (!world.isRemote) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
return Result.ALLOW;
}
@Override
public boolean canBreakBlock(WhipType whip, EntityLivingBase thrower, World world, BlockPos pos, EnumFacing face) {
return false;
}
@Override
public boolean canGrabBlock(WhipType whip, EntityLivingBase thrower, World world, BlockPos pos, EnumFacing face) {
return true;
}
@Override
public Result shouldSwing(EntityWhip whip, World world, BlockPos pos, int ticksInGround) {
if (ticksInGround > 30) {
EntityLivingBase thrower = whip.getThrower();
EntityCeramicJar jar = new EntityCeramicJar(world, whip.posX, whip.posY + 1, whip.posZ);
double dx = thrower.posX - jar.posX;
double dy = (thrower.posY + thrower.getEyeHeight()) - (jar.posY - 1);
double dz = thrower.posZ - jar.posZ;
TargetUtils.setEntityHeading(jar, dx, dy + 0.5D, dz, 1.0F, 0.0F, true);
TileEntity te = world.getTileEntity(pos);
if (te instanceof IInventory) {
ItemStack stack = ((IInventory) te).getStackInSlot(0);
if (stack != null) {
jar.setStack(stack);
}
}
if (!world.isRemote) {
world.spawnEntityInWorld(jar);
}
keepInventory = true; // don't drop items from breakBlock
world.setBlockToAir(pos);
keepInventory = false;
whip.setDead();
}
return Result.DENY;
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune) {
return null;
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean isFullCube() {
return false;
}
@Override
public boolean canDropFromExplosion(Explosion explosion) {
return false;
}
@Override
public boolean canHarvestBlock(IBlockAccess World, BlockPos pos, EntityPlayer player) {
return false;
}
@Override
public boolean canPlaceBlockAt(World world, BlockPos pos) {
return super.canPlaceBlockAt(world, pos) && (world.isSideSolid(pos.down(), EnumFacing.UP) || world.getBlockState(pos.down()).getBlock() instanceof BlockGlass);
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
if (!keepInventory) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof IInventory) {
IInventory inv = (IInventory) te;
if (inv.getStackInSlot(0) == null && world.rand.nextFloat() < Config.getJarDropChance()) {
inv.setInventorySlotContents(0, ChestGenHooks.getInfo(DungeonLootLists.JAR_DROPS).getOneItem(world.rand));
}
}
WorldUtils.dropContainerBlockInventory(world, pos);
}
super.breakBlock(world, pos, state);
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing face, float hitX, float hitY, float hitZ) {
if (!world.isRemote && player.getHeldItem() == null) {
ItemStack jarStack = new ItemStack(this);
TileEntity te = world.getTileEntity(pos);
if (te instanceof IInventory) {
ItemStack invStack = ((IInventory) te).getStackInSlot(0);
if (invStack != null) {
NBTTagCompound item = new NBTTagCompound();
invStack.writeToNBT(item);
jarStack.setTagCompound(new NBTTagCompound());
jarStack.getTagCompound().setTag("jarStack", item);
}
}
player.setCurrentItemOrArmor(0, jarStack);
keepInventory = true;
world.setBlockToAir(pos);
keepInventory = false;
}
return true;
}
@Override
public void onBlockClicked(World world, BlockPos pos, EntityPlayer player) {
if (!world.isRemote && PlayerUtils.isHoldingWeapon(player)) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase entity, ItemStack stack) {
if (stack.hasTagCompound() && stack.getTagCompound().hasKey("jarStack")) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof IInventory) {
ItemStack jarStack = ItemStack.loadItemStackFromNBT(stack.getTagCompound().getCompoundTag("jarStack"));
((IInventory) te).setInventorySlotContents(0, jarStack);
}
}
}
@Override
public void onBlockDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
if (!world.isRemote) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, Entity entity) {
this.onEntityCollidedWithBlock(world, pos, world.getBlockState(pos), entity);
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) {
if (!world.isRemote && (entity instanceof EntityArrow || entity instanceof EntityBoomerang || entity instanceof EntityHookShot)) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
}
@Override
public void onNeighborBlockChange(World world, BlockPos pos, IBlockState state, Block neighbor) {
if (!world.isRemote && !world.isSideSolid(pos.down(), EnumFacing.UP)) {
WorldUtils.playSoundAt(world, pos.getX(), pos.getY(), pos.getZ(), Sounds.BREAK_JAR, 0.4F, 0.5F);
world.destroyBlock(pos, false);
}
}
@Override
@SideOnly(Side.CLIENT)
public void registerSpecialRenderer() {
if (Config.doJarsUpdate()) { // only need to do special rendering if jars can pick up dropped items
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityCeramicJar.class, new RenderTileEntityCeramicJar());
}
}
}