Skip to content

Instantly share code, notes, and snippets.

@StillManic
Last active January 6, 2016 17:35
Show Gist options
  • Save StillManic/1ea73f1a0a7d074f6cf5 to your computer and use it in GitHub Desktop.
Save StillManic/1ea73f1a0a7d074f6cf5 to your computer and use it in GitHub Desktop.
public void preInit()
{
OBJLoader.instance.addDomain(MODID.toLowerCase());
ClientRegistry.bindTileEntitySpecialRenderer(OBJClockTileEntity.class, new OBJClockRender());
Item item8 = Item.getItemFromBlock(OBJClock.instance);
ModelLoader.setCustomModelResourceLocation(item8, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJClock.name, "inventory"));
OBJClockRender.init();
}
public static class OBJClock extends Block
{
public static final PropertyDirection FACING = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL);
public static final PropertyBool TWENTY_FOUR = PropertyBool.create("twenty_four");
public static final PropertyBool SECONDARY = PropertyBool.create("secondary");
public static final OBJClock instance = new OBJClock();
public static final String name = "OBJClock";
private ExtendedBlockState state = new ExtendedBlockState(this, new IProperty[] {FACING, TWENTY_FOUR}, new IUnlistedProperty[] {OBJModel.OBJProperty.instance});
// private String[] configNames = new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
// private int config = 0;
public OBJClock()
{
super(Material.iron);
this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(TWENTY_FOUR, false).withProperty(SECONDARY, false));
setCreativeTab(CreativeTabs.tabBlock);
setUnlocalizedName(MODID + ":" + name);
}
@Override
public boolean isOpaqueCube() { return false; }
@Override
public boolean isFullCube() { return false; }
@Override
public boolean isVisuallyOpaque() { return false; }
@Override
public boolean hasTileEntity(IBlockState state) { return !state.getValue(SECONDARY); }
@Override
public TileEntity createTileEntity(World world, IBlockState state)
{
return new OBJClockTileEntity(world, state.getValue(FACING));
}
@Override
public void setBlockBoundsBasedOnState(IBlockAccess world, BlockPos pos)
{
EnumFacing facing = world.getBlockState(pos).getValue(FACING);
switch (facing)
{
case NORTH: setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0625f); break;
case SOUTH: setBlockBounds(0.0f, 0.0f, 0.9375f, 1.0f, 1.0f, 1.0f); break;
case EAST: setBlockBounds(0.9375f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); break;
case WEST: setBlockBounds(0.0f, 0.0f, 0.0f, 0.0625f, 1.0f, 1.0f); break;
default: break;
}
}
@Override
public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side)
{
return side.getAxis() != EnumFacing.Axis.Y && world.isSideSolid(pos.offset(side.getOpposite()), side);
}
@Override
public IBlockState onBlockPlaced(World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
IBlockState retState = this.getDefaultState().withProperty(TWENTY_FOUR, false);
if (this.canPlaceBlockOnSide(world, pos, side))
{
retState = retState.withProperty(FACING, side.getOpposite());
BlockPos right = pos.offset(side.rotateY());
BlockPos left = pos.offset(side.rotateYCCW());
if (this.canPlaceBlockAt(world, pos) && this.canPlaceBlockAt(world, left) && world.isSideSolid(left.offset(side.getOpposite()), side))
{
retState = retState.withProperty(SECONDARY, false);
IBlockState secState = this.getDefaultState().withProperty(FACING, side.getOpposite()).withProperty(TWENTY_FOUR, false).withProperty(SECONDARY, true);
world.setBlockState(left, secState, 3);
}
else if (this.canPlaceBlockAt(world, pos) && this.canPlaceBlockAt(world, right) && world.isSideSolid(right.offset(side.getOpposite()), side))
{
retState = retState.withProperty(SECONDARY, true);
IBlockState primeState = this.getDefaultState().withProperty(FACING, side.getOpposite()).withProperty(TWENTY_FOUR, false).withProperty(SECONDARY, false);
world.setBlockState(right, primeState, 3);
}
}
return retState;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
{
BlockPos tilePos = state.getValue(SECONDARY) ? pos.offset(state.getValue(FACING).rotateYCCW()) : pos;
if (world.getTileEntity(tilePos) != null && world.getTileEntity(tilePos) instanceof OBJClockTileEntity)
{
world.setBlockState(tilePos, state.withProperty(TWENTY_FOUR, ((OBJClockTileEntity) world.getTileEntity(tilePos)).isTwentyFour), 3);
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state)
{
if (state.getValue(SECONDARY))
{
world.setBlockToAir(pos.offset(state.getValue(FACING).rotateYCCW()));
world.removeTileEntity(pos.offset(state.getValue(FACING).rotateYCCW()));
}
else
{
world.setBlockToAir(pos.offset(state.getValue(FACING).rotateY()));
super.breakBlock(world, pos, state);
}
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitz)
{
state = state.cycleProperty(TWENTY_FOUR);
BlockPos tilePos = state.getValue(SECONDARY) ? pos.offset(state.getValue(FACING).rotateYCCW()) : pos;
if (world.getTileEntity(tilePos) != null && world.getTileEntity(tilePos) instanceof OBJClockTileEntity)
{
((OBJClockTileEntity) world.getTileEntity(tilePos)).isTwentyFour = state.getValue(TWENTY_FOUR);
((OBJClockTileEntity) world.getTileEntity(tilePos)).facing = state.getValue(FACING);
}
return true;
}
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(FACING, EnumFacing.getHorizontal(meta & 3)).withProperty(TWENTY_FOUR, (meta & 4) > 0).withProperty(SECONDARY, (meta & 8) > 0);
}
@Override
public int getMetaFromState(IBlockState state)
{
int meta = 0;
if (state.getValue(SECONDARY)) meta |= 8;
if (state.getValue(TWENTY_FOUR)) meta |= 4;
meta |= state.getValue(FACING).getHorizontalIndex();
return meta;
}
@Override
public BlockState createBlockState()
{
return new ExtendedBlockState(this, new IProperty[] {FACING, TWENTY_FOUR, SECONDARY}, new IUnlistedProperty[] {OBJModel.OBJProperty.instance});
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
OBJModel.OBJState retState = new OBJModel.OBJState(new TRSRTransformation(state.getValue(FACING)));
if (state.getValue(SECONDARY)) retState.setHideAllConfigs();
return ((IExtendedBlockState) this.state.getBaseState()).withProperty(OBJModel.OBJProperty.instance, retState);
}
@Override
public int getRenderType()
{
return super.getRenderType();
}
}
public static class OBJClockTileEntity extends TileEntity
{
private boolean isTwentyFour = false;
private EnumFacing facing = EnumFacing.NORTH;
public OBJClockTileEntity() {}
public OBJClockTileEntity(World world, EnumFacing facing)
{
this.worldObj = world;
this.facing = facing;
}
public Pair<String, String[]> getConfigOperationFor(int index)
{
switch(index)
{
case 0: return Pair.of("hide", new String[] {"G"});
case 1: return Pair.of("show", new String[] {"E", "F"});
case 2: return Pair.of("hide", new String[] {"B", "E"});
case 3: return Pair.of("hide", new String[] {"B", "C"});
case 4: return Pair.of("hide", new String[] {"A", "C", "D"});
case 5: return Pair.of("hide", new String[] {"C", "F"});
case 6: return Pair.of("hide", new String[] {"F"});
case 7: return Pair.of("show", new String[] {"A", "E", "F"});
case 8: return Pair.of("hide", new String[] {});
case 9: return Pair.of("hide", new String[] {"C"});
default: return null;
}
}
@Override
public void writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setBoolean("twenty_four", this.isTwentyFour);
compound.setInteger("facing", this.facing.getIndex());
}
@Override
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
if (compound.hasKey("twenty_four")) this.isTwentyFour = compound.getBoolean("twenty_four");
if (compound.hasKey("facing")) this.facing = EnumFacing.getFront(compound.getInteger("facing"));
}
@Override
public boolean shouldRenderInPass(int pass)
{
return pass == 1;
}
}
public static class OBJClockRender extends TileEntitySpecialRenderer<OBJClockTileEntity>
{
private static Map<String, IFlexibleBakedModel> loadedModels = Maps.newHashMap();
private static final ResourceLocation DIGIT = new ResourceLocation(MODID.toLowerCase() + ":block/clock-digit.obj");
private static final VertexFormat CUSTOM_FORMAT;
static
{
CUSTOM_FORMAT = new VertexFormat();
CUSTOM_FORMAT.addElement(DefaultVertexFormats.POSITION_3F);
CUSTOM_FORMAT.addElement(DefaultVertexFormats.COLOR_4UB);
CUSTOM_FORMAT.addElement(DefaultVertexFormats.TEX_2F);
CUSTOM_FORMAT.addElement(DefaultVertexFormats.NORMAL_3B);
CUSTOM_FORMAT.addElement(DefaultVertexFormats.PADDING_1B);
}
public static void init()
{
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
if (manager instanceof IReloadableResourceManager)
{
((IReloadableResourceManager) manager).registerReloadListener(new IResourceManagerReloadListener()
{
@Override
public void onResourceManagerReload(IResourceManager ignored)
{
loadedModels.clear();
}
});
}
}
@Override
public void renderTileEntityAt(OBJClockTileEntity te, double x, double y, double z, float partialTicks, int destroyStage)
{
if (loadedModels.isEmpty())
{
FMLLog.info("loadedModels was empty, attempting to load model");
TextureMap texMap = Minecraft.getMinecraft().getTextureMapBlocks();
IModel model = null;
try
{
model = ModelLoaderRegistry.getModel(DIGIT);
}
catch (IOException e)
{
FMLLog.severe("OBJClockRender: Failed to get model '%s' from ModelLoaderRegistry.", DIGIT);
}
if (model != null && model instanceof OBJModel)
{
FMLLog.info("Successfully obtained model from registry");
OBJModel objModel = new OBJModel(((OBJModel) model).getMatLib(), ((OBJModel) model).getModelLocation(), ((OBJModel) model).getCustomData());
OBJCustomData.GroupConfigHandler configHandler = objModel.getCustomData().getConfigHandler();
OBJCustomData.GroupConfigBuilder builder = configHandler.getConfigBuilder();
for (int i = 0; i <= 9; i++)
{
Pair<String, String[]> configOperation = te.getConfigOperationFor(i);
builder.startNew("" + i);
if (configOperation.getLeft().equals("hide")) builder.showAll(configOperation.getRight());
if (configOperation.getLeft().equals("show")) builder.hideAll(configOperation.getRight());
configHandler.addConfig(builder.build());
}
OBJModel.OBJState state = new OBJModel.OBJState().setShowAllConfigs();
IFlexibleBakedModel flexModel = objModel.bake(state, Attributes.DEFAULT_BAKED_FORMAT,
new Function<ResourceLocation, TextureAtlasSprite>()
{
@Nullable
@Override
public TextureAtlasSprite apply(@Nullable ResourceLocation location)
{
if (location == null) return null;
return texMap.getAtlasSprite(location.toString());
}
});
loadedModels.put("0", flexModel);
}
}
bindTexture(TextureMap.locationBlocksTexture);
IFlexibleBakedModel model = loadedModels.get("0");
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldRenderer = tessellator.getWorldRenderer();
GlStateManager.pushMatrix();
// GlStateManager.scale(15.0f, 15.0f, 15.0f);
GlStateManager.translate(x, y, z);
// GlStateManager.translate(x, y, z);
worldRenderer.begin(GL11.GL_QUADS, model.getFormat());
for (BakedQuad quad : model.getGeneralQuads())
{
LightUtil.renderQuadColor(worldRenderer, quad, 0);
}
tessellator.draw();
GlStateManager.popMatrix();
}
}
{
"forge_marker": 1,
"defaults": {
"textures": {},
"model": "forgedebugmodelloaderregistry:clock-digit.obj",
"transform": "forge:default-block"
},
"variants": {
"inventory": [{
"y": 180
}],
"facing": {
"north": {},
"south": {"y": 180},
"west": {"y": 270},
"east": {"y": 90}
},
"twenty_four": {
"true": {},
"false": {}
},
"secondary": {
"true": {},
"false": {}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment