Merge remote-tracking branch 'origin/1.10-rv3-rendering' into 1.10-rv3-rendering

# Conflicts:
#	src/main/java/appeng/decorative/solid/BlockQuartzGlass.java

#	src/main/resources/assets/appliedenergistics2/blockstates/QuartzGlassBlock.json
# Changed naming convention.
This commit is contained in:
elix-x 2016-08-19 12:49:25 +02:00
commit b31e5f5356
57 changed files with 2566 additions and 168 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 );
};
}
}

View File

@ -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;
}
}
}
}

View File

@ -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 );
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<ResourceLocation, TextureAtlasSprite> 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<BakedQuad> 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<BakedQuad> quads = new ArrayList<>( 5 ); // At most 5
List<Vec3d> 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<Vec3d> 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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<ResourceLocation> getDependencies()
{
return Collections.emptySet();
}
@Override
public Collection<ResourceLocation> getTextures()
{
return ImmutableSet.<ResourceLocation>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<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
return new GlassBakedModel( format, bakedTextureGetter );
}
@Override
public IModelState getDefaultState()
{
return TRSRTransformation.identity();
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 )
{
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<EnumFacing, List<Vec3d>> cornersForFacing = generateCornersForFacings();
private RenderHelper() {
}
static List<Vec3d> getFaceCorners( EnumFacing side )
{
return cornersForFacing.get( side );
}
private static EnumMap<EnumFacing, List<Vec3d>> generateCornersForFacings()
{
EnumMap<EnumFacing, List<Vec3d>> result = new EnumMap<>( EnumFacing.class );
for( EnumFacing facing : EnumFacing.values() )
{
List<Vec3d> 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 );
}
}
}

View File

@ -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();
}

View File

@ -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" ) );
}
}

View File

@ -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" ) );
}
}

View File

@ -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

View File

@ -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<EnumFacing> 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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<EnumFacing> flushWith = EnumSet.noneOf( EnumFacing.class );
public GlassState( int x, int y, int z, EnumSet<EnumFacing> 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 );
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<GlassState>
{
@Override
public String getName()
{
return "glass_state";
}
@Override
public boolean isValid( GlassState value )
{
return true;
}
@Override
public Class<GlassState> getType()
{
return GlassState.class;
}
@Override
public String valueToString( GlassState value )
{
return null;
}
}

View File

@ -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<ItemStack> 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<ResourceLocation> 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;
}
}

View File

@ -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<ResourceLocation> 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();
}
}

View File

@ -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<AEFeature> 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;
}
}

View File

@ -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<String> 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<ResourceLocation> getItemVariants()
{
return ImmutableList.<ResourceLocation>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];
};
}
}

View File

@ -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<ResourceLocation> getItemVariants()
{
return ImmutableList.of(
MODEL_NORMAL,
MODEL_SHIMMER
);
}
@Override
@SideOnly( Side.CLIENT )
public ItemMeshDefinition getItemMeshDefinition()
{
return is -> isLumen( is ) ? MODEL_SHIMMER : MODEL_NORMAL;
}
}

View File

@ -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 ) );
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"normal": {
"model": "appliedenergistics2:builtin/connected_glass"
}
}
}

View File

@ -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
}
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -0,0 +1,3 @@
{
"parent": "appliedenergistics2:block/EnergyCell/creative_energy_cell"
}

View File

@ -0,0 +1,3 @@
{
"parent": "builtin/missing"
}

View File

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "appliedenergistics2:items/quartz_glass"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "appliedenergistics2:items/quartz_glass"
}
}

View File

@ -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"
}
}

View File

@ -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"
}

View File

@ -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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B