Skip to content

Instantly share code, notes, and snippets.

@StillManic
Created January 5, 2016 22:03
Show Gist options
  • Save StillManic/f8f1b494df74e46993f8 to your computer and use it in GitHub Desktop.
Save StillManic/f8f1b494df74e46993f8 to your computer and use it in GitHub Desktop.
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 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));
setCreativeTab(CreativeTabs.tabBlock);
setUnlocalizedName(MODID + ":" + name);
setBlockBounds(0.0f, 0.0f, 0.0f, 0.125f, 1.0f, 1.0f);
}
@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 true; }
@Override
public TileEntity createTileEntity(World world, IBlockState state)
{
return new OBJClockTileEntity(world, state);
}
@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.875f, 2.0f, 1.0f, 1.0f); break;
case SOUTH: setBlockBounds(0.0f, 0.0f, 0.0f, 2.0f, 1.0f, 0.125f); break;
case WEST: setBlockBounds(0.875f, 0.0f, 0.0f, 1.0f, 1.0f, 2.0f); break;
case EAST: setBlockBounds(0.0f, 0.0f, 0.0f, 0.125f, 1.0f, 2.0f); break;
default: break;
}
}
@Override
public IBlockState onBlockPlaced(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
return this.getDefaultState().withProperty(FACING, EnumFacing.WEST).withProperty(TWENTY_FOUR, false);
}
@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);
if (world.getTileEntity(pos) != null && world.getTileEntity(pos) instanceof OBJClockTileEntity)
{
((OBJClockTileEntity) world.getTileEntity(pos)).isTwentyFour = state.getValue(TWENTY_FOUR);
}
return true;
}
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(FACING, EnumFacing.getHorizontal(meta & 3)).withProperty(TWENTY_FOUR, (meta & 4) > 0);
}
@Override
public int getMetaFromState(IBlockState state)
{
int meta = 0;
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}, 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)));
return ((IExtendedBlockState) this.state.getBaseState()).withProperty(OBJModel.OBJProperty.instance, retState);
}
}
public static class OBJClockTileEntity extends TileEntity
{
private boolean isTwentyFour = false;
private IBlockState state;
public OBJClockTileEntity() {}
public OBJClockTileEntity(World world, IBlockState state)
{
this.worldObj = world;
this.state = state;
}
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;
}
}
}
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(e.getMessage());
}
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(Lists.newArrayList("0"));
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.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-base.obj",
"transform": "forge:default-block"
},
"variants": {
"inventory": [{
"y": 180
}],
"facing": {
"north": {},
"south": {"y": 180},
"west": {"y": 270},
"east": {"y": 90}
},
"twenty_four": {
"true": {},
"false": {}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment