I have two blocks that don't seem to mark sub chunks as containing anything, so when there aren't any other blocks in the sub chunk it doesn't render.
My block classes:
BlockCatwalk
package com.thecodewarrior.catwalks;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.ForgeEventFactory;
import buildcraft.api.tools.IToolWrench;
import codechicken.lib.raytracer.ExtendedMOP;
import codechicken.lib.raytracer.IndexedCuboid6;
import codechicken.lib.raytracer.RayTracer;
import codechicken.lib.vec.BlockCoord;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Vector3;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockCatwalk extends Block implements ICagedLadderConnectable {
public boolean lights;
public boolean bottom;
private RayTracer rayTracer = new RayTracer();
public IIcon transparent;
public IIcon sideTexture;
public IIcon bottomTexture;
public IIcon bottomTextureWithLights;
public IIcon sideTextureWithLights;
public IIcon bottomLights;
public IIcon sideLights;
public BlockCatwalk(boolean lights, boolean bottom) {
super(Material.iron);
setHardness(1.0F);
setStepSound(Block.soundTypeMetal);
setBlockName("catwalk");
if(lights && !bottom)
setCreativeTab(CreativeTabs.tabTransport);
// setHarvestLevel("wrench", 0);
// setHarvestLevel("pickaxe", 0);
this.lights = lights;
this.bottom = bottom;
}
//==============================================================================
// Clicking methods
//==============================================================================
public float getPlayerRelativeBlockHardness(EntityPlayer player, World world, int x, int y, int z){
int metadata = world.getBlockMetadata(x, y, z);
float hardness = blockHardness;
if(player.getHeldItem() != null ) {
boolean shouldBeSoft = false;
if(player.getHeldItem().getItem() instanceof IToolWrench)
shouldBeSoft = true;
Set<String> toolClasses = player.getHeldItem().getItem().getToolClasses(player.getHeldItem());
if(toolClasses.contains("wrench"))
shouldBeSoft = true;
if(shouldBeSoft)
hardness = blockHardness/10;
}
return player.getBreakSpeed(this, false, metadata, x, y, z) / hardness / 30F;
}
@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) {
MovingObjectPosition hit = RayTracer.retraceBlock(world, player, x, y, z);
ForgeDirection side = ForgeDirection.UP;
if (hit != null) {
side = (ForgeDirection) ( (ExtendedMOP) hit ).data;
}
if(player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() instanceof IToolWrench) {
if(player.isSneaking()) {
this.dropBlockAsItem(world, x, y, z, 0, 0);
world.setBlockToAir(x,y,z);
this.updateNeighborSides(world, x, y, z, false);
}
}
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int blockSide, float hitX, float hitY, float hitZ) {
MovingObjectPosition hit = RayTracer.retraceBlock(world, player, x, y, z);
ForgeDirection side = ForgeDirection.UP;
if (hit != null) {
side = (ForgeDirection) ( (ExtendedMOP) hit ).data;
}
if(player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() instanceof IToolWrench) {
if(player.isSneaking()) {
if(this.lights) {
if(!world.isRemote) {
world.spawnEntityInWorld(new EntityItem(world, x+0.5, y+0.5, z+0.5, new ItemStack(CatwalkMod.itemRopeLight, 1)));
updateData(world, x, y, z, ForgeDirection.UP, false, false);
}
}
} else {
if(side != ForgeDirection.UP) {
updateData(world,x,y,z, side, !getOpenState(world,x,y,z, side), this.lights);
}
}
}
if(player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() instanceof ItemRopeLight && this.lights == false) {
updateData(world, x, y, z, ForgeDirection.UP, false, true);
if(!player.capabilities.isCreativeMode)
player.getCurrentEquippedItem().stackSize--;
}
//
// if()
return false;
}
//==============================================================================
// Place/Destroy methods
//==============================================================================
@Override
public void onBlockPlacedBy(World w, int x, int y, int z, EntityLivingBase e, ItemStack s) {
updateNeighborSides(w,x,y,z,true);
}
public void onBlockDestroyedByPlayer(World w, int x, int y, int z, int meta) {
updateNeighborSides(w,x,y,z,false);
}
public void onBlockDestroyedByExplosion(World w, int x, int y, int z, Explosion e) {
updateNeighborSides(w,x,y,z,false);
}
//==============================================================================
// Drop methods
//==============================================================================
public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int metadata, int fortune)
{
ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
ret.add(new ItemStack(
Item.getItemFromBlock(CatwalkMod.catwalkUnlitBottom),
1));
if(this.lights) {
ret.add(new ItemStack(
CatwalkMod.itemRopeLight,
1
));
}
return ret;
}
public boolean canHarvestBlock(EntityPlayer player, int meta)
{
return true;
}
//==============================================================================
// Block highlight raytrace methods
//==============================================================================
@Override
public MovingObjectPosition collisionRayTrace(World world, int x, int y, int z, Vec3 start, Vec3 end) {
List<IndexedCuboid6> cuboids = new LinkedList<IndexedCuboid6>();
float px = 1/16F;
int meta = world.getBlockMetadata(x, y, z);
// System.out.println("META: " + (meta & );
boolean ovr = false;
double d = 0;
float smallHeight = 0.25f;
if(bottom) {
d = 0.125;
//cuboids.add(new IndexedCuboid6(Hitboxes.BOTTOM, new Cuboid6(x+ px, y+ 0, z+ px, x+ 1-px, y+ px, z+ 1-px)));
} else {
d = 0.25;
}
cuboids.add(new IndexedCuboid6(ForgeDirection.DOWN, new Cuboid6(x+ d, y+ 0, z+ d, x+ 1-d, y+ px, z+ 1-d)));
float ym = 1;
if((meta & == 0 || ovr) { ym = 1; } else { ym = smallHeight; }
cuboids.add(new IndexedCuboid6(ForgeDirection.NORTH, new Cuboid6(
x+ 0, y+ 0, z+ 0,
x+ 1, y+ ym, z+ px
)));
if((meta & 4) == 0 || ovr) { ym = 1; } else { ym = smallHeight; }
cuboids.add(new IndexedCuboid6(ForgeDirection.SOUTH, new Cuboid6(
x+ 0, y+ 0, z+ 1-px,
x+ 1, y+ ym, z+ 1
)));
if((meta & 2) == 0 || ovr) { ym = 1; } else { ym = smallHeight; }
cuboids.add(new IndexedCuboid6(ForgeDirection.WEST, new Cuboid6(
x+ 0, y+ 0, z+ 0,
x+ px, y+ ym, z+ 1
)));
if((meta & 1) == 0 || ovr) { ym = 1; } else { ym = smallHeight; }
cuboids.add(new IndexedCuboid6(ForgeDirection.EAST, new Cuboid6(
x+ 1-px, y+ 0, z+ 0,
x+ 1, y+ ym, z+ 1
)));
//new BlockCoord(x, y, z), this
ExtendedMOP mop = (ExtendedMOP) rayTracer.rayTraceCuboids(new Vector3(start), new Vector3(end), cuboids, new BlockCoord(x, y, z), this);
if(mop != null) {
if(mop.sideHit == ((ForgeDirection)mop.data).getOpposite().ordinal()) {
mop.sideHit = ((ForgeDirection)mop.data).ordinal();
}
}
// System.out.println(mop.data);
return mop;
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onBlockHighlight(DrawBlockHighlightEvent event) {
if (event.target.typeOfHit == MovingObjectType.BLOCK && event.player.worldObj.getBlock(event.target.blockX, event.target.blockY, event.target.blockZ) == this)
RayTracer.retraceBlock(event.player.worldObj, event.player, event.target.blockX, event.target.blockY, event.target.blockZ);
}
//==============================================================================
// Collision methods
//==============================================================================
@Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
if (FMLCommonHandler.instance().getEffectiveSide() != Side.CLIENT)
return;
double mul = 1.315;
if(entity instanceof EntityPlayer && ( (EntityPlayer)entity).isSneaking() ) {
mul = 2.860578;
}
CatwalkMod.proxy.speedupPlayer(world, entity, mul);
}
@Override
public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB blockBounds, List list, Entity collidingEntity) {
if(collidingEntity == null)
return;
float px = 1/16F;
int meta = world.getBlockMetadata(x, y, z);
float top = 1.5F;
if(collidingEntity.isSneaking())
top = 1.0F;
boolean ovr = false;
Cuboid6 oldBounds = new Cuboid6(
this.getBlockBoundsMinX(), this.getBlockBoundsMinY(), this.getBlockBoundsMinZ(),
this.getBlockBoundsMaxX(), this.getBlockBoundsMaxY(), this.getBlockBoundsMaxZ()
);
if(bottom) {
this.setBlockBounds(0, 0, 0, 1, px, 1);
super.addCollisionBoxesToList(world, x, y, z, blockBounds, list, collidingEntity);
}
if((meta & == 0 || ovr) {
if(getStepConnect(world,x,y,z,ForgeDirection.NORTH)) {
this.setBlockBounds(0, 0, 0, 1, 1, px);
} else {
this.setBlockBounds(0, 0, 0, 1, top, px);
}
super.addCollisionBoxesToList(world, x, y, z, blockBounds, list, collidingEntity);
}
if((meta & 4) == 0 || ovr) {
if(getStepConnect(world,x,y,z,ForgeDirection.SOUTH)) {
this.setBlockBounds(0, 0, 1-px, 1, 1, 1);
} else {
this.setBlockBounds(0, 0, 1-px, 1, top, 1);
}
super.addCollisionBoxesToList(world, x, y, z, blockBounds, list, collidingEntity);
}
if((meta & 2) == 0 || ovr) {
if(getStepConnect(world,x,y,z,ForgeDirection.WEST)) {
this.setBlockBounds(0, 0, 0, px, 1, 1);
} else {
this.setBlockBounds(0, 0, 0, px, top, 1);
}
super.addCollisionBoxesToList(world, x, y, z, blockBounds, list, collidingEntity);
}
if((meta & 1) == 0 || ovr) {
if(getStepConnect(world,x,y,z,ForgeDirection.EAST)) {
this.setBlockBounds(1-px, 0, 0, 1, 1, 1);
} else {
this.setBlockBounds(1-px, 0, 0, 1, top, 1);
}
super.addCollisionBoxesToList(world, x, y, z, blockBounds, list, collidingEntity);
}
oldBounds.setBlockBounds(this);
// this.setBlockBounds(0, 0, 0, 1, 1, 1);
}
public boolean getBlocksMovement(IBlockAccess p_149655_1_, int p_149655_2_, int p_149655_3_, int p_149655_4_)
{
return false;
}
//==============================================================================
// Texture methods
//==============================================================================
@Override
public void registerBlockIcons(IIconRegister reg) {
transparent = reg.registerIcon("catwalks:transparent");
sideTexture = reg.registerIcon("catwalks:side");
bottomTexture = reg.registerIcon("catwalks:bottom");
sideTextureWithLights = reg.registerIcon("catwalks:side_with_lights");
bottomTextureWithLights = reg.registerIcon("catwalks:bottom_with_lights");
sideLights = reg.registerIcon("catwalks:side_lights");
bottomLights = reg.registerIcon("catwalks:bottom_lights");
}
@Override
public IIcon getIcon(int _side, int meta) {
ForgeDirection dir = ForgeDirection.VALID_DIRECTIONS[_side];
/**/
if(dir == ForgeDirection.DOWN) {
if(bottom) {
return lights ? bottomTextureWithLights : bottomTexture;
}
}
if(dir == ForgeDirection.NORTH && (meta & < 1) {
return lights ? sideTextureWithLights : sideTexture;
}
if(dir == ForgeDirection.SOUTH && (meta & 4) < 1) {
return lights ? sideTextureWithLights : sideTexture;
}
if(dir == ForgeDirection.WEST && (meta & 2) < 1) {
return lights ? sideTextureWithLights : sideTexture;
}
if(dir == ForgeDirection.EAST && (meta & 1) < 1) {
return lights ? sideTextureWithLights : sideTexture;
}
return transparent; /**/
}
@Override
public boolean isSideSolid(IBlockAccess w, int x, int y, int z, ForgeDirection side) {
return !getOpenState(w,x,y,z,side);//getOpenState(w, x-side.offsetX, y-side.offsetY, z-side.offsetZ, side.getOpposite());
}
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess w, int x, int y, int z, int _side)
{
ForgeDirection dir = ForgeDirection.getOrientation(_side);
int meta = w.getBlockMetadata(x-dir.offsetX, y-dir.offsetY, z-dir.offsetZ);
if(dir == ForgeDirection.DOWN && (
bottom == false ||
( w.isSideSolid(x, y, z, ForgeDirection.UP, false) && !(w.getBlock(x,y,z) instanceof BlockCatwalk) )
)) {
return false;
}
if(dir == ForgeDirection.NORTH && (
(meta & > 0 ||
( w.isSideSolid(x, y, z, ForgeDirection.SOUTH, false) && !(w.getBlock(x,y,z) instanceof BlockCatwalk) )
)) {
return false;
}
if(dir == ForgeDirection.SOUTH && (
(meta & 4) > 0 ||
( w.isSideSolid(x, y, z, ForgeDirection.NORTH, false) )// && !(w.getBlock(x,y,z) instanceof BlockCatwalk) )
)) {
return false;
}
if(dir == ForgeDirection.WEST && (
(meta & 2) > 0 ||
( w.isSideSolid(x, y, z, ForgeDirection.EAST, false) && !(w.getBlock(x,y,z) instanceof BlockCatwalk) )
)) {
return false;
}
if(dir == ForgeDirection.EAST && (
(meta & 1) > 0 ||
( w.isSideSolid(x, y, z, ForgeDirection.WEST, false) )// && !(w.getBlock(x,y,z) instanceof BlockCatwalk) )
)) {
return false;
}
return true;
}
/**
* Gets the light value of the specified block coords. Args: x, y, z
*/
public int getLightValue()
{
return this.lights ? 15 : 0;
}
public int getRenderType(){
return CatwalkMod.catwalkRenderType;
}
@SideOnly(Side.CLIENT)
public int getRenderBlockPass()
{
return 0;
}
public boolean isOpaqueCube()
{
return false;
}
}
(I removed all the code for accessing data etc. here's the full class http://pastebin.com/HcXbYvVV)
BlockCagedLadder:
package com.thecodewarrior.catwalks;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import buildcraft.api.tools.IToolWrench;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.common.util.ForgeDirection;
import codechicken.lib.raytracer.ExtendedMOP;
import codechicken.lib.raytracer.IndexedCuboid6;
import codechicken.lib.raytracer.RayTracer;
import codechicken.lib.vec.BlockCoord;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Vector3;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockCagedLadder extends Block implements ICustomLadderVelocity, ICagedLadderConnectable {
RayTracer rayTracer = new RayTracer();
public ForgeDirection direction;
public boolean lights;
public IIcon bottom;
public IIcon bottom_with_lights;
public IIcon bottom_lights;
public IIcon ladder;
public IIcon ladder_with_lights;
public IIcon ladder_lights;
public IIcon front;
public IIcon front_with_lights;
public IIcon front_lights;
public IIcon side;
public IIcon side_with_lights;
public IIcon side_lights;
public IIcon landing;
public IIcon landing_side;
public IIcon transparent;
public Map<RelativeSide, Cuboid6> closed = new HashMap<RelativeSide, Cuboid6>();
public Map<RelativeSide, Cuboid6> open = new HashMap<RelativeSide, Cuboid6>();
// meta: bottom, front, left, right
public BlockCagedLadder(ForgeDirection direction, boolean lights) {
super(Material.iron);
setHardness(1.0F);
setStepSound(Block.soundTypeMetal);
float px = 1/16F;
setBlockBounds(px, 0, px, 1-px, 1, 1-px);
setBlockName("cagedladder");
setStepSound(soundTypeLadder);
if(direction == ForgeDirection.NORTH && !lights)
setCreativeTab(CreativeTabs.tabTransport);
setHarvestLevel("wrench", 0);
setHarvestLevel("pickaxe", 0);
this.lights = lights;
this.direction = direction;
initHitBoxes();
}
//==============================================================================
// Place/Destroy methods
//==============================================================================
@Override
public void onBlockPlacedBy(World w, int x, int y, int z, EntityLivingBase e, ItemStack s) {
updateNeighborSides(w,x,y,z,true);
}
public void onBlockDestroyedByPlayer(World w, int x, int y, int z, int meta) {
updateNeighborSides(w,x,y,z,false);
}
public void onBlockDestroyedByExplosion(World w, int x, int y, int z, Explosion e) {
updateNeighborSides(w,x,y,z,false);
}
public void updateNeighborSides(World world, int x, int y, int z, boolean self) {
Block b = world.getBlock(x, y+1, z);
if(b instanceof BlockCagedLadder) {
// this.updateOpenData(world, x, y+1, z, RelativeSide.BOTTOM, false);
// System.out.println("---");
( (BlockCagedLadder)b ).updateBottom(world, x, y+1, z);
// System.out.println("---");
}
if(self)
this.updateBottom(world, x, y, z);
}
public void updateBottom(World world, int x, int y, int z) {
// System.out.println("UPD");
if(world.getBlock(x, y-1, z) instanceof BlockCagedLadder) {
updateOpenData(world, x, y, z, RelativeSide.BOTTOM, true);
} else {
updateOpenData(world, x, y, z, RelativeSide.BOTTOM, false);
}
}
//==============================================================================
// Clicking methods
//==============================================================================
public float getPlayerRelativeBlockHardness(EntityPlayer player, World world, int x, int y, int z){
int metadata = world.getBlockMetadata(x, y, z);
float hardness = blockHardness;
if(player.getHeldItem() != null ) {
boolean shouldBeSoft = false;
if(player.getHeldItem().getItem() instanceof IToolWrench)
shouldBeSoft = true;
Set<String> toolClasses = player.getHeldItem().getItem().getToolClasses(player.getHeldItem());
if(toolClasses.contains("wrench"))
shouldBeSoft = true;
if(shouldBeSoft)
hardness = blockHardness/10;
}
return player.getBreakSpeed(this, false, metadata, x, y, z) / hardness / 30F;
}
@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) {
MovingObjectPosition hit = RayTracer.retraceBlock(world, player, x, y, z);
RelativeSide side = RelativeSide.TOP;
if (hit != null) {
side = (RelativeSide) ( (ExtendedMOP) hit ).data;
}
// if(player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() instanceof IToolWrench) {
// if(player.isSneaking()) {
//
// this.dropBlockAsItem(world, x, y, z, 0, 0);
// world.setBlockToAir(x,y,z);
// this.updateNeighborSides(world, x, y, z, false);
// }
// }
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int blockSide, float hitX, float hitY, float hitZ) {
MovingObjectPosition hit = RayTracer.retraceBlock(world, player, x, y, z);
RelativeSide side = RelativeSide.TOP;
if (hit != null) {
side = (RelativeSide) ( (ExtendedMOP) hit ).data;
}
// System.out.println(side);
ItemStack handStack = player.getCurrentEquippedItem();
if(handStack != null && handStack.getItem() instanceof IToolWrench) {
if(player.isSneaking()) {
if(this.lights) {
if(!world.isRemote) {
world.spawnEntityInWorld(new EntityItem(world, x+0.5, y+0.5, z+0.5, new ItemStack(CatwalkMod.itemRopeLight, 1)));
updateIdData(world, x, y, z, direction, false);
}
}
} else {
// System.out.println("META: " + world.getBlockMetadata(x,y,z));
updateOpenData(world, x, y, z, side, !isOpen(side, world.getBlockMetadata(x, y, z)));
// System.out.println("META2: " + world.getBlockMetadata(x,y,z));
}
}
if(player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() instanceof ItemRopeLight && this.lights == false) {
updateIdData(world, x, y, z, direction, true);
if(!player.capabilities.isCreativeMode)
player.getCurrentEquippedItem().stackSize--;
}
return false;
}
//==============================================================================
// ILadderCustomVelocity methods
//==============================================================================
@Override
public boolean isOnLadder(IBlockAccess world, int x, int y, int z, EntityLivingBase entity)
{
float px = 1/16F;
float px2 = 2*px;
float d = px*3;
return CatwalkMod.options.fullBlockLadder || entity.boundingBox.intersectsWith(AxisAlignedBB.getBoundingBox(x+d, y, z+d, x+1-d, y+1, z+1-d));
}
public double getLadderVelocity(IBlockAccess world, int x, int y, int z, EntityLivingBase entity) {
return entity.isSneaking() ? 0.15D : 0.25D;
}
public double getLadderFallVelocity(IBlockAccess world, int x, int y, int z, EntityLivingBase entity) {
return 0.25D;
}
//==============================================================================
// Block highlight raytrace methods
//==============================================================================
@Override
public MovingObjectPosition collisionRayTrace(World world, int x, int y, int z, Vec3 start, Vec3 end) {
List<IndexedCuboid6> cuboids = new LinkedList<IndexedCuboid6>();
float ym = 1;
float px = 1/16F;
float px2 = 2*px;
float outsideDistance = 1/32F;
float insideDistance = 3/32F;
float out = px/2;
float in = out+px;
int meta = world.getBlockMetadata(x, y, z);
if(!(world.getBlock(x, y+1, z) instanceof BlockCagedLadder)) {
addToList(x, y, z, cuboids, RelativeSide.TOP, open.get(RelativeSide.TOP));
}
for (RelativeSide rs : RelativeSide.values()) {
if(rs == RelativeSide.LADDER) {
addToList(x, y, z, cuboids, rs, closed.get(rs));
continue;
}
if(rs == RelativeSide.TOP) {
continue;
}
if(isOpen(rs, meta)) {
addToList(x, y, z, cuboids, rs, open.get(rs));
} else {
addToList(x, y, z, cuboids, rs, closed.get(rs));
}
}
ExtendedMOP mop = (ExtendedMOP) rayTracer.rayTraceCuboids(new Vector3(start), new Vector3(end), cuboids, new BlockCoord(x, y, z), this);
if(mop != null) {
if(mop.sideHit == RelativeSide.RStoFD( (RelativeSide)mop.data, direction).getOpposite().ordinal()) {
mop.sideHit = ForgeDirection.getOrientation(mop.sideHit).getOpposite().ordinal();
}
}
// System.out.println(mop.data);
return mop;
}
public void addToList(int x, int y, int z, List<IndexedCuboid6> list, Object data, Cuboid6 cuboid) {
list.add( new IndexedCuboid6(data, new Cuboid6(
x+cuboid.min.x, y+cuboid.min.y, z+cuboid.min.z,
x+cuboid.max.x, y+cuboid.max.y, z+cuboid.max.z
)) );
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onBlockHighlight(DrawBlockHighlightEvent event) {
if (event.target.typeOfHit == MovingObjectType.BLOCK && event.player.worldObj.getBlock(event.target.blockX, event.target.blockY, event.target.blockZ) == this)
RayTracer.retraceBlock(event.player.worldObj, event.player, event.target.blockX, event.target.blockY, event.target.blockZ);
}
//==============================================================================
// Texture methods
//==============================================================================
@Override
public void registerBlockIcons(IIconRegister reg) {
transparent = reg.registerIcon("catwalks:transparent");
bottom = reg.registerIcon("catwalks:ladder/bottom");
bottom_with_lights = reg.registerIcon("catwalks:ladder/bottom_with_lights");
bottom_lights = reg.registerIcon("catwalks:ladder/bottom_lights");
ladder = reg.registerIcon("catwalks:ladder/ladder");
ladder_with_lights = reg.registerIcon("catwalks:ladder/ladder_with_lights");
ladder_lights = reg.registerIcon("catwalks:ladder/ladder_lights");
front = reg.registerIcon("catwalks:ladder/front");
front_with_lights = reg.registerIcon("catwalks:ladder/front_with_lights");
front_lights = reg.registerIcon("catwalks:ladder/front_lights");
side = reg.registerIcon("catwalks:ladder/side");
side_with_lights = reg.registerIcon("catwalks:ladder/side_with_lights");
side_lights = reg.registerIcon("catwalks:ladder/side_lights");
landing = reg.registerIcon("catwalks:ladder/landing");
landing_side = reg.registerIcon("catwalks:ladder/landing_side");
}
@Override
public IIcon getIcon(int _side, int meta) {
RelativeSide dir = RelativeSide.FDtoRS( ForgeDirection.getOrientation(_side), direction );
switch(dir) {
case LADDER:
if(lights)
return ladder_with_lights;
else
return ladder;
case FRONT:
if(lights)
return front_with_lights;
else
return front;
case LEFT:
case RIGHT:
if(lights)
return side_with_lights;
else
return side;
case BOTTOM:
if(lights)
return bottom_with_lights;
else
return bottom;
}
return transparent;
}
public IIcon getLightIcon(int _side, int meta) {
RelativeSide dir = RelativeSide.FDtoRS( ForgeDirection.getOrientation(_side) , direction);
switch(dir) {
case LADDER:
return ladder_lights;
case FRONT:
return front_lights;
case LEFT:
case RIGHT:
return side_lights;
case BOTTOM:
return transparent;//bottom_lights;
}
return transparent;
}
@Override
public boolean isSideSolid(IBlockAccess w, int x, int y, int z, ForgeDirection side) {
if(side == ForgeDirection.UP)
return false;
return !isOpen(RelativeSide.FDtoRS(side, direction), w.getBlockMetadata(x,y,z));
}
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess w, int x, int y, int z, int _side)
{
ForgeDirection dir = ForgeDirection.getOrientation(_side);
if(dir == ForgeDirection.DOWN) {
if(w.isSideSolid(x, y, z, ForgeDirection.DOWN, false))
return false;
}
int meta = w.getBlockMetadata(x-dir.offsetX, y-dir.offsetY, z-dir.offsetZ);
if(isOpen(RelativeSide.FDtoRS(dir, direction), meta)) {
return false;
}
return true;
}
//==============================================================================
// Collision methods
//==============================================================================
@Override
public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB blockBounds, List list, Entity collidingEntity) {
if(collidingEntity == null)
return;
float px = 1/16F;
float out = px;///2;
float in = out+px;
int meta = world.getBlockMetadata(x, y, z);
if(!isOpen(RelativeSide.FDtoRS(ForgeDirection.NORTH, direction), meta)) {
addToList(world, x, y, z, blockBounds, list, out, 0, out, 1-out, 1, in);
}
if(!isOpen(RelativeSide.FDtoRS(ForgeDirection.SOUTH, direction), meta)) {
addToList(world, x, y, z, blockBounds, list, out, 0, 1-out, 1-out, 1, 1-in);
}
if(!isOpen(RelativeSide.FDtoRS(ForgeDirection.EAST, direction), meta)) {
addToList(world, x, y, z, blockBounds, list, 1-in, 0, out, 1-out, 1, 1-out);
}
if(!isOpen(RelativeSide.FDtoRS(ForgeDirection.WEST, direction), meta)) {
addToList(world, x, y, z, blockBounds, list, out, 0, out, in, 1, 1-out);
}
}
public void addToList(World world, int x, int y, int z, AxisAlignedBB blockBounds, List list, double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
AxisAlignedBB axisalignedbb1 = AxisAlignedBB.getBoundingBox(
(double)x + minX, (double)y + minY, (double)z + minZ,
(double)x + maxX, (double)y + maxY, (double)z + maxZ
);
if (axisalignedbb1 != null && blockBounds.intersectsWith(axisalignedbb1))
{
list.add(axisalignedbb1);
}
}
@Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
// System.out.println("COLLIDE!");
}
//==============================================================================
// Render type methods
//==============================================================================
public int getRenderType(){
return CatwalkMod.ladderRenderType;
}
@SideOnly(Side.CLIENT)
public int getRenderBlockPass()
{
return 0;
}
public boolean isOpaqueCube()
{
return false;
}
@SideOnly(Side.CLIENT)
public boolean isBlockNormalCube()
{
return super.isBlockNormalCube();
}
public boolean isNormalCube()
{
return false;
}
public static enum RelativeSide {
LADDER, FRONT, LEFT, RIGHT, TOP, BOTTOM;
}
}
(I removed all the code for accessing data etc. here's the full class http://pastebin.com/8z2dUkAj)
The code for the BlockCagedLadder ISBRH is quite complex (~400 lines), so unless you want it I'll just leave it out.
package com.thecodewarrior.catwalks;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
public class CatwalkRenderer implements ISimpleBlockRenderingHandler {
@Override
public void renderInventoryBlock(Block block, int meta, int modelId,
RenderBlocks renderer) {
boolean lights = false;
boolean bottom = true;
if(block instanceof BlockCatwalk) {
lights = ( (BlockCatwalk)block).lights;
bottom = ( (BlockCatwalk)block).bottom;
}
renderer.overrideBlockBounds(0, 0, 0, 1, 1, 1);
Tessellator tessellator = Tessellator.instance;
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
tessellator.startDrawingQuads();
renderer.renderFromInside = true;
renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, meta));
renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 1, meta));
renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 2, meta));
renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 3, meta));
renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 4, meta));
renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, meta));
renderer.renderFromInside = false;
renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, meta));
renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 1, meta));
renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 2, meta));
renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 3, meta));
renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 4, meta));
renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, meta));
tessellator.draw();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
renderer.unlockBlockBounds();
}
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z,
Block block, int modelId, RenderBlocks renderer) {
boolean lights = false;
boolean bottom = true;
if(block instanceof BlockCatwalk) {
lights = ( (BlockCatwalk)block).lights;
bottom = ( (BlockCatwalk)block).bottom;
}
// renderer.renderFromInside = true;
// renderer.renderStandardBlock(block, x, y, z);
// RenderBlocks renderer = new RenderBlocks(world);
// renderer.setRenderFromInside(true);
// renderer.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
renderer.overrideBlockBounds(0, 0, 0, 1, 1, 1);
renderer.renderFromInside = true;
renderer.renderStandardBlock(block, x, y, z);
renderer.renderFromInside = false;
renderer.renderStandardBlock(block, x, y, z);
boolean force = false;
if(lights) {
BlockCatwalk b = ((BlockCatwalk) block);
boolean oldAO = renderer.enableAO;
renderer.enableAO = false;
Tessellator.instance.setBrightness(15728880);
renderer.renderFromInside = true;
if( b.shouldSideBeRendered(world, x, y-1, z, 0) || force)
renderer.renderFaceYNeg(b, x, y, z, b.bottomLights);
if( b.shouldSideBeRendered(world, x, y, z-1, 2) || force)
renderer.renderFaceZNeg(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x, y, z+1, 3) || force)
renderer.renderFaceZPos(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x-1, y, z, 4) || force )
renderer.renderFaceXNeg(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x+1, y, z, 5) || force )
renderer.renderFaceXPos(b, x, y, z, b.sideLights);
renderer.renderFromInside = false;
if( b.shouldSideBeRendered(world, x, y-1, z, 0) || force)
renderer.renderFaceYNeg(b, x, y, z, b.bottomLights);
if( b.shouldSideBeRendered(world, x, y, z-1, 2) || force)
renderer.renderFaceZNeg(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x, y, z+1, 3) || force)
renderer.renderFaceZPos(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x-1, y, z, 4) || force )
renderer.renderFaceXNeg(b, x, y, z, b.sideLights);
if( b.shouldSideBeRendered(world, x+1, y, z, 5) || force )
renderer.renderFaceXPos(b, x, y, z, b.sideLights);
renderer.enableAO = oldAO;
}
renderer.unlockBlockBounds();
renderer.clearOverrideBlockTexture();
return false;
}
@Override
public boolean shouldRender3DInInventory(int modelId) {
return true;
}
@Override
public int getRenderId() {
return CatwalkMod.catwalkRenderType;
}
}