package com.jaquadro.minecraft.gardencore.block;
import com.jaquadro.minecraft.gardencore.api.IPlantProxy;
import com.jaquadro.minecraft.gardencore.api.block.IGardenBlock;
import com.jaquadro.minecraft.gardencore.api.plant.PlantItem;
import com.jaquadro.minecraft.gardencore.api.block.garden.IConnectionProfile;
import com.jaquadro.minecraft.gardencore.api.block.garden.ISlotProfile;
import com.jaquadro.minecraft.gardencore.api.block.garden.ISlotShareProfile;
import com.jaquadro.minecraft.gardencore.block.tile.TileEntityGarden;
import com.jaquadro.minecraft.gardencore.core.ModBlocks;
import com.jaquadro.minecraft.gardencore.core.ModItems;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
public abstract class BlockGarden extends BlockContainer implements IGardenBlock
{
public static final int SLOT_INVALID = -1;
protected IConnectionProfile connectionProfile;
protected ISlotProfile slotProfile;
protected ISlotShareProfile slotShareProfile;
protected BlockGarden (String blockName, Material material) {
super(material);
setBlockName(blockName);
}
@Override
public boolean canSustainPlant (IBlockAccess world, int x, int y, int z, ForgeDirection direction, IPlantable plantable) {
return false;
}
@Override
public boolean onBlockActivated (World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
if (side != ForgeDirection.UP.ordinal())
return false;
TileEntityGarden tileEntity = getTileEntity(world, x, y, z);
if (tileEntity == null) {
tileEntity = createNewTileEntity(world, 0);
world.setTileEntity(x, y, z, tileEntity);
}
return applyItemToGarden(world, x, y, z, player, null, hitX, hitY, hitZ);
}
@Override
public abstract TileEntityGarden createNewTileEntity (World world, int meta);
@Override
public void onBlockHarvested (World world, int x, int y, int z, int p_149681_5_, EntityPlayer player) {
super.onBlockHarvested(world, x, y, z, p_149681_5_, player);
if (player.capabilities.isCreativeMode) {
TileEntityGarden te = getTileEntity(world, x, y, z);
if (te != null)
te.clearPlantedContents();
}
}
@Override
public void breakBlock (World world, int x, int y, int z, Block block, int data) {
TileEntityGarden te = getTileEntity(world, x, y, z);
if (te != null) {
for (ItemStack item : te.getReachableContents())
dropBlockAsItem(world, x, y, z, item);
te.clearReachableContents();
}
super.breakBlock(world, x, y, z, block, data);
}
@Override
public int getDefaultSlot () {
return SLOT_INVALID;
}
public IConnectionProfile getConnectionProfile () {
return connectionProfile;
}
public ISlotProfile getSlotProfile () {
return slotProfile;
}
public ISlotShareProfile getSlotShareProfile () {
return slotShareProfile;
}
public void clearPlantedContents (IBlockAccess world, int x, int y, int z) {
TileEntityGarden te = getTileEntity(world, x, y, z);
if (te != null)
te.clearReachableContents();
validateBlockState(te);
}
public NBTTagCompound saveAndClearPlantedContents (IBlockAccess world, int x, int y, int z) {
TileEntityGarden te = getTileEntity(world, x, y, z);
if (te == null)
return null;
NBTTagCompound tag = new NBTTagCompound();
te.writeToNBT(tag);
clearPlantedContents(world, x, y, z);
return tag;
}
public void restorePlantedContents (IBlockAccess world, int x, int y, int z, NBTTagCompound tag) {
TileEntityGarden te = getTileEntity(world, x, y, z);
if (te == null)
return;
te.readFromNBT(tag);
validateBlockState(te);
}
public Block getPlantBlockFromSlot (IBlockAccess blockAccess, int x, int y, int z, int slot) {
TileEntityGarden te = getTileEntity(blockAccess, x, y, z);
ItemStack stack = te.getPlantInSlot(slot);
if (stack == null || stack.getItem() == null)
return null;
return Block.getBlockFromItem(stack.getItem());
}
public int getPlantMetaFromSlot (IBlockAccess blockAccess, int x, int y, int z, int slot) {
TileEntityGarden te = getTileEntity(blockAccess, x, y, z);
ItemStack stack = te.getPlantInSlot(slot);
if (stack == null || stack.getItem() == null)
return 0;
return stack.getItemDamage();
}
public static void validateBlockState (TileEntityGarden tileEntity) {
Block baseBlock = tileEntity.getWorldObj().getBlock(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
if (!(baseBlock instanceof BlockGarden))
return;
BlockGarden garden = (BlockGarden) baseBlock;
int plantHeight = garden.getAggregatePlantHeight(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
World world = tileEntity.getWorldObj();
int x = tileEntity.xCoord;
int y = tileEntity.yCoord + 1;
int z = tileEntity.zCoord;
for (int yLimit = y + plantHeight; y < yLimit; y++) {
Block block = world.getBlock(x, y, z);
if (block.isAir(world, x, y, z))
world.setBlock(x, y, z, ModBlocks.gardenProxy, 0, 3);
world.func_147479_m(x, y, z); // markBlockForRenderUpdate
}
while (world.getBlock(x, y, z) instanceof BlockGardenProxy)
world.setBlockToAir(x, y++, z);
}
public int getAggregatePlantHeight (IBlockAccess blockAccess, int x, int y, int z) {
TileEntityGarden garden = getTileEntity(blockAccess, x, y, z);
int height = 0;
for (int slot : slotProfile.getPlantSlots()) {
ItemStack item = garden.getStackInSlot(slot);
PlantItem plant = PlantItem.getForItem(blockAccess, item);
if (plant == null)
continue;
height = Math.max(height, plant.getPlantHeight());
}
return height;
}
public final boolean applyItemToGarden (World world, int x, int y, int z, EntityPlayer player, ItemStack itemStack, float hitX, float hitY, float hitZ) {
return applyItemToGarden(world, x, y, z, player, itemStack, hitX, hitY, hitZ, true);
}
public final boolean applyItemToGarden (World world, int x, int y, int z, EntityPlayer player, ItemStack itemStack) {
return applyItemToGarden(world, x, y, z, player, itemStack, 0, 0, 0, false);
}
protected boolean applyItemToGarden (World world, int x, int y, int z, EntityPlayer player, ItemStack itemStack, float hitX, float hitY, float hitZ, boolean hitValid) {
ItemStack item = (itemStack == null) ? player.inventory.getCurrentItem() : itemStack;
if (item == null)
return false;
int slot = getSlot(world, x, y, z, player, hitX, hitY, hitZ);
if (applyTestKitToGarden(world, x, y, z, slot, item))
return true;
PlantItem plant = PlantItem.getForItem(world, item);
if (plant != null) {
int plantSlot = hitValid
? getEmptySlotForPlant(world, x, y, z, player, plant, hitX, hitY, hitZ)
: getEmptySlotForPlant(world, x, y, z, player, plant);
if (plantSlot == TileEntityGarden.SLOT_INVALID)
return false;
if (canSustainPlantIndependently(world, x, y, z, plant))
return false;
return applyPlantToGarden(world, x, y, z, (itemStack == null) ? player : null, plantSlot, plant);
}
return false;
}
public boolean canSustainPlantIndependently (IBlockAccess blockAccess, int x, int y, int z, PlantItem plant) {
Item item = plant.getPlantSourceItem().getItem();
if (item instanceof IPlantable)
return canSustainPlant(blockAccess, x, y, z, ForgeDirection.UP, (IPlantable) item);
return false;
}
public abstract ItemStack getGardenSubstrate (IBlockAccess blockAccess, int x, int y, int z, int slot);
protected int getSlot (World world, int x, int y, int z, EntityPlayer player, float hitX, float hitY, float hitZ) {
return TileEntityGarden.SLOT_INVALID;
}
protected int getEmptySlotForPlant (World world, int x, int y, int z, EntityPlayer player, PlantItem plant) {
return TileEntityGarden.SLOT_INVALID;
}
protected int getEmptySlotForPlant (World world, int x, int y, int z, EntityPlayer player, PlantItem plant, float hitX, float hitY, float hitZ) {
return getEmptySlotForPlant(world, x, y, z, player, plant);
}
protected boolean enoughSpaceAround (IBlockAccess blockAccess, int x, int y, int z, int slot, PlantItem plant) {
int height = plant.getPlantHeight();
boolean enough = true;
for (int i = 0; i < height; i++)
enough &= blockAccess.isAirBlock(x, y + 1 + i, z) || blockAccess.getBlock(x, y + 1 + i, z) instanceof IPlantProxy;
return enough;
}
protected boolean isPlantValidForSubstrate (ItemStack substrate, PlantItem plant) {
return true;
}
public boolean isPlantValidForSlot (World world, int x, int y, int z, int slot, PlantItem plant) {
if (plant == null)
return false;
if (plant.getPlantBlock() instanceof BlockContainer)
return false;
if (!slotProfile.isPlantValidForSlot(world, x, y, z, slot, plant))
return false;
if (!enoughSpaceAround(world, x, y, z, slot, plant))
return false;
if (!isPlantValidForSubstrate(getGardenSubstrate(world, x, y, z, slot), plant))
return false;
if (canSustainPlantIndependently(world, x, y, z, plant))
return false;
return true;
}
public boolean applyHoe (World world, int x, int y, int z) {
return false;
}
protected boolean applyPlantToGarden (World world, int x, int y, int z, EntityPlayer player, int slot, PlantItem plant) {
if (!isPlantValidForSlot(world, x, y, z, slot, plant))
return false;
TileEntityGarden garden = getTileEntity(world, x, y, z);
garden.setInventorySlotContents(slot, plant.getPlantSourceItem().copy());
if (player != null && !player.capabilities.isCreativeMode) {
ItemStack currentItem = player.inventory.getCurrentItem();
if (--currentItem.stackSize <= 0)
player.inventory.setInventorySlotContents(player.inventory.currentItem, null);
}
return true;
}
protected boolean applyTestKitToGarden (World world, int x, int y, int z, int slot, ItemStack testKit) {
if (testKit == null || testKit.getItem() != ModItems.usedSoilTestKit)
return false;
ItemStack substrateStack = getGardenSubstrate(world, x, y, z, slot);
if (substrateStack == null || substrateStack.getItem() == null)
return false;
TileEntityGarden tileEntity = getTileEntity(world, x, y, z);
if (tileEntity == null)
return false;
tileEntity.setBiomeData(testKit.getItemDamage());
world.markBlockForUpdate(x, y, z);
for (int i = 0; i < 5; i++) {
double d0 = world.rand.nextGaussian() * 0.02D;
double d1 = world.rand.nextGaussian() * 0.02D;
double d2 = world.rand.nextGaussian() * 0.02D;
world.spawnParticle("happyVillager", x + world.rand.nextFloat(), y + .5f + world.rand.nextFloat(), z + world.rand.nextFloat(), d0, d1, d2);
}
return true;
}
public TileEntityGarden getTileEntity (IBlockAccess world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
return (te != null && te instanceof TileEntityGarden) ? (TileEntityGarden) te : null;
}
}