344 lines
10 KiB
Java
Executable file
344 lines
10 KiB
Java
Executable file
package common.block.tech;
|
|
|
|
import common.block.Block;
|
|
import common.block.DirectionalUp;
|
|
import common.block.Material;
|
|
import common.block.artificial.BlockFence;
|
|
import common.block.artificial.BlockStainedGlass;
|
|
import common.entity.types.EntityLiving;
|
|
import common.init.Blocks;
|
|
import common.item.CheatTab;
|
|
import common.model.BlockLayer;
|
|
import common.model.Model;
|
|
import common.model.ModelProvider;
|
|
import common.model.ModelRotation;
|
|
import common.model.ParticleType;
|
|
import common.properties.Property;
|
|
import common.rng.Random;
|
|
import common.util.BlockPos;
|
|
import common.util.BoundingBox;
|
|
import common.util.Facing;
|
|
import common.util.HitPosition;
|
|
import common.util.Vec3;
|
|
import common.world.AWorldClient;
|
|
import common.world.State;
|
|
import common.world.World;
|
|
import common.world.AWorldServer;
|
|
|
|
public class BlockTorch extends Block implements DirectionalUp
|
|
{
|
|
private static boolean isBlockNormalCube(World world, BlockPos pos, boolean def) {
|
|
if(!World.isValid(pos) || (world.client && !world.isBlockLoaded(pos, false)))
|
|
return def;
|
|
Block block = world.getState(pos).getBlock();
|
|
return block.getMaterial().isOpaque() && block.isFullCube();
|
|
}
|
|
|
|
public BlockTorch()
|
|
{
|
|
super(Material.SMALL);
|
|
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.UP));
|
|
// this.setTickRandomly(true);
|
|
this.setTab(CheatTab.TECHNOLOGY);
|
|
this.setFlatItemTexture();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
private boolean canPlaceOn(World worldIn, BlockPos pos)
|
|
{
|
|
if (worldIn.isBlockSolid(pos))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Block block = worldIn.getState(pos).getBlock();
|
|
return block instanceof BlockFence || block == Blocks.glass || block == Blocks.cobblestone_wall || block instanceof BlockStainedGlass;
|
|
}
|
|
}
|
|
|
|
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
|
{
|
|
for (Facing enumfacing : FACING.getStates())
|
|
{
|
|
if (this.canPlaceAt(worldIn, pos, enumfacing))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private boolean canPlaceAt(World worldIn, BlockPos pos, Facing facing)
|
|
{
|
|
BlockPos blockpos = pos.offset(facing.getOpposite());
|
|
boolean flag = facing.getAxis().isHorizontal();
|
|
return flag && isBlockNormalCube(worldIn, blockpos, true) || facing.equals(Facing.UP) && this.canPlaceOn(worldIn, blockpos);
|
|
}
|
|
|
|
/**
|
|
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
|
* IBlockstate
|
|
*/
|
|
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
|
{
|
|
if (this.canPlaceAt(worldIn, pos, facing))
|
|
{
|
|
return this.getState().withProperty(FACING, facing);
|
|
}
|
|
else
|
|
{
|
|
for (Facing enumfacing : Facing.Plane.HORIZONTAL)
|
|
{
|
|
if (isBlockNormalCube(worldIn, pos.offset(enumfacing.getOpposite()), true))
|
|
{
|
|
return this.getState().withProperty(FACING, enumfacing);
|
|
}
|
|
}
|
|
|
|
return this.getState();
|
|
}
|
|
}
|
|
|
|
public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state)
|
|
{
|
|
this.checkForDrop(worldIn, pos, state);
|
|
}
|
|
|
|
/**
|
|
* Called when a neighboring block changes.
|
|
*/
|
|
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
|
{
|
|
this.onNeighborChangeInternal(worldIn, pos, state);
|
|
}
|
|
|
|
protected boolean onNeighborChangeInternal(World worldIn, BlockPos pos, State state)
|
|
{
|
|
if (!this.checkForDrop(worldIn, pos, state))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Facing enumfacing = (Facing)state.getValue(FACING);
|
|
Facing.Axis enumfacing$axis = enumfacing.getAxis();
|
|
Facing enumfacing1 = enumfacing.getOpposite();
|
|
boolean flag = false;
|
|
|
|
if (enumfacing$axis.isHorizontal() && !isBlockNormalCube(worldIn, pos.offset(enumfacing1), true))
|
|
{
|
|
flag = true;
|
|
}
|
|
else if (enumfacing$axis.isVertical() && !this.canPlaceOn(worldIn, pos.offset(enumfacing1)))
|
|
{
|
|
flag = true;
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
this.dropBlockAsItem(worldIn, pos, state, 0);
|
|
worldIn.setBlockToAir(pos);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected boolean checkForDrop(World worldIn, BlockPos pos, State state)
|
|
{
|
|
if (state.getBlock() == this && this.canPlaceAt(worldIn, pos, (Facing)state.getValue(FACING)))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (worldIn.getState(pos).getBlock() == this)
|
|
{
|
|
this.dropBlockAsItem(worldIn, pos, state, 0);
|
|
worldIn.setBlockToAir(pos);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ray traces through the blocks collision from start vector to end vector returning a ray trace hit.
|
|
*/
|
|
public HitPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end)
|
|
{
|
|
Facing enumfacing = (Facing)worldIn.getState(pos).getValue(FACING);
|
|
float f = 0.15F;
|
|
|
|
if (enumfacing == Facing.EAST)
|
|
{
|
|
this.setBlockBounds(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f);
|
|
}
|
|
else if (enumfacing == Facing.WEST)
|
|
{
|
|
this.setBlockBounds(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f);
|
|
}
|
|
else if (enumfacing == Facing.SOUTH)
|
|
{
|
|
this.setBlockBounds(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F);
|
|
}
|
|
else if (enumfacing == Facing.NORTH)
|
|
{
|
|
this.setBlockBounds(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F);
|
|
}
|
|
else
|
|
{
|
|
f = 0.1F;
|
|
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.6F, 0.5F + f);
|
|
}
|
|
|
|
return super.collisionRayTrace(worldIn, pos, start, end);
|
|
}
|
|
|
|
public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
|
|
{
|
|
Facing enumfacing = (Facing)state.getValue(FACING);
|
|
double d0 = (double)pos.getX() + 0.5D;
|
|
double d1 = (double)pos.getY() + 0.7D;
|
|
double d2 = (double)pos.getZ() + 0.5D;
|
|
double d3 = 0.22D;
|
|
double d4 = 0.27D;
|
|
|
|
if (enumfacing.getAxis().isHorizontal())
|
|
{
|
|
Facing enumfacing1 = enumfacing.getOpposite();
|
|
worldIn.spawnParticle(ParticleType.SMOKE_NORMAL, d0 + d4 * (double)enumfacing1.getFrontOffsetX(), d1 + d3, d2 + d4 * (double)enumfacing1.getFrontOffsetZ(), 0.0D, 0.0D, 0.0D);
|
|
worldIn.spawnParticle(ParticleType.FLAME, d0 + d4 * (double)enumfacing1.getFrontOffsetX(), d1 + d3, d2 + d4 * (double)enumfacing1.getFrontOffsetZ(), 0.0D, 0.0D, 0.0D);
|
|
}
|
|
else
|
|
{
|
|
worldIn.spawnParticle(ParticleType.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D);
|
|
worldIn.spawnParticle(ParticleType.FLAME, d0, d1, d2, 0.0D, 0.0D, 0.0D);
|
|
}
|
|
}
|
|
|
|
public BlockLayer getBlockLayer()
|
|
{
|
|
return BlockLayer.CUTOUT;
|
|
}
|
|
|
|
/**
|
|
* Convert the given metadata into a BlockState for this Block
|
|
*/
|
|
public State getStateFromMeta(int meta)
|
|
{
|
|
State iblockstate = this.getState();
|
|
|
|
switch (meta)
|
|
{
|
|
case 1:
|
|
iblockstate = iblockstate.withProperty(FACING, Facing.EAST);
|
|
break;
|
|
|
|
case 2:
|
|
iblockstate = iblockstate.withProperty(FACING, Facing.WEST);
|
|
break;
|
|
|
|
case 3:
|
|
iblockstate = iblockstate.withProperty(FACING, Facing.SOUTH);
|
|
break;
|
|
|
|
case 4:
|
|
iblockstate = iblockstate.withProperty(FACING, Facing.NORTH);
|
|
break;
|
|
|
|
case 5:
|
|
default:
|
|
iblockstate = iblockstate.withProperty(FACING, Facing.UP);
|
|
}
|
|
|
|
return iblockstate;
|
|
}
|
|
|
|
/**
|
|
* Convert the BlockState into the correct metadata value
|
|
*/
|
|
public int getMetaFromState(State state)
|
|
{
|
|
int i = 0;
|
|
|
|
switch ((Facing)state.getValue(FACING))
|
|
{
|
|
case EAST:
|
|
i = i | 1;
|
|
break;
|
|
|
|
case WEST:
|
|
i = i | 2;
|
|
break;
|
|
|
|
case SOUTH:
|
|
i = i | 3;
|
|
break;
|
|
|
|
case NORTH:
|
|
i = i | 4;
|
|
break;
|
|
|
|
case DOWN:
|
|
case UP:
|
|
default:
|
|
i = i | 5;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
protected Property[] getProperties()
|
|
{
|
|
return new Property[] {FACING};
|
|
}
|
|
|
|
public Model getModel(ModelProvider provider, String name, State state) {
|
|
if(state.getValue(FACING) == Facing.UP)
|
|
return provider.getModel(name)
|
|
.add(7, 0, 7, 9, 10, 9).noShade()
|
|
.d().uv(7, 13, 9, 15).noCull()
|
|
.u().uv(7, 6, 9, 8).noCull()
|
|
.add(7, 0, 0, 9, 16, 16).noShade()
|
|
.w().uv(0, 0, 16, 16).noCull()
|
|
.e().uv(0, 0, 16, 16).noCull()
|
|
.add(0, 0, 7, 16, 16, 9).noShade()
|
|
.n().uv(0, 0, 16, 16).noCull()
|
|
.s().uv(0, 0, 16, 16).noCull();
|
|
else
|
|
return provider.getModel(name)
|
|
.add(-1, 3.5f, 7, 1, 13.5f, 9).noShade().rotate(0, 3.5f, 8, Facing.Axis.Z, -22.5f, false)
|
|
.d().uv(7, 13, 9, 15).noCull()
|
|
.u().uv(7, 6, 9, 8).noCull()
|
|
.add(-1, 3.5f, 0, 1, 19.5f, 16).noShade().rotate(0, 3.5f, 8, Facing.Axis.Z, -22.5f, false)
|
|
.w().uv(0, 0, 16, 16).noCull()
|
|
.e().uv(0, 0, 16, 16).noCull()
|
|
.add(-8, 3.5f, 7, 8, 19.5f, 9).noShade().rotate(0, 3.5f, 8, Facing.Axis.Z, -22.5f, false)
|
|
.n().uv(0, 0, 16, 16).noCull()
|
|
.s().uv(0, 0, 16, 16).noCull()
|
|
.rotate(ModelRotation.getEastRot(state.getValue(FACING), false));
|
|
}
|
|
}
|