diff --git a/src/main/java/appeng/block/AEBaseBlock.java b/src/main/java/appeng/block/AEBaseBlock.java index f0ecb8253..bf923f0c8 100644 --- a/src/main/java/appeng/block/AEBaseBlock.java +++ b/src/main/java/appeng/block/AEBaseBlock.java @@ -22,7 +22,6 @@ package appeng.block; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; - import javax.annotation.Nullable; import com.google.common.base.Optional; @@ -35,6 +34,7 @@ import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -572,4 +572,16 @@ public abstract class AEBaseBlock extends Block implements IAEFeature { this.hasSubtypes = hasSubtypes; } + + /** + * Return the item mesh definition that should be used to determine the item model of an item stack, + * instead of the default model. Return null if your Block doesn't use a custom ItemMeshDefinition (the default). + * The returned ItemMeshDefinition will automatically be registered with the ItemModelMesher during the registration of the block. + */ + @SideOnly( Side.CLIENT ) + public ItemMeshDefinition getItemMeshDefinition() + { + return null; + } + } diff --git a/src/main/java/appeng/block/networking/BlockEnergyCell.java b/src/main/java/appeng/block/networking/BlockEnergyCell.java index a948e36be..017fbd3e2 100644 --- a/src/main/java/appeng/block/networking/BlockEnergyCell.java +++ b/src/main/java/appeng/block/networking/BlockEnergyCell.java @@ -25,6 +25,8 @@ import java.util.List; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyInteger; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.ItemMeshDefinition; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -32,6 +34,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import appeng.api.implementations.items.IAEItemPowerStorage; import appeng.block.AEBaseItemBlock; import appeng.block.AEBaseItemBlockChargeable; import appeng.block.AEBaseTileBlock; @@ -96,4 +99,40 @@ public class BlockEnergyCell extends AEBaseTileBlock { return AEBaseItemBlockChargeable.class; } + + /** + * Helper method that returns the energy fill factor (between 0 and 1) of a given item stack. + * Returns 0 if the item stack has no fill factor. + */ + private static double getFillFactor( ItemStack is ) { + if( !( is.getItem() instanceof IAEItemPowerStorage ) ) + { + return 0; + } + + AEBaseItemBlockChargeable itemChargeable = (AEBaseItemBlockChargeable) is.getItem(); + double curPower = itemChargeable.getAECurrentPower( is ); + double maxPower = itemChargeable.getAEMaxPower( is ); + + return curPower / maxPower; + } + + /** + * Determines which version of the energy cell model should be used depending on the fill factor + * of the item stack. + */ + @SideOnly( Side.CLIENT ) + @Override + public ItemMeshDefinition getItemMeshDefinition() + { + return is -> { + double fillFactor = getFillFactor( is ); + + int storageLevel = TileEnergyCell.getStorageLevelFromFillFactor(fillFactor); + + return new ModelResourceLocation( "appliedenergistics2:tile.BlockEnergyCell", "fullness=" + storageLevel ); + + }; + } + } diff --git a/src/main/java/appeng/core/features/AEBlockFeatureHandler.java b/src/main/java/appeng/core/features/AEBlockFeatureHandler.java index fb4ce83f2..76ad72dd7 100644 --- a/src/main/java/appeng/core/features/AEBlockFeatureHandler.java +++ b/src/main/java/appeng/core/features/AEBlockFeatureHandler.java @@ -25,10 +25,13 @@ import com.google.common.base.Optional; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemMeshDefinition; +import net.minecraft.client.renderer.ItemModelMesher; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.resources.IReloadableResourceManager; +import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.IRegistry; import net.minecraftforge.client.model.ModelLoader; @@ -36,6 +39,7 @@ import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import appeng.api.definitions.IBlockDefinition; +import appeng.block.AEBaseBlock; import appeng.block.IHasSpecialItemModel; import appeng.client.render.model.AEIgnoringStateMapper; import appeng.core.AppEng; @@ -102,13 +106,28 @@ public final class AEBlockFeatureHandler implements IFeatureHandler @Override public void registerModel() { - if( !featured.getBlockState().getProperties().isEmpty() || featured instanceof IHasSpecialItemModel ) + ItemModelMesher itemModelMesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher(); + Item item = this.definition.maybeItem().get(); + + // Retrieve a custom item mesh definition, if the block defines one + ItemMeshDefinition itemMeshDefinition = null; + if( featured instanceof AEBaseBlock ) { - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( this.definition.maybeItem().get(), 0, new ModelResourceLocation( registryName, "inventory" ) ); + itemMeshDefinition = ( (AEBaseBlock) featured ).getItemMeshDefinition(); + } + + if ( itemMeshDefinition != null ) + { + // This block has a custom item mesh definition, so register it instead of the resource location + itemModelMesher.register( item, itemMeshDefinition ); + } + else if( !featured.getBlockState().getProperties().isEmpty() || featured instanceof IHasSpecialItemModel ) + { + itemModelMesher.register( item, 0, new ModelResourceLocation( registryName, "inventory" ) ); } else { - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( this.definition.maybeItem().get(), 0, new ModelResourceLocation( registryName, "normal" ) ); + itemModelMesher.register( item, 0, new ModelResourceLocation( registryName, "normal" ) ); } } diff --git a/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java b/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java index 64d8bc18f..6f835a986 100644 --- a/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java +++ b/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java @@ -26,11 +26,14 @@ import com.google.common.base.Optional; import com.google.common.collect.Sets; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemMeshDefinition; +import net.minecraft.client.renderer.ItemModelMesher; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.resources.IReloadableResourceManager; +import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.IRegistry; import net.minecraftforge.client.ForgeHooksClient; @@ -123,13 +126,22 @@ public final class AETileBlockFeatureHandler implements IFeatureHandler @Override public void registerModel() { - if( !featured.getBlockState().getProperties().isEmpty() || featured instanceof IHasSpecialItemModel ) + ItemModelMesher itemModelMesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher(); + Item item = this.definition.maybeItem().get(); + ItemMeshDefinition itemMeshDefinition = featured.getItemMeshDefinition(); + + if( itemMeshDefinition != null ) { - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( this.definition.maybeItem().get(), 0, new ModelResourceLocation( registryName, "inventory" ) ); + // This block has a custom item mesh definition, so register it instead of the resource location + itemModelMesher.register( item, itemMeshDefinition ); + } + else if( !featured.getBlockState().getProperties().isEmpty() || featured instanceof IHasSpecialItemModel ) + { + itemModelMesher.register( item, 0, new ModelResourceLocation( registryName, "inventory" ) ); } else { - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( this.definition.maybeItem().get(), 0, new ModelResourceLocation( registryName, "normal" ) ); + itemModelMesher.register( item, 0, new ModelResourceLocation( registryName, "normal" ) ); } } diff --git a/src/main/java/appeng/tile/networking/TileEnergyCell.java b/src/main/java/appeng/tile/networking/TileEnergyCell.java index 04051c219..14eaacc45 100644 --- a/src/main/java/appeng/tile/networking/TileEnergyCell.java +++ b/src/main/java/appeng/tile/networking/TileEnergyCell.java @@ -60,19 +60,17 @@ public class TileEnergyCell extends AENetworkTile implements IAEPowerStorage public void onReady() { super.onReady(); - final int value = (Integer) this.worldObj.getBlockState( this.pos ).getValue( BlockEnergyCell.ENERGY_STORAGE ); + final int value = this.worldObj.getBlockState( this.pos ).getValue( BlockEnergyCell.ENERGY_STORAGE ); this.currentMeta = (byte) value; this.changePowerLevel(); } - private void changePowerLevel() - { - if( this.notLoaded() ) - { - return; - } - - byte boundMetadata = (byte) ( 8.0 * ( this.internalCurrentPower / this.getInternalMaxPower() ) ); + /** + * Given a fill factor, return the storage level (0-7) used for the state of the block. + * This is also used for determining the item model. + */ + public static int getStorageLevelFromFillFactor( double fillFactor ) { + byte boundMetadata = (byte) ( 8.0 * ( fillFactor ) ); if( boundMetadata > 7 ) { @@ -82,11 +80,22 @@ public class TileEnergyCell extends AENetworkTile implements IAEPowerStorage { boundMetadata = 0; } + return boundMetadata; + } - if( this.currentMeta != boundMetadata ) + private void changePowerLevel() + { + if( this.notLoaded() ) { - this.currentMeta = boundMetadata; - this.worldObj.setBlockState( this.pos, this.worldObj.getBlockState( this.pos ).withProperty( BlockEnergyCell.ENERGY_STORAGE, (int) boundMetadata ) ); + return; + } + + int storageLevel = getStorageLevelFromFillFactor( this.internalCurrentPower / this.getInternalMaxPower() ); + + if( this.currentMeta != storageLevel ) + { + this.currentMeta = (byte) storageLevel; + this.worldObj.setBlockState( this.pos, this.worldObj.getBlockState( this.pos ).withProperty( BlockEnergyCell.ENERGY_STORAGE, storageLevel ) ); } } diff --git a/src/main/resources/assets/appliedenergistics2/models/item/tile.BlockCreativeEnergyCell.json b/src/main/resources/assets/appliedenergistics2/models/item/tile.BlockCreativeEnergyCell.json new file mode 100644 index 000000000..3cda6a09d --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/tile.BlockCreativeEnergyCell.json @@ -0,0 +1,3 @@ +{ + "parent": "appliedenergistics2:block/EnergyCell/tile.BlockCreativeEnergyCell" +}