package com.fredtargaryen.floocraft.block;
import com.fredtargaryen.floocraft.FloocraftBase;
import com.fredtargaryen.floocraft.client.gui.GuiTeleport;
import com.fredtargaryen.floocraft.proxy.ClientProxy;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public abstract class GreenFlamesBase extends Block {
public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 9);
public GreenFlamesBase() {
super(Material.FIRE);
}
@Override
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, AGE);
}
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(AGE, meta);
}
@Override
public int getMetaFromState(IBlockState state)
{
return (Integer)state.getValue(AGE);
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
return FULL_BLOCK_AABB;
}
@Override
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer()
{
return BlockRenderLayer.CUTOUT_MIPPED;
}
@Override
public void onEntityCollidedWithBlock(World par1World, BlockPos pos, IBlockState state, Entity par4Entity)
{
if (par1World.isRemote)
{
if (par4Entity instanceof EntityPlayer)
{
doClientGuiTings(pos);
}
}
}
@SideOnly(Side.CLIENT)
private void doClientGuiTings(BlockPos pos) {
ClientProxy proxy = (ClientProxy) FloocraftBase.proxy;
if (Minecraft.getMinecraft().currentScreen == null && !proxy.overrideTicker.isOverriding()) {
Minecraft.getMinecraft().displayGuiScreen(new GuiTeleport(pos.getX(), pos.getY(), pos.getZ()));
proxy.overrideTicker.start();
}
}
@Override
public int tickRate(World par1World) {
return 30;
}
@Override
public void onBlockAdded(World par1World, BlockPos pos, IBlockState state) {
if (isInFireplace(par1World, pos)) {
par1World.scheduleUpdate(pos, this, this.tickRate(par1World));
} else {
par1World.setBlockState(pos, Blocks.FIRE.getDefaultState());
}
}
@Override
public void updateTick(World par1World, BlockPos pos, IBlockState state, Random par5Random) {
if (!isInFireplace(par1World, pos) || par1World.getBlockState(pos).getValue(AGE).equals(0)) {
par1World.setBlockState(pos, Blocks.FIRE.getDefaultState());
} else {
par1World.scheduleUpdate(pos, this, this.tickRate(par1World) + par5Random.nextInt(10));
}
}
@Override
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face)
{
return false;
}
@Deprecated
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn, boolean lolidkwhatthisis)
{}
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand)
{
if (rand.nextInt(24) == 0)
{
worldIn.playSound((double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 1.0F + rand.nextFloat(), rand.nextFloat() * 0.7F + 0.3F, false);
}
for (int i = 0; i < 3; ++i)
{
double d0 = (double)pos.getX() + rand.nextDouble();
double d1 = (double)pos.getY() + rand.nextDouble() * 0.5D + 0.5D;
double d2 = (double)pos.getZ() + rand.nextDouble();
worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
}
}
/**
* ALL FIREPLACE VALIDATION CODE STARTS HERE
*/
private int getTopBlockY(World w, BlockPos pos) {
BlockPos newPos = pos.offset(EnumFacing.UP, 1);
int y = newPos.getY();
IBlockState bs = w.getBlockState(newPos);
while (bs.getBlock().isAir(bs, w, newPos) && y < 256) {
newPos = newPos.offset(EnumFacing.UP, 1);
y = newPos.getY();
bs = w.getBlockState(newPos);
}
//When y >= 256 you get an air block, so if b is a solid cube y is implicitly < 256
if (bs.getBlock().getMaterial(bs).isSolid()) return y;
return 0;
}
private boolean isWallColumn(World w, BlockPos bottomPos, int topY) {
boolean valid = true;
BlockPos newBottomPos = bottomPos;
while (valid && newBottomPos.getY() < topY) {
IBlockState bs = w.getBlockState(newBottomPos);
if (bs.getBlock().getMaterial(bs).isSolid()) {
newBottomPos = newBottomPos.offset(EnumFacing.UP, 1);
} else {
valid = false;
}
}
return valid;
}
private List<Integer> getWalls(World w, BlockPos bottomPos, int topY) {
List<Integer> walls = new ArrayList<Integer>();
if (this.isWallColumn(w, bottomPos.add(0.0D, 0.0D, 1.0D), topY)) {
walls.add(2);
}
if (this.isWallColumn(w, bottomPos.add(-1.0D, 0.0D, 0.0D), topY)) {
walls.add(4);
}
if (this.isWallColumn(w, bottomPos.add(1.0D, 0.0D, 0.0D), topY)) {
walls.add(6);
}
if (this.isWallColumn(w, bottomPos.add(0.0D, 0.0D, -1.0D), topY)) {
walls.add(8);
}
return walls;
}
private boolean canLoopToCorner(World w, int x, int y, int z, int backWall, int oldSideWall, int top) {
int sideWall;
int oldX = x;
int oldZ = z;
switch (oldSideWall) {
case 2:
sideWall = 8;
break;
case 4:
sideWall = 6;
break;
case 6:
sideWall = 4;
break;
case 8:
sideWall = 2;
break;
default:
return false;
}
boolean stop = false;
while (!stop) {
if (backWall == 2 || backWall == 8) {
if (sideWall == 4) {
x--;
} else {
x++;
}
} else {
if (sideWall == 2) {
z++;
} else {
z--;
}
}
BlockPos newBottomPos = new BlockPos(x, y, z);
int newTop = this.getTopBlockY(w, newBottomPos);
List<Integer> walls = this.getWalls(w, newBottomPos, newTop);
switch (walls.size()) {
case 1:
if (!walls.contains(backWall)) {
return false;
} else {
if (newTop > top++) {
if (!this.isWallColumn(w, new BlockPos(oldX, top, oldZ), newTop)) {
return false;
}
} else if (newTop < top--) {
if (!this.isWallColumn(w, new BlockPos(x, newTop, z), top)) {
return false;
}
}
oldX = x;
top = newTop;
oldZ = z;
}
break;
case 2:
if (walls.contains(backWall) && walls.contains(sideWall)) {
stop = true;
} else {
return false;
}
break;
default:
return false;
}
}
return true;
}
public boolean isInFireplace(World w, BlockPos pos)
{
if (pos.getY() < 254)
{
int t = this.getTopBlockY(w, pos);
if (t > 0)
{
List<Integer> walls = this.getWalls(w, pos, t);
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
switch (walls.size())
{
case 3:
return true;
case 2:
if ((walls.contains(2) && (walls.contains(4) || walls.contains(6))
|| (walls.contains(8) && (walls.contains(4) || walls.contains(6))))) {
return this.canLoopToCorner(w, x, y, z, walls.get(0), walls.get(1), t)
|| this.canLoopToCorner(w, x, y, z, walls.get(1), walls.get(0), t);
}
break;
case 1:
switch (walls.get(0)) {
case 2:
return this.canLoopToCorner(w, x, y, z, 2, 4, t) && this.canLoopToCorner(w, x, y, z, 2, 6, t);
case 4:
return this.canLoopToCorner(w, x, y, z, 4, 8, t) && this.canLoopToCorner(w, x, y, z, 4, 2, t);
case 6:
return this.canLoopToCorner(w, x, y, z, 6, 8, t) && this.canLoopToCorner(w, x, y, z, 6, 2, t);
case 8:
return this.canLoopToCorner(w, x, y, z, 8, 4, t) && this.canLoopToCorner(w, x, y, z, 8, 6, t);
default:
break;
}
break;
default:
break;
}
}
}
return false;
}
}