package mcjty.deepresonance.blocks.pedestal;
import elec332.core.world.WorldHelper;
import mcjty.deepresonance.blocks.ModBlocks;
import mcjty.deepresonance.blocks.collector.EnergyCollectorSetup;
import mcjty.deepresonance.blocks.collector.EnergyCollectorTileEntity;
import mcjty.deepresonance.blocks.crystals.ResonatingCrystalTileEntity;
import mcjty.deepresonance.config.ConfigMachines;
import mcjty.lib.container.DefaultSidedInventory;
import mcjty.lib.container.InventoryHelper;
import mcjty.lib.container.InventoryLocator;
import mcjty.lib.entity.GenericTileEntity;
import mcjty.lib.varia.BlockTools;
import mcjty.lib.varia.CustomSidedInvWrapper;
import mcjty.lib.varia.SoundTools;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public class PedestalTileEntity extends GenericTileEntity implements DefaultSidedInventory, ITickable {
private InventoryHelper inventoryHelper = new InventoryHelper(this, PedestalContainer.factory, 1);
private int checkCounter = 0;
// Cache for the inventory used to put the spent crystal material in.
private InventoryLocator inventoryLocator = new InventoryLocator();
private BlockPos cachedLocator = null;
@Override
public InventoryHelper getInventoryHelper() {
return inventoryHelper;
}
@Override
public void update() {
if (!worldObj.isRemote){
checkStateServer();
}
}
protected void checkStateServer() {
checkCounter--;
if (checkCounter > 0) {
return;
}
checkCounter = 20;
IBlockState state = worldObj.getBlockState(getPos());
EnumFacing orientation = BlockTools.getOrientation(state.getBlock().getMetaFromState(state));
BlockPos b = pos.offset(orientation);
if (worldObj.isAirBlock(b)) {
// Nothing in front. We can place a new crystal if we have one.
placeCrystal(b);
} else if (WorldHelper.getBlockAt(worldObj, b) == ModBlocks.resonatingCrystalBlock) {
// Check if the crystal in front of us still has power.
// If not we will remove it.
checkCrystal(b);
} // else we can do nothing.
}
private void placeCrystal(BlockPos pos) {
ItemStack crystalStack = inventoryHelper.getStackInSlot(PedestalContainer.SLOT_CRYSTAL);
if (crystalStack != null && crystalStack.stackSize > 0) {
if (crystalStack.getItem() instanceof ItemBlock) {
ItemBlock itemBlock = (ItemBlock) (crystalStack.getItem());
itemBlock.placeBlockAt(crystalStack, FakePlayerFactory.getMinecraft((WorldServer) worldObj), worldObj, pos, null, 0, 0, 0, itemBlock.getBlock().getStateFromMeta(0));
inventoryHelper.decrStackSize(PedestalContainer.SLOT_CRYSTAL, 1);
SoundTools.playSound(worldObj, ModBlocks.resonatingCrystalBlock.getSoundType().breakSound, getPos().getX(), getPos().getY(), getPos().getZ(), 1.0f, 1.0f);
if (findCollector(pos)) {
TileEntity tileEntity = WorldHelper.getTileAt(worldObj, new BlockPos(cachedLocator));
if (tileEntity instanceof EnergyCollectorTileEntity) {
EnergyCollectorTileEntity energyCollectorTileEntity = (EnergyCollectorTileEntity) tileEntity;
energyCollectorTileEntity.addCrystal(pos.getX(), pos.getY(), pos.getZ());
}
}
}
}
}
private static EnumFacing[] directions = new EnumFacing[] {
EnumFacing.EAST, EnumFacing.WEST, EnumFacing.NORTH, EnumFacing.SOUTH,
EnumFacing.UP, EnumFacing.DOWN
};
private void checkCrystal(BlockPos p) {
TileEntity tileEntity = WorldHelper.getTileAt(worldObj, p);
if (tileEntity instanceof ResonatingCrystalTileEntity) {
ResonatingCrystalTileEntity resonatingCrystalTileEntity = (ResonatingCrystalTileEntity) tileEntity;
if (resonatingCrystalTileEntity.getPower() <= EnergyCollectorTileEntity.CRYSTAL_MIN_POWER) {
ItemStack spentCrystal = new ItemStack(ModBlocks.resonatingCrystalBlock, 1);
NBTTagCompound tagCompound = new NBTTagCompound();
resonatingCrystalTileEntity.writeToNBT(tagCompound);
spentCrystal.setTagCompound(tagCompound);
inventoryLocator.ejectStack(worldObj, getPos(), spentCrystal, pos, directions);
worldObj.setBlockToAir(p);
SoundTools.playSound(worldObj, ModBlocks.resonatingCrystalBlock.getSoundType().breakSound, p.getX(), p.getY(), p.getZ(), 1.0f, 1.0f);
}
}
}
private boolean findCollector(BlockPos crystalLocation) {
if (cachedLocator != null) {
if (WorldHelper.getBlockAt(worldObj, crystalLocation) == EnergyCollectorSetup.energyCollectorBlock) {
return true;
}
cachedLocator = null;
}
float closestDistance = Float.MAX_VALUE;
int yy = crystalLocation.getY(), xx = crystalLocation.getX(), zz = crystalLocation.getZ();
for (int y = yy - ConfigMachines.Collector.maxVerticalCrystalDistance ; y <= yy + ConfigMachines.Collector.maxVerticalCrystalDistance ; y++) {
if (y >= 0 && y < worldObj.getHeight()) {
int maxhordist = ConfigMachines.Collector.maxHorizontalCrystalDistance;
for (int x = xx - maxhordist; x <= xx + maxhordist; x++) {
for (int z = zz - maxhordist; z <= zz + maxhordist; z++) {
BlockPos pos = new BlockPos(x, y, z);
if (WorldHelper.getBlockAt(worldObj, pos) == EnergyCollectorSetup.energyCollectorBlock) {
double sqdist = pos.distanceSq(crystalLocation);
if (sqdist < closestDistance) {
closestDistance = (float)sqdist;
cachedLocator = pos;
}
}
}
}
}
}
return cachedLocator != null;
}
@Override
public void readFromNBT(NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
}
@Override
public void readRestorableFromNBT(NBTTagCompound tagCompound) {
super.readRestorableFromNBT(tagCompound);
readBufferFromNBT(tagCompound, inventoryHelper);
}
@Override
public void writeToNBT(NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
}
@Override
public void writeRestorableToNBT(NBTTagCompound tagCompound) {
super.writeRestorableToNBT(tagCompound);
writeBufferToNBT(tagCompound, inventoryHelper);
}
@Override
public int[] getSlotsForFace(EnumFacing side) {
return new int[] { PedestalContainer.SLOT_CRYSTAL };
}
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
return false;
}
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction) {
return isItemValidForSlot(index, itemStackIn);
}
@Override
public int getInventoryStackLimit() {
return 1;
}
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
return canPlayerAccess(player);
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return stack.getItem() == Item.getItemFromBlock(ModBlocks.resonatingCrystalBlock);
}
IItemHandler invHandler = new CustomSidedInvWrapper(this);
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return true;
}
return super.hasCapability(capability, facing);
}
@Override
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return (T) invHandler;
}
return super.getCapability(capability, facing);
}
}