package com.jaquadro.minecraft.storagedrawers.client.model; import com.google.common.collect.ImmutableList; import com.jaquadro.minecraft.chameleon.Chameleon; import com.jaquadro.minecraft.chameleon.model.CachedBuilderModel; import com.jaquadro.minecraft.chameleon.model.ChamModel; import com.jaquadro.minecraft.chameleon.model.ProxyBuilderModel; import com.jaquadro.minecraft.chameleon.render.ChamRender; import com.jaquadro.minecraft.chameleon.resources.IconUtil; import com.jaquadro.minecraft.chameleon.resources.register.DefaultRegister; import com.jaquadro.minecraft.storagedrawers.StorageDrawers; import com.jaquadro.minecraft.storagedrawers.api.storage.EnumBasicDrawer; import com.jaquadro.minecraft.storagedrawers.block.BlockDrawers; import com.jaquadro.minecraft.storagedrawers.block.BlockDrawersCustom; import com.jaquadro.minecraft.storagedrawers.block.BlockStandardDrawers; import com.jaquadro.minecraft.storagedrawers.block.modeldata.DrawerStateModelData; import com.jaquadro.minecraft.storagedrawers.block.modeldata.MaterialModelData; import com.jaquadro.minecraft.storagedrawers.client.model.component.DrawerDecoratorModel; import com.jaquadro.minecraft.storagedrawers.client.model.component.DrawerSealedModel; import com.jaquadro.minecraft.storagedrawers.client.model.dynamic.CommonDrawerRenderer; import com.jaquadro.minecraft.storagedrawers.core.ModBlocks; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.model.*; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.util.Constants; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class CustomDrawerModel extends ChamModel { public static class Register extends DefaultRegister { public static final ResourceLocation iconDefaultSide = new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/drawers_raw_side"); public static final ResourceLocation[] iconDefaultFront = new ResourceLocation[] { new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/drawers_raw_front_1"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/drawers_raw_front_2"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/drawers_raw_front_4"), }; public static final ResourceLocation[] iconOverlayTrim = new ResourceLocation[] { new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_trim_1"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_trim_2"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_trim_4"), }; public static final ResourceLocation[] iconOverlayBoldTrim = new ResourceLocation[] { new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_boldtrim_1"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_boldtrim_2"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_boldtrim_4"), }; public static final ResourceLocation[] iconOverlayFace = new ResourceLocation[] { new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_face_1"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_face_2"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/shading_face_4"), }; public static final ResourceLocation[] iconOverlayHandle = new ResourceLocation[]{ new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/handle_1"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/handle_2"), new ResourceLocation(StorageDrawers.MOD_ID + ":blocks/overlay/handle_4"), }; public Register () { super(ModBlocks.customDrawers); } @Override public List<IBlockState> getBlockStates () { List<IBlockState> states = new ArrayList<IBlockState>(); for (EnumBasicDrawer drawer : EnumBasicDrawer.values()) { for (EnumFacing dir : EnumFacing.HORIZONTALS) states.add(ModBlocks.customDrawers.getDefaultState().withProperty(BlockStandardDrawers.BLOCK, drawer).withProperty(BlockDrawers.FACING, dir)); } return states; } @Override public IBakedModel getModel (IBlockState state, IBakedModel existingModel) { return new CachedBuilderModel(new Model()); } @Override public IBakedModel getModel (ItemStack stack, IBakedModel existingModel) { return new CachedBuilderModel(new Model()); } @Override public List<ResourceLocation> getTextureResources () { List<ResourceLocation> resource = new ArrayList<ResourceLocation>(); resource.add(iconDefaultSide); resource.addAll(Arrays.asList(iconDefaultFront)); resource.addAll(Arrays.asList(iconOverlayTrim)); resource.addAll(Arrays.asList(iconOverlayBoldTrim)); resource.addAll(Arrays.asList(iconOverlayFace)); resource.addAll(Arrays.asList(iconOverlayHandle)); return resource; } } private static final int[] iconIndex = new int[] { 0, 0, 1, 0, 2 }; private TextureAtlasSprite iconParticle; public static IBakedModel fromBlock (IBlockState state) { if (!(state instanceof IExtendedBlockState)) return new CustomDrawerModel(state, false); IExtendedBlockState xstate = (IExtendedBlockState) state; DrawerStateModelData stateModel = xstate.getValue(BlockDrawers.STATE_MODEL); MaterialModelData matModel = xstate.getValue(BlockDrawersCustom.MAT_MODEL); if (stateModel == null || matModel == null) return new CustomDrawerModel(state, false); ItemStack effMatFront = matModel.getEffectiveMaterialFront(); ItemStack effMatSide = matModel.getEffectiveMaterialSide(); ItemStack effMatTrim = matModel.getEffectiveMaterialTrim(); ItemStack matFront = matModel.getMaterialFront(); ItemStack matSide = matModel.getMaterialSide(); ItemStack matTrim = matModel.getMaterialTrim(); return new CustomDrawerModel(state, effMatFront, effMatSide, effMatTrim, matFront, matSide, matTrim, false); } public static IBakedModel fromItem (ItemStack stack) { IBlockState state = ModBlocks.customDrawers.getStateFromMeta(stack.getMetadata()); if (!stack.hasTagCompound()) return new CustomDrawerModel(state, true); NBTTagCompound tag = stack.getTagCompound(); ItemStack matFront = null; ItemStack matSide = null; ItemStack matTrim = null; if (tag.hasKey("MatF", Constants.NBT.TAG_COMPOUND)) matFront = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("MatF")); if (tag.hasKey("MatS", Constants.NBT.TAG_COMPOUND)) matSide = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("MatS")); if (tag.hasKey("MatT", Constants.NBT.TAG_COMPOUND)) matTrim = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("MatT")); ItemStack effMatFront = matFront != null ? matFront : matSide; ItemStack effMatTrim = matTrim != null ? matTrim : matSide; ItemStack effMatSide = matSide; IBakedModel model = new CustomDrawerModel(state, effMatFront, effMatSide, effMatTrim, matFront, matSide, matTrim, true); if (!stack.getTagCompound().hasKey("tile", Constants.NBT.TAG_COMPOUND)) return model; return new DrawerSealedModel(model, state, true); } private CustomDrawerModel (IBlockState state, boolean mergeLayers) { this(state, null, null, null, null, null, null, mergeLayers); } private CustomDrawerModel (IBlockState state, ItemStack effMatFront, ItemStack effMatSide, ItemStack effMatTrim, ItemStack matFront, ItemStack matSide, ItemStack matTrim, boolean mergeLayers) { super(state, mergeLayers, effMatFront, effMatSide, effMatTrim, matFront, matSide, matTrim); } @Override protected void renderMippedLayer (ChamRender renderer, IBlockState state, Object... args) { EnumBasicDrawer info = state.getValue(BlockStandardDrawers.BLOCK); int index = iconIndex[info.getDrawerCount()]; TextureAtlasSprite iconFront = IconUtil.getIconFromStack((ItemStack)args[0]); TextureAtlasSprite iconSide = IconUtil.getIconFromStack((ItemStack)args[1]); TextureAtlasSprite iconTrim = IconUtil.getIconFromStack((ItemStack)args[2]); if (iconFront == null) iconFront = iconSide; if (iconTrim == null) iconTrim = iconSide; if (iconFront == null) iconFront = Chameleon.instance.iconRegistry.getIcon(Register.iconDefaultFront[index]); if (iconSide == null) iconSide = Chameleon.instance.iconRegistry.getIcon(Register.iconDefaultSide); if (iconTrim == null) iconTrim = Chameleon.instance.iconRegistry.getIcon(Register.iconDefaultSide); iconParticle = iconSide; CommonDrawerRenderer drawerRenderer = new CommonDrawerRenderer(renderer); drawerRenderer.renderBasePass(null, state, BlockPos.ORIGIN, state.getValue(BlockDrawers.FACING), iconSide, iconTrim, iconFront); } @Override protected void renderTransLayer (ChamRender renderer, IBlockState state, Object... args) { EnumBasicDrawer info = state.getValue(BlockStandardDrawers.BLOCK); int index = iconIndex[info.getDrawerCount()]; TextureAtlasSprite iconOverlayFace = Chameleon.instance.iconRegistry.getIcon(Register.iconOverlayFace[index]); TextureAtlasSprite iconOverlayHandle = Chameleon.instance.iconRegistry.getIcon(Register.iconOverlayHandle[index]); TextureAtlasSprite iconTrim = IconUtil.getIconFromStack((ItemStack)args[5]); TextureAtlasSprite iconOverlayTrim; if (iconTrim == null) iconOverlayTrim = Chameleon.instance.iconRegistry.getIcon(Register.iconOverlayBoldTrim[index]); else iconOverlayTrim = Chameleon.instance.iconRegistry.getIcon(Register.iconOverlayTrim[index]); CommonDrawerRenderer drawerRenderer = new CommonDrawerRenderer(renderer); drawerRenderer.renderOverlayPass(null, state, BlockPos.ORIGIN, state.getValue(BlockDrawers.FACING), iconOverlayTrim, iconOverlayHandle, iconOverlayFace); } @Override public TextureAtlasSprite getParticleTexture () { return iconParticle; } public static class Model extends ProxyBuilderModel { public Model () { super(Chameleon.instance.iconRegistry.getIcon(Register.iconDefaultSide)); } @Override protected IBakedModel buildModel (IBlockState state, IBakedModel parent) { try { IBakedModel mainModel = CustomDrawerModel.fromBlock(state); if (!(state instanceof IExtendedBlockState)) return mainModel; IExtendedBlockState xstate = (IExtendedBlockState) state; DrawerStateModelData stateModel = xstate.getValue(BlockDrawers.STATE_MODEL); try { if (!DrawerDecoratorModel.shouldHandleState(stateModel)) return mainModel; EnumBasicDrawer drawer = state.getValue(BlockStandardDrawers.BLOCK); EnumFacing dir = state.getValue(BlockDrawers.FACING); DrawerDecoratorModel decModel = new DrawerDecoratorModel(mainModel, xstate, drawer, dir, stateModel); decModel.addBaseRenderLayer(BlockRenderLayer.TRANSLUCENT); return decModel; } catch (Throwable t) { return mainModel; } } catch (Throwable t) { return parent; } } @Override public ItemOverrideList getOverrides () { return itemHandler; } @Override public List<Object> getKey (IBlockState state) { try { List<Object> key = new ArrayList<Object>(); IExtendedBlockState xstate = (IExtendedBlockState)state; key.add(xstate.getValue(BlockDrawers.STATE_MODEL)); key.add(xstate.getValue(BlockDrawersCustom.MAT_MODEL)); return key; } catch (Throwable t) { return super.getKey(state); } } } private static class ItemHandler extends ItemOverrideList { public ItemHandler () { super(ImmutableList.<ItemOverride>of()); } @Override public IBakedModel handleItemState (IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { return fromItem(stack); } } private static final ItemHandler itemHandler = new ItemHandler(); }