package common.block;

import java.util.Map;

import common.collect.Maps;
import common.init.Blocks;
import common.init.Config;
import common.init.SoundEvent;
import common.material.Material;
import common.model.BlockLayer;
import common.model.Model;
import common.model.ModelProvider;
import common.model.ModelRotation;
import common.model.ParticleType;
import common.properties.IProperty;
import common.properties.PropertyBool;
import common.properties.PropertyInteger;
import common.rng.Random;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.Facing;
import common.world.IBlockAccess;
import common.world.IWorldAccess;
import common.world.AWorldClient;
import common.world.State;
import common.world.World;
import common.world.AWorldServer;

public class BlockFire extends Block
{
    public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 15);
    public static final PropertyBool FLIP = PropertyBool.create("flip");
    public static final PropertyBool ALT = PropertyBool.create("alt");
    public static final PropertyBool NORTH = PropertyBool.create("north");
    public static final PropertyBool EAST = PropertyBool.create("east");
    public static final PropertyBool SOUTH = PropertyBool.create("south");
    public static final PropertyBool WEST = PropertyBool.create("west");
    public static final PropertyInteger UPPER = PropertyInteger.create("upper", 0, 2);
    private final Map<Block, Integer> encouragements = Maps.<Block, Integer>newIdentityHashMap();
    private final Map<Block, Integer> flammabilities = Maps.<Block, Integer>newIdentityHashMap();

    /**
     * Get the actual Block state of this Block at the given position. This applies properties not visible in the
     * metadata, such as fence connections.
     */
    public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
    {
        int i = pos.getX();
        int j = pos.getY();
        int k = pos.getZ();

        if (!World.isSolidSurface(worldIn.getState(pos.down())) && !Blocks.fire.canCatchFire(worldIn, pos.down()))
        {
            boolean flag = (i + j + k & 1) == 1;
            boolean flag1 = (i / 2 + j / 2 + k / 2 & 1) == 1;
            int l = 0;

            if (this.canCatchFire(worldIn, pos.up()))
            {
                l = flag ? 1 : 2;
            }

            return state.withProperty(NORTH, Boolean.valueOf(this.canCatchFire(worldIn, pos.north()))).withProperty(EAST, Boolean.valueOf(this.canCatchFire(worldIn, pos.east()))).withProperty(SOUTH, Boolean.valueOf(this.canCatchFire(worldIn, pos.south()))).withProperty(WEST, Boolean.valueOf(this.canCatchFire(worldIn, pos.west()))).withProperty(UPPER, Integer.valueOf(l)).withProperty(FLIP, Boolean.valueOf(flag1)).withProperty(ALT, Boolean.valueOf(flag));
        }
        else
        {
            return this.getState();
        }
    }

    public BlockFire()
    {
        super(Material.fire);
        this.setDefaultState(this.getBaseState().withProperty(AGE, Integer.valueOf(0)).withProperty(FLIP, Boolean.valueOf(false)).withProperty(ALT, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)).withProperty(UPPER, Integer.valueOf(0)));
        this.setTickRandomly();
    }

    public void setFireInfo(Block blockIn, int encouragement, int flammability)
    {
        this.encouragements.put(blockIn, Integer.valueOf(encouragement));
        this.flammabilities.put(blockIn, Integer.valueOf(flammability));
    }

    public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
    {
        return null;
    }

    /**
     * Used to determine ambient occlusion and culling when rebuilding chunks for render
     */
    public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean isFullCube()
    {
        return false;
    }

    /**
     * Returns the quantity of items to drop on block destruction.
     */
    public int quantityDropped(Random random)
    {
        return 0;
    }

    /**
     * How many world ticks before ticking
     */
    public int tickRate(World worldIn, BlockPos pos)
    {
        return 30;
    }

    public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
    {
        if (Config.fire)
        {
            if (!this.canPlaceBlockAt(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }

            Block block = worldIn.getState(pos.down()).getBlock();
            boolean flag = block.canKeepFire(); // == Blocks.hellrock;

//            if (worldIn.dimension instanceof AreaEnd && block == Blocks.bedrock)
//            {
//                flag = true;
//            }

            if (!flag && worldIn.isRaining() && this.canDie(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }
            else
            {
                int i = ((Integer)state.getValue(AGE)).intValue();

                if (i < 15 && rand.chance(3))
                {
                    state = state.withProperty(AGE, Integer.valueOf(i + 1)); // rand.zrange(3) / 2));
                    worldIn.setState(pos, state, 4);
                }

                worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos) + rand.zrange(10));

                if (!flag)
                {
                    if (!this.canNeighborCatchFire(worldIn, pos))
                    {
                        if (!worldIn.isBlockSolid(pos.down()) || i == 15); // i > 3)
                        {
                            worldIn.setBlockToAir(pos);
                        }

                        return;
                    }

//                    if (!this.canCatchFire(worldIn, pos.down()) && i == 15 && rand.chance(4))
//                    {
//                        worldIn.setBlockToAir(pos);
//                        return;
//                    }
                }

                boolean flag1 = worldIn.isBlockinHighHumidity(pos);
                int j = 0;

                if (flag1)
                {
                    j = -50;
                }

                this.catchOnFire(worldIn, pos.east(), 300 + j, rand, i);
                this.catchOnFire(worldIn, pos.west(), 300 + j, rand, i);
                this.catchOnFire(worldIn, pos.down(), 250 + j, rand, i);
                this.catchOnFire(worldIn, pos.up(), 250 + j, rand, i);
                this.catchOnFire(worldIn, pos.north(), 300 + j, rand, i);
                this.catchOnFire(worldIn, pos.south(), 300 + j, rand, i);

                for (int k = -1; k <= 1; ++k)
                {
                    for (int l = -1; l <= 1; ++l)
                    {
                        for (int i1 = -1; i1 <= 4; ++i1)
                        {
                            if (k != 0 || i1 != 0 || l != 0)
                            {
                                int j1 = 100;

                                if (i1 > 1 && (i1 > 2 || rand.rarity(5)))
                                {
                                    j1 += (i1 - 1) * 100;
                                }
                                else if(i1 < 0 && rand.chance(5)) {
                                	i1 -= 1;
                                }

                                BlockPos blockpos = pos.add(rand.chance(k, k * 2, 5), i1, rand.chance(l, l * 2, 5));
                                int k1 = this.getNeighborEncouragement(worldIn, blockpos);

                                if (k1 > 0)
                                {
                                    int l1 = (k1 + 40 + /* worldIn.getDifficulty().getId() */ 3 * 7) / (i + 30);

                                    if (flag1)
                                    {
                                        l1 /= 2;
                                    }

                                    if (l1 > 0 && rand.zrange(j1) <= l1 && (!worldIn.isRaining() || !this.canDie(worldIn, blockpos)))
                                    {
                                        int i2 = i + rand.zrange(5) / 4;

                                        if (i2 > 15)
                                        {
                                            i2 = 15;
                                        }

                                        worldIn.setState(blockpos, state.withProperty(AGE, Integer.valueOf(i2)), 3);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    protected boolean canDie(World worldIn, BlockPos pos)
    {
        return worldIn.isRainingAt(pos, true) || worldIn.isRainingAt(pos.west(), true) || worldIn.isRainingAt(pos.east(), true) || worldIn.isRainingAt(pos.north(), true) || worldIn.isRainingAt(pos.south(), true);
    }

    public boolean requiresUpdates()
    {
        return false;
    }

    private int getFlammability(Block blockIn)
    {
        Integer integer = (Integer)this.flammabilities.get(blockIn);
        return integer == null ? 0 : integer.intValue();
    }

    private int getEncouragement(Block blockIn)
    {
        Integer integer = (Integer)this.encouragements.get(blockIn);
        return integer == null ? 0 : integer.intValue();
    }

    private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age)
    {
        int i = this.getFlammability(worldIn.getState(pos).getBlock());

        if (random.zrange(chance) < i)
        {
            State iblockstate = worldIn.getState(pos);

            if (random.zrange(age + 10) < 5 && !worldIn.isRainingAt(pos, true))
            {
                int j = age + random.zrange(5) / 4;

                if (j > 15)
                {
                    j = 15;
                }

                worldIn.setState(pos, this.getState().withProperty(AGE, Integer.valueOf(j)), 3);
            }
            else
            {
                worldIn.setBlockToAir(pos);
            }

            iblockstate.getBlock().onDestroyedByFire(worldIn, pos, iblockstate);
//            if (iblockstate.getBlock() == Blocks.tnt)
//            {
//                Blocks.tnt.onBlockDestroyedByPlayer(worldIn, pos, iblockstate.withProperty(BlockTNT.EXPLODE, Boolean.valueOf(true)));
//            }
        }
    }

    private boolean canNeighborCatchFire(World worldIn, BlockPos pos)
    {
        for (Facing enumfacing : Facing.values())
        {
            if (this.canCatchFire(worldIn, pos.offset(enumfacing)))
            {
                return true;
            }
        }

        return false;
    }

    private int getNeighborEncouragement(World worldIn, BlockPos pos)
    {
        if (!worldIn.isAirBlock(pos))
        {
            return 0;
        }
        else
        {
            int i = 0;

            for (Facing enumfacing : Facing.values())
            {
                i = Math.max(this.getEncouragement(worldIn.getState(pos.offset(enumfacing)).getBlock()), i);
            }

            return i;
        }
    }

    /**
     * Returns if this block is collidable (only used by Fire). Args: x, y, z
     */
    public boolean isCollidable()
    {
        return false;
    }

    /**
     * Checks if the block can be caught on fire
     */
    public boolean canCatchFire(IBlockAccess worldIn, BlockPos pos)
    {
        return this.getEncouragement(worldIn.getState(pos).getBlock()) > 0;
    }

    public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
    {
        return worldIn.isBlockSolid(pos.down()) || this.canNeighborCatchFire(worldIn, pos);
    }

    /**
     * Called when a neighboring block changes.
     */
    public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
    {
        if (!worldIn.isBlockSolid(pos.down()) && !this.canNeighborCatchFire(worldIn, pos))
        {
            worldIn.setBlockToAir(pos);
        }
    }

    public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state)
    {
        if ( // (worldIn.dimension.getDimensionId() < -1 || worldIn.dimension.getDimensionId() > 0) || 
        		!Blocks.portal.tryIgnitePortal(worldIn, pos, worldIn.rand.zrange(8)))
        {
            if (!worldIn.isBlockSolid(pos.down()) && !this.canNeighborCatchFire(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }
            else
            {
                worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos) + worldIn.rand.zrange(10));
            }
        }
    }

    public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
    {
        if (rand.chance(24))
        {
            worldIn.playSound((double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), SoundEvent.FIRE, 1.0F + rand.floatv());
        }

        if (!worldIn.isBlockSolid(pos.down()) && !Blocks.fire.canCatchFire(worldIn, pos.down()))
        {
            if (Blocks.fire.canCatchFire(worldIn, pos.west()))
            {
                for (int j = 0; j < 2; ++j)
                {
                    double d3 = (double)pos.getX() + rand.doublev() * 0.10000000149011612D;
                    double d8 = (double)pos.getY() + rand.doublev();
                    double d13 = (double)pos.getZ() + rand.doublev();
                    worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d3, d8, d13, 0.0D, 0.0D, 0.0D);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.east()))
            {
                for (int k = 0; k < 2; ++k)
                {
                    double d4 = (double)(pos.getX() + 1) - rand.doublev() * 0.10000000149011612D;
                    double d9 = (double)pos.getY() + rand.doublev();
                    double d14 = (double)pos.getZ() + rand.doublev();
                    worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d4, d9, d14, 0.0D, 0.0D, 0.0D);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.north()))
            {
                for (int l = 0; l < 2; ++l)
                {
                    double d5 = (double)pos.getX() + rand.doublev();
                    double d10 = (double)pos.getY() + rand.doublev();
                    double d15 = (double)pos.getZ() + rand.doublev() * 0.10000000149011612D;
                    worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d5, d10, d15, 0.0D, 0.0D, 0.0D);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.south()))
            {
                for (int i1 = 0; i1 < 2; ++i1)
                {
                    double d6 = (double)pos.getX() + rand.doublev();
                    double d11 = (double)pos.getY() + rand.doublev();
                    double d16 = (double)(pos.getZ() + 1) - rand.doublev() * 0.10000000149011612D;
                    worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d6, d11, d16, 0.0D, 0.0D, 0.0D);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.up()))
            {
                for (int j1 = 0; j1 < 2; ++j1)
                {
                    double d7 = (double)pos.getX() + rand.doublev();
                    double d12 = (double)(pos.getY() + 1) - rand.doublev() * 0.10000000149011612D;
                    double d17 = (double)pos.getZ() + rand.doublev();
                    worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d7, d12, d17, 0.0D, 0.0D, 0.0D);
                }
            }
        }
        else
        {
            for (int i = 0; i < 3; ++i)
            {
                double d0 = (double)pos.getX() + rand.doublev();
                double d1 = (double)pos.getY() + rand.doublev() * 0.5D + 0.5D;
                double d2 = (double)pos.getZ() + rand.doublev();
                worldIn.spawnParticle(ParticleType.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D);
            }
        }
    }

//    /**
//     * Get the MapColor for this Block and the given BlockState
//     */
//    public MapColor getMapColor(IBlockState state)
//    {
//        return MapColor.tntColor;
//    }

    public BlockLayer getBlockLayer()
    {
        return BlockLayer.CUTOUT;
    }

    /**
     * Convert the given metadata into a BlockState for this Block
     */
    public State getStateFromMeta(int meta)
    {
        return this.getState().withProperty(AGE, Integer.valueOf(meta));
    }

    /**
     * Convert the BlockState into the correct metadata value
     */
    public int getMetaFromState(State state)
    {
        return ((Integer)state.getValue(AGE)).intValue();
    }

    protected IProperty[] getProperties()
    {
        return new IProperty[] {AGE, NORTH, EAST, SOUTH, WEST, UPPER, FLIP, ALT};
    }
    
	private static Model fire_nsu2_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nu1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_nseu2_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_neu1_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_nsu2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nu2_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_neu2_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nsewu2_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nsewu2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nsew(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_floor(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 0, 8.8f, 16, 22.4f, 8.8f).noShade().rotate(8, 8, 8, Facing.Axis.X, -22.5f, true)
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 0, 7.2f, 16, 22.4f, 7.2f).noShade().rotate(8, 8, 8, Facing.Axis.X, 22.5f, true)
				.n().uv(0, 0, 16, 16).noCull()
			.add(8.8f, 0, 0, 8.8f, 22.4f, 16).noShade().rotate(8, 8, 8, Facing.Axis.Z, -22.5f, true)
				.w().uv(0, 0, 16, 16).noCull()
			.add(7.2f, 0, 0, 7.2f, 22.4f, 16).noShade().rotate(8, 8, 8, Facing.Axis.Z, 22.5f, true)
				.e().uv(0, 0, 16, 16).noCull()
			.add(0, 0, 15.99f, 16, 22.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 0, 0.01f, 16, 22.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0.01f, 0, 0, 0.01f, 22.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 0, 0, 15.99f, 22.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_u1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_n_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull();
	}
	private static Model fire_ne(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nsew_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull();
	}
	private static Model fire_nse(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nse_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull();
	}
	private static Model fire_nsu1_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_n(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_ns(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_neu1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_u2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nseu2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_neu2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nu2(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(180).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true)
				.d().uv(0, 0, 16, 16).noCull();
	}
	private static Model fire_nseu1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_ns_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull();
	}
	private static Model fire_nsewu1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(0, 0, 16, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_nsu1(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(0, 0, 16, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(0, 0, 16, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_nsewu1_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model fire_ne_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull();
	}
	private static Model fire_nseu1_flip(String fire) {
		return ModelProvider.getModelProvider().getModel(fire).noOcclude()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.s().uv(16, 0, 0, 16).noCull()
			.add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade()
				.n().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.e().uv(16, 0, 0, 16).noCull()
			.add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade()
				.w().uv(16, 0, 0, 16).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true)
				.d().uv(0, 0, 16, 16).rot(270).noCull()
			.add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true)
				.d().uv(0, 0, 16, 16).rot(90).noCull();
	}
	private static Model getFireModel(boolean alt, boolean flip, int upper, boolean n, boolean s, boolean w, boolean e) {
		String tex = alt ? "fire_layer_1" : "fire_layer_0";
		if(!e && !flip && !n && !s && upper == 0 && !w)
			return fire_floor(tex);
        else if(!e && !flip && !n && s && upper == 0 && !w)
			return fire_n(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && !n && !s && upper == 0 && w)
			return fire_n(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && !s && upper == 0 && !w)
			return fire_n(tex);
        else if(e && !flip && !n && !s && upper == 0 && !w)
			return fire_n(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && !s && upper == 0 && !w)
			return fire_ne(tex);
        else if(e && !flip && !n && s && upper == 0 && !w)
			return fire_ne(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && !n && s && upper == 0 && w)
			return fire_ne(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && n && !s && upper == 0 && w)
			return fire_ne(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && s && upper == 0 && !w)
			return fire_ns(tex);
        else if(e && !flip && !n && !s && upper == 0 && w)
			return fire_ns(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && s && upper == 0 && !w)
			return fire_nse(tex);
        else if(e && !flip && !n && s && upper == 0 && w)
			return fire_nse(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && n && s && upper == 0 && w)
			return fire_nse(tex).rotate(ModelRotation.X0_Y180);
        else if(e && !flip && n && !s && upper == 0 && w)
			return fire_nse(tex).rotate(ModelRotation.X0_Y270);
        else if(e && !flip && n && s && upper == 0 && w)
			return fire_nsew(tex);
        else if(!e && !flip && !n && !s && upper == 1 && !w)
			return fire_u1(tex);
        else if(!e && !flip && !n && s && upper == 1 && !w)
			return fire_nu1(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && !n && !s && upper == 1 && w)
			return fire_nu1(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && !s && upper == 1 && !w)
			return fire_nu1(tex);
        else if(e && !flip && !n && !s && upper == 1 && !w)
			return fire_nu1(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && !s && upper == 1 && !w)
			return fire_neu1(tex);
        else if(e && !flip && !n && s && upper == 1 && !w)
			return fire_neu1(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && !n && s && upper == 1 && w)
			return fire_neu1(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && n && !s && upper == 1 && w)
			return fire_neu1(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && s && upper == 1 && !w)
			return fire_nsu1(tex);
        else if(e && !flip && !n && !s && upper == 1 && w)
			return fire_nsu1(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && s && upper == 1 && !w)
			return fire_nseu1(tex);
        else if(e && !flip && !n && s && upper == 1 && w)
			return fire_nseu1(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && n && s && upper == 1 && w)
			return fire_nseu1(tex).rotate(ModelRotation.X0_Y180);
        else if(e && !flip && n && !s && upper == 1 && w)
			return fire_nseu1(tex).rotate(ModelRotation.X0_Y270);
        else if(e && !flip && n && s && upper == 1 && w)
			return fire_nsewu1(tex);
        else if(!e && !flip && !n && !s && upper == 2 && !w)
			return fire_u2(tex);
        else if(!e && !flip && !n && s && upper == 2 && !w)
			return fire_nu2(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && !n && !s && upper == 2 && w)
			return fire_nu2(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && !s && upper == 2 && !w)
			return fire_nu2(tex);
        else if(e && !flip && !n && !s && upper == 2 && !w)
			return fire_nu2(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && !s && upper == 2 && !w)
			return fire_neu2(tex);
        else if(e && !flip && !n && s && upper == 2 && !w)
			return fire_neu2(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && !n && s && upper == 2 && w)
			return fire_neu2(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && !flip && n && !s && upper == 2 && w)
			return fire_neu2(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && !flip && n && s && upper == 2 && !w)
			return fire_nsu2(tex);
        else if(e && !flip && !n && !s && upper == 2 && w)
			return fire_nsu2(tex).rotate(ModelRotation.X0_Y90);
        else if(e && !flip && n && s && upper == 2 && !w)
			return fire_nseu2(tex);
        else if(e && !flip && !n && s && upper == 2 && w)
			return fire_nseu2(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && !flip && n && s && upper == 2 && w)
			return fire_nseu2(tex).rotate(ModelRotation.X0_Y180);
        else if(e && !flip && n && !s && upper == 2 && w)
			return fire_nseu2(tex).rotate(ModelRotation.X0_Y270);
        else if(e && !flip && n && s && upper == 2 && w)
			return fire_nsewu2(tex);
        else if(!e && flip && !n && !s && upper == 0 && !w)
			return fire_floor(tex);
        else if(!e && flip && !n && s && upper == 0 && !w)
			return fire_n_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && flip && !n && !s && upper == 0 && w)
			return fire_n_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && flip && n && !s && upper == 0 && !w)
			return fire_n_flip(tex);
        else if(e && flip && !n && !s && upper == 0 && !w)
			return fire_n_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(e && flip && n && !s && upper == 0 && !w)
			return fire_ne_flip(tex);
        else if(e && flip && !n && s && upper == 0 && !w)
			return fire_ne_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && !n && s && upper == 0 && w)
			return fire_ne_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && flip && n && !s && upper == 0 && w)
			return fire_ne_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && flip && n && s && upper == 0 && !w)
			return fire_ns_flip(tex);
        else if(e && flip && !n && !s && upper == 0 && w)
			return fire_ns_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(e && flip && n && s && upper == 0 && !w)
			return fire_nse_flip(tex);
        else if(e && flip && !n && s && upper == 0 && w)
			return fire_nse_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && n && s && upper == 0 && w)
			return fire_nse_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(e && flip && n && !s && upper == 0 && w)
			return fire_nse_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(e && flip && n && s && upper == 0 && w)
			return fire_nsew_flip(tex);
        else if(!e && flip && !n && !s && upper == 1 && !w)
			return fire_u1(tex);
        else if(!e && flip && !n && s && upper == 1 && !w)
			return fire_u2(tex).rotate(ModelRotation.X0_Y180); // fire_nu1_flip
        else if(!e && flip && !n && !s && upper == 1 && w)
			return fire_u2(tex).rotate(ModelRotation.X0_Y270); // fire_nu1_flip
        else if(!e && flip && n && !s && upper == 1 && !w)
			return fire_u2(tex); // fire_nu1_flip
        else if(e && flip && !n && !s && upper == 1 && !w)
			return fire_u2(tex).rotate(ModelRotation.X0_Y90); // fire_nu1_flip
        else if(e && flip && n && !s && upper == 1 && !w)
			return fire_neu1_flip(tex);
        else if(e && flip && !n && s && upper == 1 && !w)
			return fire_neu1_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && !n && s && upper == 1 && w)
			return fire_neu1_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && flip && n && !s && upper == 1 && w)
			return fire_neu1_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && flip && n && s && upper == 1 && !w)
			return fire_nsu1_flip(tex);
        else if(e && flip && !n && !s && upper == 1 && w)
			return fire_nsu1_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(e && flip && n && s && upper == 1 && !w)
			return fire_nseu1_flip(tex);
        else if(e && flip && !n && s && upper == 1 && w)
			return fire_nseu1_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && n && s && upper == 1 && w)
			return fire_nseu1_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(e && flip && n && !s && upper == 1 && w)
			return fire_nseu1_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(e && flip && n && s && upper == 1 && w)
			return fire_nsewu1_flip(tex);
        else if(!e && flip && !n && !s && upper == 2 && !w)
			return fire_u2(tex);
        else if(!e && flip && !n && s && upper == 2 && !w)
			return fire_nu2_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && flip && !n && !s && upper == 2 && w)
			return fire_nu2_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && flip && n && !s && upper == 2 && !w)
			return fire_nu2_flip(tex);
        else if(e && flip && !n && !s && upper == 2 && !w)
			return fire_nu2_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(e && flip && n && !s && upper == 2 && !w)
			return fire_neu2_flip(tex);
        else if(e && flip && !n && s && upper == 2 && !w)
			return fire_neu2_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && !n && s && upper == 2 && w)
			return fire_neu2_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(!e && flip && n && !s && upper == 2 && w)
			return fire_neu2_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(!e && flip && n && s && upper == 2 && !w)
			return fire_nsu2_flip(tex);
        else if(e && flip && !n && !s && upper == 2 && w)
			return fire_nsu2_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(e && flip && n && s && upper == 2 && !w)
			return fire_nseu2_flip(tex);
        else if(e && flip && !n && s && upper == 2 && w)
			return fire_nseu2_flip(tex).rotate(ModelRotation.X0_Y90);
        else if(!e && flip && n && s && upper == 2 && w)
			return fire_nseu2_flip(tex).rotate(ModelRotation.X0_Y180);
        else if(e && flip && n && !s && upper == 2 && w)
			return fire_nseu2_flip(tex).rotate(ModelRotation.X0_Y270);
        else if(e && flip && n && s && upper == 2 && w)
			return fire_nsewu2_flip(tex);
        else
        	return fire_floor(tex);
	}

    public Model getModel(ModelProvider provider, String name, State state) {
    	return getFireModel(state.getValue(ALT), state.getValue(FLIP), state.getValue(UPPER), 
    			state.getValue(NORTH), state.getValue(SOUTH), state.getValue(WEST), state.getValue(EAST));
    }

    public IProperty<?>[] getIgnoredProperties() {
    	return new IProperty[] {AGE};
    }
    
    public void getAnimatedTextures(Map<String, Object> map) {
    	map.put("blocks/fire_layer_0", "fire1");
    	map.put("blocks/fire_layer_1", "fire2");
    }
}
