diff --git a/src/main/java/appeng/block/AEBaseBlock.java b/src/main/java/appeng/block/AEBaseBlock.java index f0ecb825..bf923f0c 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/misc/BlockQuartzTorch.java b/src/main/java/appeng/block/misc/BlockQuartzTorch.java index 8804cb61..6621efc3 100644 --- a/src/main/java/appeng/block/misc/BlockQuartzTorch.java +++ b/src/main/java/appeng/block/misc/BlockQuartzTorch.java @@ -27,10 +27,12 @@ import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; +import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -52,15 +54,18 @@ import appeng.helpers.MetaRotation; public class BlockQuartzTorch extends AEBaseBlock implements IOrientableBlock, ICustomCollision { - + // Cannot use the vanilla FACING property here because it excludes facing DOWN - public static final PropertyDirection FACING = PropertyDirection.create("facing"); - + public static final PropertyDirection FACING = PropertyDirection.create( "facing" ); + + // Used to alternate between two variants of the torch on adjacent blocks + public static final PropertyBool ODD = PropertyBool.create( "odd" ); + public BlockQuartzTorch() { super( Material.CIRCUITS ); - this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.UP)); + this.setDefaultState( this.blockState.getBaseState().withProperty( FACING, EnumFacing.UP ).withProperty( ODD, false ) ); this.setFeature( EnumSet.of( AEFeature.DecorativeLights ) ); this.setLightLevel( 0.9375F ); this.setLightOpacity( 0 ); @@ -68,10 +73,22 @@ public class BlockQuartzTorch extends AEBaseBlock implements IOrientableBlock, I this.setOpaque( false ); } + /** + * Sets the "ODD" property of the block state according to the placement of the block. + */ + @Override + public IBlockState getActualState( IBlockState state, IBlockAccess worldIn, BlockPos pos ) + { + boolean oddPlacement = ((pos.getX() + pos.getY() + pos.getZ()) % 2) != 0; + + return super.getActualState( state, worldIn, pos ) + .withProperty( ODD, oddPlacement ); + } + @Override public int getMetaFromState( final IBlockState state ) { - return state.getValue(FACING).ordinal(); + return state.getValue( FACING ).ordinal(); } @Override @@ -84,7 +101,7 @@ public class BlockQuartzTorch extends AEBaseBlock implements IOrientableBlock, I @Override protected IProperty[] getAEStates() { - return new IProperty[] { FACING }; + return new IProperty[] { FACING, ODD }; } @Override @@ -188,4 +205,23 @@ public class BlockQuartzTorch extends AEBaseBlock implements IOrientableBlock, I { return new MetaRotation( w, pos, FACING ); } + + @Override + public boolean isOpaque() + { + return false; + } + + @Override + public boolean isFullCube( IBlockState state ) + { + return false; + } + + @SideOnly(Side.CLIENT) + public BlockRenderLayer getBlockLayer() + { + return BlockRenderLayer.CUTOUT; + } + } diff --git a/src/main/java/appeng/block/networking/BlockEnergyCell.java b/src/main/java/appeng/block/networking/BlockEnergyCell.java index a948e36b..017fbd3e 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/client/ClientHelper.java b/src/main/java/appeng/client/ClientHelper.java index c8ff2fb8..78cefb34 100644 --- a/src/main/java/appeng/client/ClientHelper.java +++ b/src/main/java/appeng/client/ClientHelper.java @@ -31,7 +31,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.color.IBlockColor; -import net.minecraft.client.renderer.color.IItemColor; +import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; @@ -62,6 +62,7 @@ import appeng.client.render.effects.EnergyFx; import appeng.client.render.effects.LightningArcFX; import appeng.client.render.effects.LightningFX; import appeng.client.render.effects.VibrantFX; +import appeng.client.render.model.GlassModelLoader; import appeng.client.render.model.UVLModelLoader; import appeng.client.render.textures.ParticleTextures; import appeng.core.AEConfig; @@ -93,6 +94,7 @@ public class ClientHelper extends ServerHelper { MinecraftForge.EVENT_BUS.register( this ); ModelLoaderRegistry.registerLoader( UVLModelLoader.INSTANCE ); + ModelLoaderRegistry.registerLoader( new GlassModelLoader() ); for( IAEFeature feature : Api.INSTANCE.definitions().getFeatureRegistry().getRegisteredFeatures() ) { feature.handler().registerStateMapper(); @@ -129,7 +131,10 @@ public class ClientHelper extends ServerHelper } } - Minecraft.getMinecraft().getItemColors().registerItemColorHandler( new ItemPaintBallColor(), Api.INSTANCE.definitions().items().paintBall().maybeItem().get() ); + // Register color handling for paintball items + ItemColors itemColors = Minecraft.getMinecraft().getItemColors(); + Item paintballItem = Api.INSTANCE.definitions().items().paintBall().maybeItem().get(); + itemColors.registerItemColorHandler( ItemPaintBall::getColorFromItemstack, paintballItem ); } @Override @@ -464,30 +469,4 @@ public class ClientHelper extends ServerHelper } } - - public class ItemPaintBallColor implements IItemColor - { - - @Override - public int getColorFromItemstack( ItemStack stack, int tintIndex ) - { - final AEColor col = ( (ItemPaintBall) stack.getItem() ).getColor( stack ); - - final int colorValue = stack.getItemDamage() >= 20 ? col.mediumVariant : col.mediumVariant; - final int r = ( colorValue >> 16 ) & 0xff; - final int g = ( colorValue >> 8 ) & 0xff; - final int b = ( colorValue ) & 0xff; - - if( stack.getItemDamage() >= 20 ) - { - final float fail = 0.7f; - final int full = (int) ( 255 * 0.3 ); - return (int) ( full + r * fail ) << 16 | (int) ( full + g * fail ) << 8 | (int) ( full + b * fail ) | 0xff << 24; - } - else - { - return r << 16 | g << 8 | b | 0xff << 24; - } - } - } } \ No newline at end of file diff --git a/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java b/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java index c3c91a3e..1d96b194 100644 --- a/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java +++ b/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java @@ -216,7 +216,7 @@ public class CachingRotatingBakedModel implements IBakedModel public void setQuadTint( int tint ) { - + parent.setQuadTint( tint ); } @Override @@ -228,13 +228,13 @@ public class CachingRotatingBakedModel implements IBakedModel @Override public void setApplyDiffuseLighting( boolean diffuse ) { - + parent.setApplyDiffuseLighting( diffuse ); } @Override public void setTexture( TextureAtlasSprite texture ) { - + parent.setTexture( texture ); } } diff --git a/src/main/java/appeng/client/render/model/GlassBakedModel.java b/src/main/java/appeng/client/render/model/GlassBakedModel.java new file mode 100644 index 00000000..405332ac --- /dev/null +++ b/src/main/java/appeng/client/render/model/GlassBakedModel.java @@ -0,0 +1,314 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.IntStream; + +import javax.annotation.Nullable; + +import com.google.common.base.Function; +import com.google.common.base.Strings; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; +import net.minecraftforge.common.property.IExtendedBlockState; + +import appeng.decorative.solid.BlockQuartzGlass; +import appeng.decorative.solid.GlassState; + + +public class GlassBakedModel implements IBakedModel +{ + + private static final byte[][][] OFFSETS = generateOffsets(); + + // Alternating textures based on position + static final ResourceLocation TEXTURE_A = new ResourceLocation( "appliedenergistics2:blocks/glass/BlockQuartzGlassA" ); + static final ResourceLocation TEXTURE_B = new ResourceLocation( "appliedenergistics2:blocks/glass/BlockQuartzGlassB" ); + static final ResourceLocation TEXTURE_C = new ResourceLocation( "appliedenergistics2:blocks/glass/BlockQuartzGlassC" ); + static final ResourceLocation TEXTURE_D = new ResourceLocation( "appliedenergistics2:blocks/glass/BlockQuartzGlassD" ); + + // Frame texture + static final ResourceLocation[] TEXTURES_FRAME = generateTexturesFrame(); + + // Generates the required textures for the frame + private static ResourceLocation[] generateTexturesFrame() + { + return IntStream.range( 1, 16 ) + .mapToObj( Integer::toBinaryString ) + .map( s -> Strings.padStart( s, 4, '0' ) ) + .map( s -> new ResourceLocation( "appliedenergistics2:blocks/glass/BlockQuartzGlassFrame" + s ) ) + .toArray( ResourceLocation[]::new ); + } + + private final TextureAtlasSprite[] glassTextures; + + private final TextureAtlasSprite[] frameTextures; + + private final VertexFormat vertexFormat; + + public GlassBakedModel( VertexFormat format, Function bakedTextureGetter ) + { + this.glassTextures = new TextureAtlasSprite[] { + bakedTextureGetter.apply( TEXTURE_A ), + bakedTextureGetter.apply( TEXTURE_B ), + bakedTextureGetter.apply( TEXTURE_C ), + bakedTextureGetter.apply( TEXTURE_D ) + }; + + this.vertexFormat = format; + + // The first frame texture would be empty, so we simply leave it set to null here + this.frameTextures = new TextureAtlasSprite[16]; + for( int i = 0; i < TEXTURES_FRAME.length; i++ ) + { + this.frameTextures[1 + i] = bakedTextureGetter.apply( TEXTURES_FRAME[i] ); + } + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + + if( !( state instanceof IExtendedBlockState ) || side == null ) + { + return Collections.emptyList(); + } + + IExtendedBlockState extState = (IExtendedBlockState) state; + + GlassState glassState = extState.getValue( BlockQuartzGlass.GLASS_STATE ); + + final int cx = Math.abs( glassState.getX() % 10 ); + final int cy = Math.abs( glassState.getY() % 10 ); + final int cz = Math.abs( glassState.getZ() % 10 ); + + int u = OFFSETS[cx][cy][cz] % 4; + int v = OFFSETS[9 - cx][9 - cy][9 - cz] % 4; + + int texIdx = Math.abs( ( OFFSETS[cx][cy][cz] + ( glassState.getX() + glassState.getY() + glassState.getZ() ) ) % 4 ); + + if( texIdx < 2 ) + { + u /= 2; + v /= 2; + } + + TextureAtlasSprite glassTexture = glassTextures[texIdx]; + + // Render the glass side + List quads = new ArrayList<>( 5 ); // At most 5 + + List corners = RenderHelper.getFaceCorners( side ); + quads.add( createQuad( side, corners, glassTexture, u, v ) ); + + /* + This needs some explanation: + The bit-field contains 4-bits, one for each direction that a frame may be drawn. + Converted to a number, the bit-field is then used as an index into the list of + frame textures, which have been created in such a way that their filenames + indicate, in which directions they contain borders. + i.e. bitmask = 0101 means a border should be drawn up and down (in terms of u,v space). + Converted to a number, this bitmask is 5. So the texture at index 5 is used. + That texture had "0101" in its filename to indicate this. + */ + int edgeBitmask = makeBitmask( glassState, side ); + TextureAtlasSprite sideSprite = frameTextures[edgeBitmask]; + if( sideSprite != null ) + { + quads.add( createQuad( side, corners, sideSprite, 0, 0 ) ); + } + + return quads; + } + + /** + * Creates the bitmask that indicates, in which directions (in terms of u,v space) a border should be drawn. + */ + private static int makeBitmask( GlassState state, EnumFacing side ) + { + switch( side ) + { + case DOWN: + return makeBitmask( state, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.NORTH, EnumFacing.WEST ); + case UP: + return makeBitmask( state, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.NORTH, EnumFacing.EAST ); + case NORTH: + return makeBitmask( state, EnumFacing.UP, EnumFacing.WEST, EnumFacing.DOWN, EnumFacing.EAST ); + case SOUTH: + return makeBitmask( state, EnumFacing.UP, EnumFacing.EAST, EnumFacing.DOWN, EnumFacing.WEST ); + case WEST: + return makeBitmask( state, EnumFacing.UP, EnumFacing.SOUTH, EnumFacing.DOWN, EnumFacing.NORTH ); + case EAST: + return makeBitmask( state, EnumFacing.UP, EnumFacing.NORTH, EnumFacing.DOWN, EnumFacing.SOUTH ); + default: + throw new IllegalArgumentException( "Unsupported side!" ); + } + } + + private static int makeBitmask( GlassState state, EnumFacing up, EnumFacing right, EnumFacing down, EnumFacing left ) + { + + int bitmask = 0; + + if( !state.isFlushWith( up ) ) + { + bitmask |= 1; + } + if( !state.isFlushWith( right ) ) + { + bitmask |= 2; + } + if( !state.isFlushWith( down ) ) + { + bitmask |= 4; + } + if( !state.isFlushWith( left ) ) + { + bitmask |= 8; + } + return bitmask; + } + + private BakedQuad createQuad( EnumFacing side, List corners, TextureAtlasSprite sprite, float uOffset, float vOffset ) + { + return createQuad( side, corners.get( 0 ), corners.get( 1 ), corners.get( 2 ), corners.get( 3 ), sprite, uOffset, vOffset ); + } + + private BakedQuad createQuad( EnumFacing side, Vec3d c1, Vec3d c2, Vec3d c3, Vec3d c4, TextureAtlasSprite sprite, float uOffset, float vOffset ) + { + Vec3d normal = new Vec3d( side.getDirectionVec() ); + + // Apply the u,v shift. + // This mirrors the logic from OffsetIcon from 1.7 + float u1 = MathHelper.clamp_float( 0 - uOffset, 0, 16 ); + float u2 = MathHelper.clamp_float( 16 - uOffset, 0, 16 ); + float v1 = MathHelper.clamp_float( 0 - vOffset, 0, 16 ); + float v2 = MathHelper.clamp_float( 16 - vOffset, 0, 16 ); + + UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( vertexFormat ); + builder.setTexture( sprite ); + putVertex( builder, normal, c1.xCoord, c1.yCoord, c1.zCoord, sprite, u1, v1 ); + putVertex( builder, normal, c2.xCoord, c2.yCoord, c2.zCoord, sprite, u1, v2 ); + putVertex( builder, normal, c3.xCoord, c3.yCoord, c3.zCoord, sprite, u2, v2 ); + putVertex( builder, normal, c4.xCoord, c4.yCoord, c4.zCoord, sprite, u2, v1 ); + return builder.build(); + } + + /* + This method is as complicated as it is, because the order in which we push data into the vertexbuffer actually has to be precisely the order + in which the vertex elements had been declared in the vertex format. + */ + private void putVertex( UnpackedBakedQuad.Builder builder, Vec3d normal, double x, double y, double z, TextureAtlasSprite sprite, float u, float v ) + { + for( int e = 0; e < vertexFormat.getElementCount(); e++ ) + { + switch( vertexFormat.getElement( e ).getUsage() ) + { + case POSITION: + builder.put( e, (float) x, (float) y, (float) z, 1.0f ); + break; + case COLOR: + builder.put( e, 1.0f, 1.0f, 1.0f, 1.0f ); + break; + case UV: + if( vertexFormat.getElement( e ).getIndex() == 0 ) + { + u = sprite.getInterpolatedU( u ); + v = sprite.getInterpolatedV( v ); + builder.put( e, u, v, 0f, 1f ); + break; + } + case NORMAL: + builder.put( e, (float) normal.xCoord, (float) normal.yCoord, (float) normal.zCoord, 0f ); + break; + default: + builder.put( e ); + break; + } + } + } + + @Override + public ItemOverrideList getOverrides() + { + return ItemOverrideList.NONE; + } + + @Override + public boolean isAmbientOcclusion() + { + return false; + } + + @Override + public boolean isGui3d() + { + return false; + } + + @Override + public boolean isBuiltInRenderer() + { + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return frameTextures[frameTextures.length - 1]; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return ItemCameraTransforms.DEFAULT; + } + + private static byte[][][] generateOffsets() + { + final Random r = new Random( 924 ); + final byte[][][] offset = new byte[10][10][10]; + + for( int x = 0; x < 10; x++ ) + { + for( int y = 0; y < 10; y++ ) + { + r.nextBytes( offset[x][y] ); + } + } + + return offset; + } +} diff --git a/src/main/java/appeng/client/render/model/GlassModel.java b/src/main/java/appeng/client/render/model/GlassModel.java new file mode 100644 index 00000000..8621a731 --- /dev/null +++ b/src/main/java/appeng/client/render/model/GlassModel.java @@ -0,0 +1,69 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import java.util.Collection; +import java.util.Collections; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; + +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.IModel; +import net.minecraftforge.common.model.IModelState; +import net.minecraftforge.common.model.TRSRTransformation; + + +/** + * Model class for the connected texture glass model. + */ +public class GlassModel implements IModel +{ + + @Override + public Collection getDependencies() + { + return Collections.emptySet(); + } + + @Override + public Collection getTextures() + { + return ImmutableSet.builder() + .add( GlassBakedModel.TEXTURE_A, GlassBakedModel.TEXTURE_B, GlassBakedModel.TEXTURE_C, GlassBakedModel.TEXTURE_D ) + .add( GlassBakedModel.TEXTURES_FRAME ) + .build(); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + return new GlassBakedModel( format, bakedTextureGetter ); + } + + @Override + public IModelState getDefaultState() + { + return TRSRTransformation.identity(); + } +} diff --git a/src/main/java/appeng/client/render/model/GlassModelLoader.java b/src/main/java/appeng/client/render/model/GlassModelLoader.java new file mode 100644 index 00000000..5e1edc38 --- /dev/null +++ b/src/main/java/appeng/client/render/model/GlassModelLoader.java @@ -0,0 +1,55 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.ICustomModelLoader; +import net.minecraftforge.client.model.IModel; + +import appeng.core.AppEng; + + +/** + * Model loader to manage connected texture glass. + */ +public class GlassModelLoader implements ICustomModelLoader +{ + + private static final GlassModel GLASS_MODEL = new GlassModel(); + + @Override + public boolean accepts( ResourceLocation modelLocation ) + { + return modelLocation.getResourceDomain().equals( AppEng.MOD_ID ) && "models/block/builtin/connected_glass".equals( modelLocation.getResourcePath() ); + } + + @Override + public IModel loadModel( ResourceLocation modelLocation ) throws Exception + { + return GLASS_MODEL; + } + + @Override + public void onResourceManagerReload( IResourceManager resourceManager ) + { + + } +} diff --git a/src/main/java/appeng/client/render/model/RenderHelper.java b/src/main/java/appeng/client/render/model/RenderHelper.java new file mode 100644 index 00000000..694708b7 --- /dev/null +++ b/src/main/java/appeng/client/render/model/RenderHelper.java @@ -0,0 +1,107 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ +package appeng.client.render.model; + + +import java.util.EnumMap; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3d; + + +final class RenderHelper +{ + + private static EnumMap> cornersForFacing = generateCornersForFacings(); + + private RenderHelper() { + + } + + static List getFaceCorners( EnumFacing side ) + { + return cornersForFacing.get( side ); + } + + private static EnumMap> generateCornersForFacings() + { + EnumMap> result = new EnumMap<>( EnumFacing.class ); + + for( EnumFacing facing : EnumFacing.values() ) + { + List corners; + + float offset = ( facing.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE ) ? 0 : 1; + + switch( facing.getAxis() ) + { + default: + case X: + corners = Lists.newArrayList( + new Vec3d( offset, 1, 1 ), + new Vec3d( offset, 0, 1 ), + new Vec3d( offset, 0, 0 ), + new Vec3d( offset, 1, 0 ) + ); + break; + case Y: + corners = Lists.newArrayList( + new Vec3d( 1, offset, 1 ), + new Vec3d( 1, offset, 0 ), + new Vec3d( 0, offset, 0 ), + new Vec3d( 0, offset, 1 ) + ); + break; + case Z: + corners = Lists.newArrayList( + new Vec3d( 0, 1, offset ), + new Vec3d( 0, 0, offset ), + new Vec3d( 1, 0, offset ), + new Vec3d( 1, 1, offset ) + ); + break; + } + + if (facing.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE) { + corners = Lists.reverse( corners ); + } + + result.put( facing, ImmutableList.copyOf( corners ) ); + } + + return result; + } + + private static Vec3d adjust( Vec3d vec, EnumFacing.Axis axis, double delta ) + { + switch( axis ) + { + default: + case X: + return new Vec3d( vec.xCoord + delta, vec.yCoord, vec.zCoord ); + case Y: + return new Vec3d( vec.xCoord, vec.yCoord + delta, vec.zCoord ); + case Z: + return new Vec3d( vec.xCoord, vec.yCoord, vec.zCoord + delta ); + } + } +} diff --git a/src/main/java/appeng/client/render/model/UVLModelLoader.java b/src/main/java/appeng/client/render/model/UVLModelLoader.java index 681c7886..9cbe8f75 100644 --- a/src/main/java/appeng/client/render/model/UVLModelLoader.java +++ b/src/main/java/appeng/client/render/model/UVLModelLoader.java @@ -320,9 +320,15 @@ public enum UVLModelLoader implements ICustomModelLoader lightmap[1] = brightness.getLeft(); } + @Override + public void setQuadTint( int tint ) + { + // Tint requires a block state which we don't have at this point + } }; trans.setParent( builder ); quad.pipe( trans ); + builder.setQuadTint( quad.getTintIndex() ); builder.setQuadOrientation( quad.getFace() ); return builder.build(); } diff --git a/src/main/java/appeng/core/features/AEBlockFeatureHandler.java b/src/main/java/appeng/core/features/AEBlockFeatureHandler.java index 7fd425b8..bf938989 100644 --- a/src/main/java/appeng/core/features/AEBlockFeatureHandler.java +++ b/src/main/java/appeng/core/features/AEBlockFeatureHandler.java @@ -25,6 +25,8 @@ 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; @@ -37,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; @@ -107,13 +110,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 839e5f9a..396e09c8 100644 --- a/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java +++ b/src/main/java/appeng/core/features/AETileBlockFeatureHandler.java @@ -26,6 +26,8 @@ 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; @@ -128,13 +130,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/core/features/ItemFeatureHandler.java b/src/main/java/appeng/core/features/ItemFeatureHandler.java index e460993c..56a0d96a 100644 --- a/src/main/java/appeng/core/features/ItemFeatureHandler.java +++ b/src/main/java/appeng/core/features/ItemFeatureHandler.java @@ -24,6 +24,7 @@ import java.util.EnumSet; import com.google.common.base.Optional; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; @@ -37,6 +38,7 @@ import appeng.api.definitions.IItemDefinition; import appeng.core.AppEng; import appeng.core.CreativeTab; import appeng.core.CreativeTabFacade; +import appeng.items.AEBaseItem; import appeng.items.parts.ItemFacade; @@ -99,7 +101,18 @@ public final class ItemFeatureHandler implements IFeatureHandler if( side == Side.CLIENT ) { - ModelBakery.registerItemVariants( item, registryName ); + if( item instanceof AEBaseItem ) + { + AEBaseItem baseItem = (AEBaseItem) item; + + // Handle registration of item variants + ResourceLocation[] variants = baseItem.getItemVariants().toArray( new ResourceLocation[0] ); + ModelBakery.registerItemVariants( item, variants ); + } + else + { + ModelBakery.registerItemVariants( item, registryName ); + } } } } @@ -107,7 +120,23 @@ public final class ItemFeatureHandler implements IFeatureHandler @Override public void registerModel() { - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, 0, new ModelResourceLocation( registryName, "inventory" ) ); + ItemMeshDefinition meshDefinition = null; + + // Register a custom item model handler if the item wants one + if( item instanceof AEBaseItem ) + { + AEBaseItem baseItem = (AEBaseItem) item; + meshDefinition = baseItem.getItemMeshDefinition(); + } + + if( meshDefinition != null ) + { + Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, meshDefinition ); + } + else + { + Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, 0, new ModelResourceLocation( registryName, "inventory" ) ); + } } @Override diff --git a/src/main/java/appeng/decorative/solid/BlockQuartzGlass.java b/src/main/java/appeng/decorative/solid/BlockQuartzGlass.java index 828f6cf0..da6cd9f5 100644 --- a/src/main/java/appeng/decorative/solid/BlockQuartzGlass.java +++ b/src/main/java/appeng/decorative/solid/BlockQuartzGlass.java @@ -22,19 +22,29 @@ package appeng.decorative.solid; import java.util.EnumSet; import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.property.ExtendedBlockState; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.common.property.IUnlistedProperty; import appeng.block.AEBaseBlock; +import appeng.block.IHasSpecialItemModel; import appeng.core.features.AEFeature; import appeng.helpers.AEGlassMaterial; -public class BlockQuartzGlass extends AEBaseBlock +public class BlockQuartzGlass extends AEBaseBlock implements IHasSpecialItemModel { + + // This unlisted property is used to determine the actual block that should be rendered + public static final UnlistedGlassStateProperty GLASS_STATE = new UnlistedGlassStateProperty(); + public BlockQuartzGlass() { super( Material.GLASS ); @@ -43,6 +53,40 @@ public class BlockQuartzGlass extends AEBaseBlock this.setFeature( EnumSet.of( AEFeature.DecorativeQuartzBlocks ) ); } + @Override + protected BlockStateContainer createBlockState() + { + IProperty[] listedProperties = new IProperty[0]; + IUnlistedProperty[] unlistedProperties = new IUnlistedProperty[] { GLASS_STATE }; + return new ExtendedBlockState( this, listedProperties, unlistedProperties ); + } + + @Override + public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos ) + { + + EnumSet flushWith = EnumSet.noneOf( EnumFacing.class ); + // Test every direction for another glass block + for( EnumFacing facing : EnumFacing.values() ) + { + if( isGlassBlock( world, pos, facing ) ) + { + flushWith.add( facing ); + } + } + + GlassState glassState = new GlassState( pos.getX(), pos.getY(), pos.getZ(), flushWith ); + + IExtendedBlockState extState = (IExtendedBlockState) state; + + return extState.withProperty( GLASS_STATE, glassState ); + } + + private static boolean isGlassBlock( IBlockAccess world, BlockPos pos, EnumFacing facing ) + { + return world.getBlockState( pos.offset( facing ) ).getBlock() instanceof BlockQuartzGlass; + } + @Override public BlockRenderLayer getBlockLayer() { @@ -52,14 +96,23 @@ public class BlockQuartzGlass extends AEBaseBlock @Override public boolean shouldSideBeRendered( final IBlockState state, final IBlockAccess w, final BlockPos pos, final EnumFacing side ) { - final Material mat = w.getBlockState( pos ).getBlock().getMaterial(state); + BlockPos adjacentPos = pos.offset( side ); + + final Material mat = w.getBlockState( adjacentPos ).getBlock().getMaterial( state ); if( mat == Material.GLASS || mat == AEGlassMaterial.INSTANCE ) { - if( w.getBlockState( pos ).getBlock().getRenderType(state) == this.getRenderType(state) ) + if( w.getBlockState( adjacentPos ).getBlock().getRenderType( state ) == this.getRenderType( state ) ) { return false; } } return super.shouldSideBeRendered( state, w, pos, side ); } -} + + @Override + public boolean isFullCube( IBlockState state ) + { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/appeng/decorative/solid/GlassState.java b/src/main/java/appeng/decorative/solid/GlassState.java new file mode 100644 index 00000000..83173311 --- /dev/null +++ b/src/main/java/appeng/decorative/solid/GlassState.java @@ -0,0 +1,67 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ +package appeng.decorative.solid; + + +import java.util.EnumSet; + +import net.minecraft.util.EnumFacing; + + +/** + * Immutable (and thus thread-safe) class that encapsulates the rendering state required for a connected texture + * glass block. + */ +public final class GlassState +{ + + private final int x; + private final int y; + private final int z; + + private final EnumSet flushWith = EnumSet.noneOf( EnumFacing.class ); + + public GlassState( int x, int y, int z, EnumSet flushWith ) + { + this.x = x; + this.y = y; + this.z = z; + this.flushWith.addAll( flushWith ); + } + + public int getX() + { + return x; + } + + public int getY() + { + return y; + } + + public int getZ() + { + return z; + } + + public boolean isFlushWith( EnumFacing side ) + { + return flushWith.contains( side ); + } + +} diff --git a/src/main/java/appeng/decorative/solid/UnlistedGlassStateProperty.java b/src/main/java/appeng/decorative/solid/UnlistedGlassStateProperty.java new file mode 100644 index 00000000..4d240d5b --- /dev/null +++ b/src/main/java/appeng/decorative/solid/UnlistedGlassStateProperty.java @@ -0,0 +1,54 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.decorative.solid; + + +import net.minecraftforge.common.property.IUnlistedProperty; + + +/** + * This unlisted property is used to transport the connected texture state into our model class. + */ +public class UnlistedGlassStateProperty implements IUnlistedProperty +{ + + @Override + public String getName() + { + return "glass_state"; + } + + @Override + public boolean isValid( GlassState value ) + { + return true; + } + + @Override + public Class getType() + { + return GlassState.class; + } + + @Override + public String valueToString( GlassState value ) + { + return null; + } +} diff --git a/src/main/java/appeng/items/AEBaseItem.java b/src/main/java/appeng/items/AEBaseItem.java index fb46c5f6..d2996cd3 100644 --- a/src/main/java/appeng/items/AEBaseItem.java +++ b/src/main/java/appeng/items/AEBaseItem.java @@ -23,16 +23,17 @@ import java.util.EnumSet; import java.util.List; import com.google.common.base.Optional; +import com.google.common.collect.Lists; -import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import appeng.client.ClientHelper; import appeng.core.features.AEFeature; import appeng.core.features.FeatureNameExtractor; import appeng.core.features.IAEFeature; @@ -106,11 +107,27 @@ public abstract class AEBaseItem extends Item implements IAEFeature super.addInformation( stack, player, lines, displayMoreInfo ); } - @SideOnly( Side.CLIENT ) - public void registerCustomIcon( final TextureMap map ){} - protected void getCheckedSubItems( final Item sameItem, final CreativeTabs creativeTab, final List itemStacks ) { super.getSubItems( sameItem, creativeTab, itemStacks ); } + + /** + * During registration of the item in the registry, this method is used to determine which models need to be registered for the item to be + * rendered. If your item subclass requires more than just the default, override this method and add them to the list, or replace it entirely. + */ + @SideOnly( Side.CLIENT ) + public List getItemVariants() { + return Lists.newArrayList( getRegistryName() ); + } + + /** + * If this item requires special logic to select the model for rendering, this method can be overriden to return that selection logic. + * Return null to use the standard logic. + */ + @SideOnly( Side.CLIENT ) + public ItemMeshDefinition getItemMeshDefinition() { + return null; + } + } diff --git a/src/main/java/appeng/items/materials/ItemMultiItem.java b/src/main/java/appeng/items/materials/ItemMultiItem.java index bf48b4f3..180f5317 100644 --- a/src/main/java/appeng/items/materials/ItemMultiItem.java +++ b/src/main/java/appeng/items/materials/ItemMultiItem.java @@ -30,10 +30,12 @@ import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; +import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; @@ -46,6 +48,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -61,7 +64,6 @@ import appeng.api.implementations.items.IUpgradeModule; import appeng.api.implementations.tiles.ISegmentedInventory; import appeng.api.parts.IPartHost; import appeng.api.parts.SelectedPart; -import appeng.client.ClientHelper; import appeng.core.AEConfig; import appeng.core.features.AEFeature; import appeng.core.features.IStackSrc; @@ -143,11 +145,8 @@ public final class ItemMultiItem extends AEBaseItem implements IStorageComponent public MaterialType getTypeByStack( final ItemStack is ) { - if( this.dmgToMaterial.containsKey( is.getItemDamage() ) ) - { - return this.dmgToMaterial.get( is.getItemDamage() ); - } - return MaterialType.InvalidType; + MaterialType type = this.dmgToMaterial.get( is.getItemDamage() ); + return (type != null) ? type : MaterialType.InvalidType; } @Override @@ -446,4 +445,23 @@ public final class ItemMultiItem extends AEBaseItem implements IStorageComponent return o1.compareTo( o2 ); } } + + @Override + @SideOnly( Side.CLIENT ) + public List getItemVariants() + { + // Register a resource location for every material type + return Arrays.stream( MaterialType.values() ) + .map( MaterialType::getModel ) + .collect( Collectors.toList() ); + + } + + @Override + @SideOnly( Side.CLIENT ) + public ItemMeshDefinition getItemMeshDefinition() + { + return is -> getTypeByStack( is ).getModel(); + } + } diff --git a/src/main/java/appeng/items/materials/MaterialType.java b/src/main/java/appeng/items/materials/MaterialType.java index 5caa5694..c5119e07 100644 --- a/src/main/java/appeng/items/materials/MaterialType.java +++ b/src/main/java/appeng/items/materials/MaterialType.java @@ -21,13 +21,11 @@ package appeng.items.materials; import java.util.EnumSet; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.Entity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.registry.EntityRegistry; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import appeng.core.AppEng; import appeng.core.features.AEFeature; @@ -118,9 +116,7 @@ public enum MaterialType CardCrafting( 53 ); private final EnumSet features; - // TextureAtlasSprite for the material. - @SideOnly( Side.CLIENT ) - private TextureAtlasSprite IIcon; + private final ModelResourceLocation model = new ModelResourceLocation( "appliedenergistics2:ItemMaterial." + name() ); private Item itemInstance; private int damageValue; // stack! @@ -221,16 +217,6 @@ public enum MaterialType this.itemInstance = itemInstance; } - TextureAtlasSprite getIIcon() - { - return this.IIcon; - } - - void setIIcon( final TextureAtlasSprite iIcon ) - { - this.IIcon = iIcon; - } - MaterialStackSrc getStackSrc() { return this.stackSrc; @@ -241,4 +227,8 @@ public enum MaterialType this.stackSrc = stackSrc; } + public ModelResourceLocation getModel() { + return model; + } + } diff --git a/src/main/java/appeng/items/misc/ItemCrystalSeed.java b/src/main/java/appeng/items/misc/ItemCrystalSeed.java index 21557d97..3b89979a 100644 --- a/src/main/java/appeng/items/misc/ItemCrystalSeed.java +++ b/src/main/java/appeng/items/misc/ItemCrystalSeed.java @@ -21,21 +21,21 @@ package appeng.items.misc; import java.util.EnumSet; import java.util.List; - import javax.annotation.Nullable; +import com.google.common.collect.ImmutableList; + import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -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.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.common.registry.EntityRegistry; import net.minecraftforge.fml.relauncher.Side; @@ -45,7 +45,6 @@ import appeng.api.AEApi; import appeng.api.definitions.IMaterials; import appeng.api.implementations.items.IGrowableCrystal; import appeng.api.recipes.ResolverResult; -import appeng.client.ClientHelper; import appeng.core.AppEng; import appeng.core.features.AEFeature; import appeng.core.localization.ButtonToolTips; @@ -91,11 +90,11 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal private static ItemStack newStyle( final ItemStack itemStack ) { - ( (ItemCrystalSeed) itemStack.getItem() ).getProgress( itemStack ); + getProgress( itemStack ); return itemStack; } - private int getProgress( final ItemStack is ) + private static int getProgress( final ItemStack is ) { if( is.hasTagCompound() ) { @@ -115,7 +114,7 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal @Override public ItemStack triggerGrowth( final ItemStack is ) { - final int newDamage = this.getProgress( is ) + 1; + final int newDamage = getProgress( is ) + 1; final IMaterials materials = AEApi.instance().definitions().materials(); final int size = is.stackSize; @@ -166,7 +165,7 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal public void addCheckedInformation( final ItemStack stack, final EntityPlayer player, final List lines, final boolean displayMoreInfo ) { lines.add( ButtonToolTips.DoesntDespawn.getLocal() ); - final int progress = this.getProgress( stack ) % SINGLE_OFFSET; + final int progress = getProgress( stack ) % SINGLE_OFFSET; lines.add( Math.floor( (float) progress / (float) ( SINGLE_OFFSET / 100 ) ) + "%" ); super.addCheckedInformation( stack, player, lines, displayMoreInfo ); @@ -181,7 +180,7 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal @Override public String getUnlocalizedName( final ItemStack is ) { - final int damage = this.getProgress( is ); + final int damage = getProgress( is ); if( damage < CERTUS + SINGLE_OFFSET ) { @@ -234,12 +233,9 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal egc.motionY = location.motionY; egc.motionZ = location.motionZ; - if( location instanceof EntityItem ) - { - // TODO: DELAY BEFORE PICKUP - // NEEDS FIXING?!?! - // egc.delayBeforeCanPickup = ( (EntityItem) location ).delayBeforeCanPickup; - } + // Cannot read the pickup delay of the original item, so we + // use the pickup delay used for items dropped by a player instead + egc.setPickupDelay(40); return egc; } @@ -262,4 +258,73 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal itemStacks.add( newStyle( new ItemStack( this, 1, LEVEL_OFFSET * 2 + NETHER ) ) ); itemStacks.add( newStyle( new ItemStack( this, 1, LEVEL_OFFSET * 2 + FLUIX ) ) ); } + + private static final ModelResourceLocation[] MODELS_CERTUS = { + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Certus" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Certus2" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Certus3" ) + }; + private static final ModelResourceLocation[] MODELS_FLUIX = { + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Fluix" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Fluix2" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Fluix3" ) + }; + private static final ModelResourceLocation[] MODELS_NETHER = { + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Nether" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Nether2" ), + new ModelResourceLocation( "appliedenergistics2:ItemCrystalSeed.Nether3" ) + }; + + @Override + @SideOnly( Side.CLIENT ) + public List getItemVariants() + { + return ImmutableList.builder().add( MODELS_CERTUS ).add( MODELS_FLUIX ).add( MODELS_NETHER ).build(); + } + + @Override + @SideOnly( Side.CLIENT ) + public ItemMeshDefinition getItemMeshDefinition() + { + return is -> { + int damage = getProgress( is ); + + // Split the damage value into crystal type and growth level + int type = damage / SINGLE_OFFSET; + int level = ( damage % SINGLE_OFFSET ) / LEVEL_OFFSET; + + // Determine which list of models to use based on the type of crystal + ModelResourceLocation[] models; + switch( type ) + { + case 0: + models = MODELS_CERTUS; + break; + case 1: + models = MODELS_NETHER; + break; + case 2: + models = MODELS_FLUIX; + break; + default: + // We use this as the fallback for broken items + models = MODELS_CERTUS; + break; + } + + // Return one of the 3 models based on the level + if( level < 0 ) + { + level = 0; + } + else if( level >= models.length ) + { + level = models.length - 1; + } + + return models[level]; + + }; + } + } diff --git a/src/main/java/appeng/items/misc/ItemPaintBall.java b/src/main/java/appeng/items/misc/ItemPaintBall.java index 314ecf2a..4f0fffbc 100644 --- a/src/main/java/appeng/items/misc/ItemPaintBall.java +++ b/src/main/java/appeng/items/misc/ItemPaintBall.java @@ -22,26 +22,21 @@ package appeng.items.misc; import java.util.EnumSet; import java.util.List; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; +import com.google.common.collect.ImmutableList; + import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.ModelResourceLocation; -import net.minecraft.client.renderer.color.IBlockColor; -import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.util.AEColor; -import appeng.client.ClientHelper; import appeng.core.features.AEFeature; import appeng.core.localization.GuiText; import appeng.items.AEBaseItem; -import appeng.util.Platform; public class ItemPaintBall extends AEBaseItem @@ -107,4 +102,44 @@ public class ItemPaintBall extends AEBaseItem final int dmg = is.getItemDamage(); return dmg >= DAMAGE_THRESHOLD; } + + public static int getColorFromItemstack( ItemStack stack, int tintIndex ) + { + final AEColor col = ( (ItemPaintBall) stack.getItem() ).getColor( stack ); + + final int colorValue = stack.getItemDamage() >= 20 ? col.mediumVariant : col.mediumVariant; + final int r = ( colorValue >> 16 ) & 0xff; + final int g = ( colorValue >> 8 ) & 0xff; + final int b = ( colorValue ) & 0xff; + + if( stack.getItemDamage() >= 20 ) + { + final float fail = 0.7f; + final int full = (int) ( 255 * 0.3 ); + return (int) ( full + r * fail ) << 16 | (int) ( full + g * fail ) << 8 | (int) ( full + b * fail ) | 0xff << 24; + } + else + { + return r << 16 | g << 8 | b | 0xff << 24; + } + } + + private static final ModelResourceLocation MODEL_NORMAL = new ModelResourceLocation( "appliedenergistics2:ItemPaintBall" ); + private static final ModelResourceLocation MODEL_SHIMMER = new ModelResourceLocation( "appliedenergistics2:ItemPaintBallShimmer" ); + + @Override + public List getItemVariants() + { + return ImmutableList.of( + MODEL_NORMAL, + MODEL_SHIMMER + ); + } + + @Override + @SideOnly( Side.CLIENT ) + public ItemMeshDefinition getItemMeshDefinition() + { + return is -> isLumen( is ) ? MODEL_SHIMMER : MODEL_NORMAL; + } } diff --git a/src/main/java/appeng/tile/networking/TileEnergyCell.java b/src/main/java/appeng/tile/networking/TileEnergyCell.java index 04051c21..14eaacc4 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/blockstates/quartz_lamp.json b/src/main/resources/assets/appliedenergistics2/blockstates/quartz_lamp.json new file mode 100644 index 00000000..09fb49b2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/blockstates/quartz_lamp.json @@ -0,0 +1,7 @@ +{ + "variants": { + "normal": { + "model": "appliedenergistics2:builtin/connected_glass" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/blockstates/quartz_torch.json b/src/main/resources/assets/appliedenergistics2/blockstates/quartz_torch.json new file mode 100644 index 00000000..0700ee83 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/blockstates/quartz_torch.json @@ -0,0 +1,48 @@ +{ + "variants": { + "facing=down,odd=false": { + "model": "appliedenergistics2:quartz_torch_standing", + "x": 180 + }, + "facing=down,odd=true": { + "model": "appliedenergistics2:quartz_torch_standing_odd", + "x": 180 + }, + "facing=east,odd=false": { + "model": "appliedenergistics2:quartz_torch_wall", + "y": 90 + }, + "facing=east,odd=true": { + "model": "appliedenergistics2:quartz_torch_wall_odd", + "y": 90 + }, + "facing=north,odd=false": { + "model": "appliedenergistics2:quartz_torch_wall" + }, + "facing=north,odd=true": { + "model": "appliedenergistics2:quartz_torch_wall_odd" + }, + "facing=south,odd=false": { + "model": "appliedenergistics2:quartz_torch_wall", + "y": 180 + }, + "facing=south,odd=true": { + "model": "appliedenergistics2:quartz_torch_wall_odd", + "y": 180 + }, + "facing=up,odd=false": { + "model": "appliedenergistics2:quartz_torch_standing" + }, + "facing=up,odd=true": { + "model": "appliedenergistics2:quartz_torch_standing_odd" + }, + "facing=west,odd=false": { + "model": "appliedenergistics2:quartz_torch_wall", + "y": 270 + }, + "facing=west,odd=true": { + "model": "appliedenergistics2:quartz_torch_wall_odd", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing.json b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing.json new file mode 100644 index 00000000..137c92ef --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing.json @@ -0,0 +1,305 @@ +{ + "elements": [ + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 3.0, + 6.0 + ], + "name": "Middle Plate", + "to": [ + 10.0, + 4.0, + 10.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 1.0, + 7.0 + ], + "name": "Lower Quartz Block", + "to": [ + 9.0, + 3.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 0.0, + 7.0 + ], + "name": "Lower Quartz Tip", + "to": [ + 8.0, + 1.0, + 8.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 4.0, + 7.0 + ], + "name": "Upper Quartz Block", + "to": [ + 9.0, + 6.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 8.0, + 6.0, + 8.0 + ], + "name": "Upper Quartz Tip", + "to": [ + 9.0, + 7.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 0.0, + 6.0 + ], + "name": "NW Feet", + "to": [ + 7.0, + 3.0, + 7.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 0.0, + 9.0 + ], + "name": "NE Feet", + "to": [ + 7.0, + 3.0, + 10.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 9.0, + 0.0, + 6.0 + ], + "name": "SW Feet", + "to": [ + 10.0, + 3.0, + 7.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 9.0, + 0.0, + 9.0 + ], + "name": "SE Feet", + "to": [ + 10.0, + 3.0, + 10.0 + ] + } + ], + "textures": { + "metal": "appliedenergistics2:blocks/quartz_torch_metal", + "quartz": "appliedenergistics2:blocks/quartz_torch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing_odd.json b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing_odd.json new file mode 100644 index 00000000..c37d8bcf --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_standing_odd.json @@ -0,0 +1,305 @@ +{ + "elements": [ + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 3.0, + 6.0 + ], + "name": "Middle Plate", + "to": [ + 10.0, + 4.0, + 10.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 1.0, + 7.0 + ], + "name": "Lower Quartz Block", + "to": [ + 9.0, + 3.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 8.0, + 0.0, + 8.0 + ], + "name": "Lower Quartz Tip", + "to": [ + 9.0, + 1.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 4.0, + 7.0 + ], + "name": "Upper Quartz Block", + "to": [ + 9.0, + 6.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 6.0, + 7.0 + ], + "name": "Upper Quartz Tip", + "to": [ + 8.0, + 7.0, + 8.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 0.0, + 6.0 + ], + "name": "NW Feet", + "to": [ + 7.0, + 3.0, + 7.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 0.0, + 9.0 + ], + "name": "NE Feet", + "to": [ + 7.0, + 3.0, + 10.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 9.0, + 0.0, + 6.0 + ], + "name": "SW Feet", + "to": [ + 10.0, + 3.0, + 7.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 9.0, + 0.0, + 9.0 + ], + "name": "SE Feet", + "to": [ + 10.0, + 3.0, + 10.0 + ] + } + ], + "textures": { + "metal": "appliedenergistics2:blocks/quartz_torch_metal", + "quartz": "appliedenergistics2:blocks/quartz_torch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall.json b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall.json new file mode 100644 index 00000000..c17543a6 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall.json @@ -0,0 +1,207 @@ +{ + "ambientocclusion": false, + "elements": [ + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 7.0, + 7.0, + 14.0 + ], + "name": "Connecting Strut", + "to": [ + 8.0, + 8.0, + 16.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 7.0, + 10.0 + ], + "name": "Middle Plate", + "to": [ + 10.0, + 8.0, + 14.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 5.0, + 11.0 + ], + "name": "Lower Quartz Block", + "to": [ + 9.0, + 7.0, + 13.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 4.0, + 11.0 + ], + "name": "Lower Quartz Tip", + "to": [ + 8.0, + 5.0, + 12.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 8.0, + 11.0 + ], + "name": "Upper Quartz Block", + "to": [ + 9.0, + 10.0, + 13.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 8.0, + 10.0, + 12.0 + ], + "name": "Upper Quartz Tip", + "to": [ + 9.0, + 11.0, + 13.0 + ] + } + ], + "textures": { + "metal": "appliedenergistics2:blocks/quartz_torch_metal", + "quartz": "appliedenergistics2:blocks/quartz_torch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall_odd.json b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall_odd.json new file mode 100644 index 00000000..f19c5713 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/quartz_torch_wall_odd.json @@ -0,0 +1,207 @@ +{ + "ambientocclusion": false, + "elements": [ + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 7.0, + 7.0, + 14.0 + ], + "name": "Connecting Strut", + "to": [ + 8.0, + 8.0, + 16.0 + ] + }, + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 7.0, + 10.0 + ], + "name": "Middle Plate", + "to": [ + 10.0, + 8.0, + 14.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 5.0, + 11.0 + ], + "name": "Lower Quartz Block", + "to": [ + 9.0, + 7.0, + 13.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 8.0, + 4.0, + 12.0 + ], + "name": "Lower Quartz Tip", + "to": [ + 9.0, + 5.0, + 13.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 8.0, + 11.0 + ], + "name": "Upper Quartz Block", + "to": [ + 9.0, + 10.0, + 13.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 10.0, + 11.0 + ], + "name": "Upper Quartz Tip", + "to": [ + 8.0, + 11.0, + 12.0 + ] + } + ], + "textures": { + "metal": "appliedenergistics2:blocks/quartz_torch_metal", + "quartz": "appliedenergistics2:blocks/quartz_torch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/creative_energy_cell.json b/src/main/resources/assets/appliedenergistics2/models/item/creative_energy_cell.json new file mode 100644 index 00000000..9a55f807 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/creative_energy_cell.json @@ -0,0 +1,3 @@ +{ + "parent": "appliedenergistics2:block/EnergyCell/creative_energy_cell" +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/material_invalid_type.json b/src/main/resources/assets/appliedenergistics2/models/item/material_invalid_type.json new file mode 100644 index 00000000..08b7f492 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/material_invalid_type.json @@ -0,0 +1,3 @@ +{ + "parent": "builtin/missing" +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/quartz_glass.json b/src/main/resources/assets/appliedenergistics2/models/item/quartz_glass.json new file mode 100644 index 00000000..cfe7da7d --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/quartz_glass.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "appliedenergistics2:items/quartz_glass" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/quartz_lamp.json b/src/main/resources/assets/appliedenergistics2/models/item/quartz_lamp.json new file mode 100644 index 00000000..cfe7da7d --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/quartz_lamp.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "appliedenergistics2:items/quartz_glass" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/quartz_torch.json b/src/main/resources/assets/appliedenergistics2/models/item/quartz_torch.json new file mode 100644 index 00000000..30e6cb3e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/quartz_torch.json @@ -0,0 +1,174 @@ +{ + "elements": [ + { + "faces": { + "down": { + "texture": "#metal" + }, + "east": { + "texture": "#metal" + }, + "north": { + "texture": "#metal" + }, + "south": { + "texture": "#metal" + }, + "up": { + "texture": "#metal" + }, + "west": { + "texture": "#metal" + } + }, + "from": [ + 6.0, + 8.0, + 6.0 + ], + "name": "Middle Plate", + "to": [ + 10.0, + 9.0, + 10.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 6.0, + 7.0 + ], + "name": "Lower Quartz Block", + "to": [ + 9.0, + 8.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 8.0, + 5.0, + 7.0 + ], + "name": "Lower Quartz Tip", + "to": [ + 9.0, + 6.0, + 8.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 9.0, + 7.0 + ], + "name": "Upper Quartz Block", + "to": [ + 9.0, + 11.0, + 9.0 + ] + }, + { + "faces": { + "down": { + "texture": "#quartz" + }, + "east": { + "texture": "#quartz" + }, + "north": { + "texture": "#quartz" + }, + "south": { + "texture": "#quartz" + }, + "up": { + "texture": "#quartz" + }, + "west": { + "texture": "#quartz" + } + }, + "from": [ + 7.0, + 11.0, + 8.0 + ], + "name": "Upper Quartz Tip", + "to": [ + 8.0, + 12.0, + 9.0 + ] + } + ], + "parent": "block/block", + "textures": { + "metal": "appliedenergistics2:blocks/quartz_torch_metal", + "quartz": "appliedenergistics2:blocks/quartz_torch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_block.json b/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_block.json index 7bfe2e69..cd20eec8 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_block.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_block.json @@ -1,35 +1,107 @@ { - "parent": "builtin/entity", "display": { - "gui": { - "rotation": [ 30, 45, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.625, 0.625, 0.625 ] - }, - "ground": { - "rotation": [ 0, 0, 0 ], - "translation": [ 0, 3, 0], - "scale":[ 0.25, 0.25, 0.25 ] - }, - "head": { - "rotation": [ 0, 180, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 1, 1, 1] + "firstperson_righthand": { + "rotation": [ + 0, + 315, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ], + "translation": [ + 0, + 0, + 0 + ] }, "fixed": { - "rotation": [ 0, 180, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.5, 0.5, 0.5 ] + "rotation": [ + 0, + 180, + 0 + ], + "scale": [ + 0.5, + 0.5, + 0.5 + ], + "translation": [ + 0, + 0, + 0 + ] + }, + "ground": { + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 0.25, + 0.25, + 0.25 + ], + "translation": [ + 0, + 3, + 0 + ] + }, + "gui": { + "rotation": [ + 30, + 45, + 0 + ], + "scale": [ + 0.625, + 0.625, + 0.625 + ], + "translation": [ + 0, + 0, + 0 + ] + }, + "head": { + "rotation": [ + 0, + 180, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "translation": [ + 0, + 0, + 0 + ] }, "thirdperson_righthand": { - "rotation": [ 75, 315, 0 ], - "translation": [ 0, 2.5, 0], - "scale": [ 0.375, 0.375, 0.375 ] - }, - "firstperson_righthand": { - "rotation": [ 0, 315, 0 ], - "translation": [ 0, 0, 0], - "scale": [ 0.4, 0.4, 0.4 ] + "rotation": [ + 75, + 315, + 0 + ], + "scale": [ + 0.375, + 0.375, + 0.375 + ], + "translation": [ + 0, + 2.5, + 0 + ] } - } -} + }, + "parent": "builtin/entity" +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_stone.json b/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_stone.json index 7bfe2e69..cd20eec8 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_stone.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/sky_chest_stone.json @@ -1,35 +1,107 @@ { - "parent": "builtin/entity", "display": { - "gui": { - "rotation": [ 30, 45, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.625, 0.625, 0.625 ] - }, - "ground": { - "rotation": [ 0, 0, 0 ], - "translation": [ 0, 3, 0], - "scale":[ 0.25, 0.25, 0.25 ] - }, - "head": { - "rotation": [ 0, 180, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 1, 1, 1] + "firstperson_righthand": { + "rotation": [ + 0, + 315, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ], + "translation": [ + 0, + 0, + 0 + ] }, "fixed": { - "rotation": [ 0, 180, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.5, 0.5, 0.5 ] + "rotation": [ + 0, + 180, + 0 + ], + "scale": [ + 0.5, + 0.5, + 0.5 + ], + "translation": [ + 0, + 0, + 0 + ] + }, + "ground": { + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 0.25, + 0.25, + 0.25 + ], + "translation": [ + 0, + 3, + 0 + ] + }, + "gui": { + "rotation": [ + 30, + 45, + 0 + ], + "scale": [ + 0.625, + 0.625, + 0.625 + ], + "translation": [ + 0, + 0, + 0 + ] + }, + "head": { + "rotation": [ + 0, + 180, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "translation": [ + 0, + 0, + 0 + ] }, "thirdperson_righthand": { - "rotation": [ 75, 315, 0 ], - "translation": [ 0, 2.5, 0], - "scale": [ 0.375, 0.375, 0.375 ] - }, - "firstperson_righthand": { - "rotation": [ 0, 315, 0 ], - "translation": [ 0, 0, 0], - "scale": [ 0.4, 0.4, 0.4 ] + "rotation": [ + 75, + 315, + 0 + ], + "scale": [ + 0.375, + 0.375, + 0.375 + ], + "translation": [ + 0, + 2.5, + 0 + ] } - } -} + }, + "parent": "builtin/entity" +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_a.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_a.png new file mode 100644 index 00000000..08ced73f Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_a.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_b.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_b.png new file mode 100644 index 00000000..51ce1f7d Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_b.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_c.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_c.png new file mode 100644 index 00000000..640b0bea Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_c.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_d.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_d.png new file mode 100644 index 00000000..78445807 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_d.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0001.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0001.png new file mode 100644 index 00000000..0096ebbb Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0001.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0010.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0010.png new file mode 100644 index 00000000..18e17893 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0010.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0011.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0011.png new file mode 100644 index 00000000..4c959e13 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0011.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0100.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0100.png new file mode 100644 index 00000000..8c28e98e Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0100.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0101.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0101.png new file mode 100644 index 00000000..c70506ed Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0101.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0110.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0110.png new file mode 100644 index 00000000..0a07653a Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0110.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0111.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0111.png new file mode 100644 index 00000000..bc2a7120 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame0111.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1000.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1000.png new file mode 100644 index 00000000..94863092 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1000.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1001.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1001.png new file mode 100644 index 00000000..6c7a463d Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1001.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1010.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1010.png new file mode 100644 index 00000000..6b63d165 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1010.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1011.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1011.png new file mode 100644 index 00000000..627f8a20 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1011.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1100.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1100.png new file mode 100644 index 00000000..1b816324 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1100.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1101.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1101.png new file mode 100644 index 00000000..67511a5a Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1101.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1110.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1110.png new file mode 100644 index 00000000..e8d0be18 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1110.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1111.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1111.png new file mode 100644 index 00000000..1b44a2e8 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/glass/quartz_glass_frame1111.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch.png new file mode 100644 index 00000000..4c61b6dd Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch_metal.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch_metal.png new file mode 100644 index 00000000..c2ef6662 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/blocks/quartz_torch_metal.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/quartz_glass.png b/src/main/resources/assets/appliedenergistics2/textures/items/quartz_glass.png new file mode 100644 index 00000000..520ced32 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/items/quartz_glass.png differ