Orientation Fixes when Placing Blocks with Tile Entities
Sky Compass Rendering (no rotation yet)
This commit is contained in:
@@ -21,15 +21,20 @@ package appeng.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.util.IOrientable;
|
||||
import appeng.api.util.IOrientableBlock;
|
||||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.me.helpers.IGridProxyable;
|
||||
import appeng.tile.AEBaseTile;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.World;
|
||||
@@ -73,123 +78,128 @@ public class AEBaseBlockItem extends BlockItem
|
||||
return this.blockType.getTranslationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType tryPlace(BlockItemUseContext context) {
|
||||
|
||||
// @Override
|
||||
// public boolean placeBlock( final ItemStack stack, final PlayerEntity player, final World w, final BlockPos pos, final Direction side, final float hitX, final float hitY, final float hitZ, final BlockState newState )
|
||||
// {
|
||||
// Direction up = null;
|
||||
// Direction forward = null;
|
||||
//
|
||||
// if( this.blockType instanceof AEBaseTileBlock )
|
||||
// {
|
||||
// if( this.blockType instanceof BlockLightDetector )
|
||||
// {
|
||||
// up = side;
|
||||
// if( up == Direction.UP || up == Direction.DOWN )
|
||||
// {
|
||||
// forward = Direction.SOUTH;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// forward = Direction.UP;
|
||||
// }
|
||||
// }
|
||||
// else if( this.blockType instanceof BlockWireless || this.blockType instanceof BlockSkyCompass )
|
||||
// {
|
||||
// forward = side;
|
||||
// if( forward == Direction.UP || forward == Direction.DOWN )
|
||||
// {
|
||||
// up = Direction.SOUTH;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// up = Direction.UP;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// up = Direction.UP;
|
||||
//
|
||||
// final byte rotation = (byte) ( MathHelper.floor( ( player.rotationYaw * 4F ) / 360F + 2.5D ) & 3 );
|
||||
//
|
||||
// switch( rotation )
|
||||
// {
|
||||
// default:
|
||||
// case 0:
|
||||
// forward = Direction.SOUTH;
|
||||
// break;
|
||||
// case 1:
|
||||
// forward = Direction.WEST;
|
||||
// break;
|
||||
// case 2:
|
||||
// forward = Direction.NORTH;
|
||||
// break;
|
||||
// case 3:
|
||||
// forward = Direction.EAST;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if( player.rotationPitch > 65 )
|
||||
// {
|
||||
// up = forward.getOpposite();
|
||||
// forward = Direction.UP;
|
||||
// }
|
||||
// else if( player.rotationPitch < -65 )
|
||||
// {
|
||||
// up = forward.getOpposite();
|
||||
// forward = Direction.DOWN;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// IOrientable ori = null;
|
||||
// if( this.blockType instanceof IOrientableBlock )
|
||||
// {
|
||||
// ori = ( (IOrientableBlock) this.blockType ).getOrientable( w, pos );
|
||||
// up = side;
|
||||
// forward = Direction.SOUTH;
|
||||
// if( up.getYOffset() == 0 )
|
||||
// {
|
||||
// forward = Direction.UP;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if( !this.blockType.isValidOrientation( w, pos, forward, up ) )
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if( super.placeBlock( stack, player, w, pos, side, hitX, hitY, hitZ, newState ) )
|
||||
// {
|
||||
// if( this.blockType instanceof AEBaseTileBlock && !( this.blockType instanceof BlockLightDetector ) )
|
||||
// {
|
||||
// final AEBaseTile tile = ( (AEBaseTileBlock) this.blockType ).getTileEntity( w, pos );
|
||||
// ori = tile;
|
||||
//
|
||||
// if( tile == null )
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if( ori.canBeRotated() && !this.blockType.hasCustomRotation() )
|
||||
// {
|
||||
// ori.setOrientation( forward, up );
|
||||
// }
|
||||
//
|
||||
// if( tile instanceof IGridProxyable )
|
||||
// {
|
||||
// ( (IGridProxyable) tile ).getProxy().setOwner( player );
|
||||
// }
|
||||
//
|
||||
// tile.onPlacement( stack, player, side );
|
||||
// }
|
||||
// else if( this.blockType instanceof IOrientableBlock )
|
||||
// {
|
||||
// ori.setOrientation( forward, up );
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
Direction up = null;
|
||||
Direction forward = null;
|
||||
|
||||
Direction side = context.getFace();
|
||||
PlayerEntity player = context.getPlayer();
|
||||
|
||||
if( this.blockType instanceof AEBaseTileBlock )
|
||||
{
|
||||
// FIXME if( this.blockType instanceof BlockLightDetector )
|
||||
// FIXME {
|
||||
// FIXME up = side;
|
||||
// FIXME if( up == Direction.UP || up == Direction.DOWN )
|
||||
// FIXME {
|
||||
// FIXME forward = Direction.SOUTH;
|
||||
// FIXME }
|
||||
// FIXME else
|
||||
// FIXME {
|
||||
// FIXME forward = Direction.UP;
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
/* FIXME else */ if( /*this.blockType instanceof BlockWireless ||*/ this.blockType instanceof BlockSkyCompass)
|
||||
{
|
||||
forward = side;
|
||||
if( forward == Direction.UP || forward == Direction.DOWN )
|
||||
{
|
||||
up = Direction.SOUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
up = Direction.UP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
up = Direction.UP;
|
||||
|
||||
// FIXME: investigate placementYaw
|
||||
final byte rotation = (byte) ( MathHelper.floor( ( player.rotationYaw * 4F ) / 360F + 2.5D ) & 3 );
|
||||
|
||||
switch( rotation )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
forward = Direction.SOUTH;
|
||||
break;
|
||||
case 1:
|
||||
forward = Direction.WEST;
|
||||
break;
|
||||
case 2:
|
||||
forward = Direction.NORTH;
|
||||
break;
|
||||
case 3:
|
||||
forward = Direction.EAST;
|
||||
break;
|
||||
}
|
||||
|
||||
if( player.rotationPitch > 65 )
|
||||
{
|
||||
up = forward.getOpposite();
|
||||
forward = Direction.UP;
|
||||
}
|
||||
else if( player.rotationPitch < -65 )
|
||||
{
|
||||
up = forward.getOpposite();
|
||||
forward = Direction.DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IOrientable ori = null;
|
||||
if( this.blockType instanceof IOrientableBlock)
|
||||
{
|
||||
ori = ( (IOrientableBlock) this.blockType ).getOrientable( context.getWorld(), context.getPos() );
|
||||
up = side;
|
||||
forward = Direction.SOUTH;
|
||||
if( up.getYOffset() == 0 )
|
||||
{
|
||||
forward = Direction.UP;
|
||||
}
|
||||
}
|
||||
|
||||
if( !this.blockType.isValidOrientation( context.getWorld(), context.getPos(), forward, up ) )
|
||||
{
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
ActionResultType result = super.tryPlace(context);
|
||||
if (result != ActionResultType.SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if( this.blockType instanceof AEBaseTileBlock /* FIXME && !( this.blockType instanceof BlockLightDetector ) */ )
|
||||
{
|
||||
final AEBaseTile tile = ( (AEBaseTileBlock<?>) this.blockType ).getTileEntity( context.getWorld(), context.getPos() );
|
||||
ori = tile;
|
||||
|
||||
if( tile == null )
|
||||
{
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
if( ori.canBeRotated() && !this.blockType.hasCustomRotation() )
|
||||
{
|
||||
ori.setOrientation( forward, up );
|
||||
}
|
||||
|
||||
if( tile instanceof IGridProxyable)
|
||||
{
|
||||
( (IGridProxyable) tile ).getProxy().setOwner( player );
|
||||
}
|
||||
|
||||
tile.onPlacement( context );
|
||||
}
|
||||
else if( this.blockType instanceof IOrientableBlock )
|
||||
{
|
||||
ori.setOrientation( forward, up );
|
||||
}
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,9 +122,11 @@ public class BlockLightDetector extends AEBaseTileBlock implements IOrientableBl
|
||||
return this.canPlaceAt( w, pos, up.getOpposite() );
|
||||
}
|
||||
|
||||
private boolean canPlaceAt( final World w, final BlockPos pos, final Direction dir )
|
||||
private boolean canPlaceAt( final IBlockReader w, final BlockPos pos, final Direction dir )
|
||||
{
|
||||
return w.isSideSolid( pos.offset( dir ), dir.getOpposite(), false );
|
||||
final BlockPos test = pos.offset( dir );
|
||||
BlockState blockstate = w.getBlockState(test);
|
||||
return blockstate.isSolidSide(w, test, dir.getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,48 +19,31 @@
|
||||
package appeng.block.misc;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.BlockStateContainer;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.BlockRenderType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.common.property.PropertyFloat;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.helpers.ICustomCollision;
|
||||
import appeng.tile.misc.TileSkyCompass;
|
||||
|
||||
|
||||
public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
||||
public class BlockSkyCompass extends AEBaseTileBlock<TileSkyCompass>
|
||||
{
|
||||
|
||||
// Rotation is expressed as radians
|
||||
public static final PropertyFloat ROTATION = new PropertyFloat( "rotation" );
|
||||
|
||||
public BlockSkyCompass()
|
||||
public BlockSkyCompass(Block.Properties props)
|
||||
{
|
||||
super( Material.MISCELLANEOUS );
|
||||
this.setLightOpacity( 0 );
|
||||
this.setFullSize( false );
|
||||
this.setOpaque( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState()
|
||||
{
|
||||
return new ExtendedBlockState( this, this.getAEStates(), new IUnlistedProperty[] { FORWARD, UP, ROTATION } );
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,9 +57,11 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
||||
return this.canPlaceAt( w, pos, forward.getOpposite() );
|
||||
}
|
||||
|
||||
private boolean canPlaceAt( final World w, final BlockPos pos, final Direction dir )
|
||||
private boolean canPlaceAt( final IBlockReader w, final BlockPos pos, final Direction dir )
|
||||
{
|
||||
return w.isSideSolid( pos.offset( dir ), dir.getOpposite(), false );
|
||||
final BlockPos test = pos.offset( dir );
|
||||
BlockState blockstate = w.getBlockState(test);
|
||||
return blockstate.isSolidSide(w, test, dir.getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +96,10 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool( final World w, final BlockPos pos, final Entity thePlayer, final boolean b )
|
||||
{
|
||||
public VoxelShape getShape(BlockState state, IBlockReader w, BlockPos pos, ISelectionContext context) {
|
||||
|
||||
// TODO: This definitely needs to be memoized
|
||||
|
||||
final TileSkyCompass tile = this.getTileEntity( w, pos );
|
||||
if( tile != null )
|
||||
{
|
||||
@@ -167,27 +154,20 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
||||
break;
|
||||
}
|
||||
|
||||
return Collections.singletonList( new AxisAlignedBB( minX, minY, minZ, maxX, maxY, maxZ ) );
|
||||
return VoxelShapes.create(new AxisAlignedBB( minX, minY, minZ, maxX, maxY, maxZ ) );
|
||||
}
|
||||
return Collections.singletonList( new AxisAlignedBB( 0.0, 0, 0.0, 1.0, 1.0, 1.0 ) );
|
||||
return VoxelShapes.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCollidingBlockToList( final World w, final BlockPos pos, final AxisAlignedBB bb, final List<AxisAlignedBB> out, final Entity e )
|
||||
{
|
||||
|
||||
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return VoxelShapes.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType( BlockState state )
|
||||
public BlockRenderType getRenderType(BlockState state )
|
||||
{
|
||||
return BlockRenderType.ENTITYBLOCK_ANIMATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullBlock( BlockState state )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,29 +19,21 @@
|
||||
package appeng.block.misc;
|
||||
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import appeng.bootstrap.*;
|
||||
import appeng.client.render.tesr.SkyCompassTESR;
|
||||
import appeng.tile.misc.TileSkyCompass;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
import appeng.client.render.model.SkyCompassModel;
|
||||
import appeng.client.render.tesr.SkyCompassTESR;
|
||||
|
||||
|
||||
public class SkyCompassRendering extends BlockRenderingCustomizer
|
||||
public class SkyCompassRendering extends TileEntityRenderingCustomizer<TileSkyCompass>
|
||||
{
|
||||
|
||||
private static final ModelResourceLocation ITEM_MODEL = new ModelResourceLocation( "appliedenergistics2:sky_compass", "normal" );
|
||||
|
||||
@Override
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
|
||||
{
|
||||
rendering.tileEntityRenderer( new SkyCompassTESR() );
|
||||
itemRendering.model( ITEM_MODEL );
|
||||
itemRendering.builtInModel( "models/block/builtin/sky_compass", new SkyCompassModel() );
|
||||
public void customize(TileEntityRendering<TileSkyCompass> rendering) {
|
||||
rendering.tileEntityRenderer( SkyCompassTESR::new );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -201,11 +201,11 @@ public class AutoRotatingModel implements IBakedModel
|
||||
for( int e = 0; e < count; e++ )
|
||||
{
|
||||
VertexFormatElement element = format.getElement( e );
|
||||
if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION )
|
||||
if( element.getUsage() == VertexFormatElement.Usage.POSITION )
|
||||
{
|
||||
this.parent.put( e, this.transform( this.quadData[e][v] ) );
|
||||
}
|
||||
else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
|
||||
else if( element.getUsage() == VertexFormatElement.Usage.NORMAL )
|
||||
{
|
||||
this.parent.put( e, this.transformNormal( this.quadData[e][v] ) );
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.google.common.base.Strings;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.model.Material;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
@@ -47,7 +46,6 @@ import appeng.decorative.solid.BlockQuartzGlass;
|
||||
import appeng.decorative.solid.GlassState;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraftforge.client.model.ModelDataManager;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector4f;
|
||||
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.Vector4f;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Applies an arbitrary transformation matrix to the vertices of a quad.
|
||||
@@ -46,18 +47,19 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||
protected void processQuad()
|
||||
{
|
||||
VertexFormat format = this.parent.getVertexFormat();
|
||||
int count = format.getElementCount();
|
||||
List<VertexFormatElement> elements = format.getElements();
|
||||
int count = elements.size();
|
||||
|
||||
for( int v = 0; v < 4; v++ )
|
||||
{
|
||||
for( int e = 0; e < count; e++ )
|
||||
{
|
||||
VertexFormatElement element = format.getElement( e );
|
||||
if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION )
|
||||
VertexFormatElement element = elements.get( e );
|
||||
if( element.getUsage() == VertexFormatElement.Usage.POSITION )
|
||||
{
|
||||
this.parent.put( e, this.transform( this.quadData[e][v], element.getElementCount() ) );
|
||||
}
|
||||
else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
|
||||
else if( element.getUsage() == VertexFormatElement.Usage.NORMAL )
|
||||
{
|
||||
this.parent.put( e, this.transformNormal( this.quadData[e][v] ) );
|
||||
}
|
||||
@@ -98,38 +100,38 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||
switch( fs.length )
|
||||
{
|
||||
case 3:
|
||||
javax.vecmath.Vector3f vec = new javax.vecmath.Vector3f( fs[0], fs[1], fs[2] );
|
||||
vec.x -= 0.5f;
|
||||
vec.y -= 0.5f;
|
||||
vec.z -= 0.5f;
|
||||
this.transform.transform( vec );
|
||||
vec.x += 0.5f;
|
||||
vec.y += 0.5f;
|
||||
vec.z += 0.5f;
|
||||
Vector4f vec = new Vector4f( fs[0], fs[1], fs[2], 1 );
|
||||
vec.setX(vec.getX() - 0.5f);
|
||||
vec.setY(vec.getY() - 0.5f);
|
||||
vec.setZ(vec.getZ() - 0.5f);
|
||||
vec.transform(this.transform); // FIXME: Check this, we're using a Vec4, input is Vec3
|
||||
vec.setX(vec.getX() + 0.5f);
|
||||
vec.setY(vec.getY() + 0.5f);
|
||||
vec.setZ(vec.getZ() + 0.5f);
|
||||
return new float[] {
|
||||
vec.x,
|
||||
vec.y,
|
||||
vec.z
|
||||
vec.getX(),
|
||||
vec.getY(),
|
||||
vec.getZ()
|
||||
};
|
||||
case 4:
|
||||
Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
||||
// Otherwise all translation is lost
|
||||
if( elemCount == 3 )
|
||||
{
|
||||
vecc.w = 1;
|
||||
vecc.setW(1);
|
||||
}
|
||||
vecc.x -= 0.5f;
|
||||
vecc.y -= 0.5f;
|
||||
vecc.z -= 0.5f;
|
||||
this.transform.transform( vecc );
|
||||
vecc.x += 0.5f;
|
||||
vecc.y += 0.5f;
|
||||
vecc.z += 0.5f;
|
||||
vecc.setX(vecc.getX() - 0.5f);
|
||||
vecc.setY(vecc.getY() - 0.5f);
|
||||
vecc.setZ(vecc.getZ() - 0.5f);
|
||||
vecc.transform(this.transform);
|
||||
vecc.setX(vecc.getX() + 0.5f);
|
||||
vecc.setY(vecc.getY() + 0.5f);
|
||||
vecc.setZ(vecc.getZ() + 0.5f);
|
||||
return new float[] {
|
||||
vecc.x,
|
||||
vecc.y,
|
||||
vecc.z,
|
||||
vecc.w
|
||||
vecc.getX(),
|
||||
vecc.getY(),
|
||||
vecc.getZ(),
|
||||
vecc.getW()
|
||||
};
|
||||
|
||||
default:
|
||||
@@ -145,23 +147,23 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||
{
|
||||
case 3:
|
||||
normal = new Vector4f( fs[0], fs[1], fs[2], 0 );
|
||||
this.transform.transform( normal );
|
||||
normal.transform(this.transform);
|
||||
normal.normalize();
|
||||
return new float[] {
|
||||
normal.x,
|
||||
normal.y,
|
||||
normal.z
|
||||
normal.getX(),
|
||||
normal.getY(),
|
||||
normal.getZ()
|
||||
};
|
||||
|
||||
case 4:
|
||||
normal = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
||||
this.transform.transform( normal );
|
||||
normal.transform(this.transform);
|
||||
normal.normalize();
|
||||
return new float[] {
|
||||
normal.x,
|
||||
normal.y,
|
||||
normal.z,
|
||||
normal.w
|
||||
normal.getX(),
|
||||
normal.getY(),
|
||||
normal.getZ(),
|
||||
normal.getW()
|
||||
};
|
||||
|
||||
default:
|
||||
|
||||
@@ -22,13 +22,14 @@ package appeng.client.render.model;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.AxisAngle4f;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.entity.PlayerEntitySP;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
@@ -40,20 +41,21 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
|
||||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.hooks.CompassManager;
|
||||
import appeng.hooks.CompassResult;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* This baked model combines the quads of a compass base and the quads of a compass pointer, which will be rotated
|
||||
* around the Y-axis to get the compass to point in the right direction.
|
||||
*/
|
||||
public class SkyCompassBakedModel implements IBakedModel
|
||||
public class SkyCompassBakedModel implements IDynamicBakedModel
|
||||
{
|
||||
// Rotation is expressed as radians
|
||||
public static final ModelProperty<Float> ROTATION = new ModelProperty<>();
|
||||
|
||||
private final IBakedModel base;
|
||||
|
||||
@@ -68,19 +70,15 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, long rand )
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand, IModelData extraData )
|
||||
{
|
||||
float rotation = 0;
|
||||
// Get rotation from the special block state
|
||||
if( state instanceof IExtendedBlockState )
|
||||
{
|
||||
Float rotationOpt = ( (IExtendedBlockState) state ).getValue( BlockSkyCompass.ROTATION );
|
||||
if( rotationOpt != null )
|
||||
{
|
||||
rotation = rotationOpt;
|
||||
}
|
||||
Float rotationFromData = extraData.getData(ROTATION);
|
||||
if (rotationFromData != null) {
|
||||
rotation = rotationFromData;
|
||||
}
|
||||
else if( state == null )
|
||||
else
|
||||
{
|
||||
// This is used to render a compass pointing in a specific direction when being held in hand
|
||||
rotation = this.fallbackRotation;
|
||||
@@ -88,8 +86,7 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
|
||||
// Pre-compute the quad count to avoid list resizes
|
||||
List<BakedQuad> quads = new ArrayList<>();
|
||||
|
||||
quads.addAll( this.base.getQuads( state, side, rand ) );
|
||||
quads.addAll( this.base.getQuads( state, side, rand, extraData ) );
|
||||
|
||||
// We'll add the pointer as "sideless"
|
||||
if( side == null )
|
||||
@@ -97,17 +94,18 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
// Set up the rotation around the Y-axis for the pointer
|
||||
Matrix4f matrix = new Matrix4f();
|
||||
matrix.setIdentity();
|
||||
matrix.setRotation( new AxisAngle4f( 0, 1, 0, rotation ) );
|
||||
matrix.mul( new Quaternion( 0, rotation, 0, false ) );
|
||||
|
||||
MatrixVertexTransformer transformer = new MatrixVertexTransformer( matrix );
|
||||
for( BakedQuad bakedQuad : this.pointer.getQuads( state, side, rand ) )
|
||||
for( BakedQuad bakedQuad : this.pointer.getQuads( state, side, rand, extraData ) )
|
||||
{
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( bakedQuad.getFormat() );
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder();
|
||||
|
||||
transformer.setParent( builder );
|
||||
transformer.setVertexFormat( builder.getVertexFormat() );
|
||||
bakedQuad.pipe( transformer );
|
||||
builder.setQuadOrientation( null ); // After rotation, facing a specific side cannot be guaranteed
|
||||
// FIXME: This entire code is no longer truly valid...
|
||||
// FIXME builder.setQuadOrientation( null ); // After rotation, facing a specific side cannot be guaranteed
|
||||
// anymore
|
||||
BakedQuad q = builder.build();
|
||||
quads.add( q );
|
||||
@@ -129,6 +127,11 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
@@ -155,13 +158,12 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
* animate using the
|
||||
* spinning animation.
|
||||
*/
|
||||
return new ItemOverrideList( Collections.emptyList() )
|
||||
return new ItemOverrideList()
|
||||
{
|
||||
|
||||
@Override
|
||||
public IBakedModel handleItemState( IBakedModel originalModel, ItemStack stack, World world, LivingEntity entity )
|
||||
{
|
||||
if( world != null && entity instanceof PlayerEntitySP )
|
||||
public IBakedModel getModelWithOverrides(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable LivingEntity entity) {
|
||||
// FIXME: This check prevents compasses being held by OTHERS from getting the rotation, BUT do we actually still need this???
|
||||
if (world != null && entity instanceof ClientPlayerEntity)
|
||||
{
|
||||
PlayerEntity player = (PlayerEntity) entity;
|
||||
|
||||
@@ -186,38 +188,38 @@ public class SkyCompassBakedModel implements IBakedModel
|
||||
{
|
||||
|
||||
// Only query for a meteor position if we know our own position
|
||||
if( pos != null )
|
||||
{
|
||||
CompassResult cr = CompassManager.INSTANCE.getCompassDirection( 0, pos.getX(), pos.getY(), pos.getZ() );
|
||||
|
||||
// Prefetch meteor positions from the server for adjacent blocks so they are available more quickly when
|
||||
// we're moving
|
||||
if( prefetch )
|
||||
{
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
for( int j = 0; j < 3; j++ )
|
||||
{
|
||||
CompassManager.INSTANCE.getCompassDirection( 0, pos.getX() + i - 1, pos.getY(), pos.getZ() + j - 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( cr.isValidResult() )
|
||||
{
|
||||
if( cr.isSpin() )
|
||||
{
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// .5 seconds per full rotation
|
||||
timeMillis %= 500;
|
||||
return timeMillis / 500.f * (float) Math.PI * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float) cr.getRad();
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME if( pos != null )
|
||||
// FIXME {
|
||||
// FIXME CompassResult cr = CompassManager.INSTANCE.getCompassDirection( 0, pos.getX(), pos.getY(), pos.getZ() );
|
||||
// FIXME
|
||||
// FIXME // Prefetch meteor positions from the server for adjacent blocks so they are available more quickly when
|
||||
// FIXME // we're moving
|
||||
// FIXME if( prefetch )
|
||||
// FIXME {
|
||||
// FIXME for( int i = 0; i < 3; i++ )
|
||||
// FIXME {
|
||||
// FIXME for( int j = 0; j < 3; j++ )
|
||||
// FIXME {
|
||||
// FIXME CompassManager.INSTANCE.getCompassDirection( 0, pos.getX() + i - 1, pos.getY(), pos.getZ() + j - 1 );
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
// FIXME
|
||||
// FIXME if( cr.isValidResult() )
|
||||
// FIXME {
|
||||
// FIXME if( cr.isSpin() )
|
||||
// FIXME {
|
||||
// FIXME long timeMillis = System.currentTimeMillis();
|
||||
// FIXME // .5 seconds per full rotation
|
||||
// FIXME timeMillis %= 500;
|
||||
// FIXME return timeMillis / 500.f * (float) Math.PI * 2;
|
||||
// FIXME }
|
||||
// FIXME else
|
||||
// FIXME {
|
||||
// FIXME return (float) cr.getRad();
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// 3 seconds per full rotation
|
||||
|
||||
@@ -19,69 +19,44 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.model.*;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
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.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
|
||||
/**
|
||||
* The parent model for the compass baked model. Declares the dependencies for the base and pointer submodels mostly.
|
||||
*/
|
||||
public class SkyCompassModel implements IModel
|
||||
public class SkyCompassModel implements IModelGeometry<SkyCompassModel>
|
||||
{
|
||||
|
||||
private static final ResourceLocation MODEL_BASE = new ResourceLocation( "appliedenergistics2:block/sky_compass_base" );
|
||||
|
||||
private static final ResourceLocation MODEL_POINTER = new ResourceLocation( "appliedenergistics2:block/sky_compass_pointer" );
|
||||
|
||||
private static final List<ResourceLocation> DEPENDENCIES = ImmutableList.of( MODEL_BASE, MODEL_POINTER );
|
||||
public static final List<ResourceLocation> DEPENDENCIES = ImmutableList.of( MODEL_BASE, MODEL_POINTER );
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return DEPENDENCIES;
|
||||
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation) {
|
||||
IBakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
|
||||
IBakedModel pointerModel = bakery.getBakedModel(MODEL_POINTER, modelTransform, spriteGetter);
|
||||
|
||||
return new SkyCompassBakedModel( baseModel, pointerModel );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getTextures()
|
||||
{
|
||||
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
IModel baseModel, pointerModel;
|
||||
try
|
||||
{
|
||||
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
|
||||
pointerModel = ModelLoaderRegistry.getModel( MODEL_POINTER );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
IBakedModel bakedBase = baseModel.bake( state, format, bakedTextureGetter );
|
||||
IBakedModel bakedPointer = pointerModel.bake( state, format, bakedTextureGetter );
|
||||
return new SkyCompassBakedModel( bakedBase, bakedPointer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Allows the built-in sky compass model the be loaded from JSON.
|
||||
*/
|
||||
public class SkyCompassModelLoader implements IModelLoader<SkyCompassModel> {
|
||||
|
||||
public static final SkyCompassModelLoader INSTANCE = new SkyCompassModelLoader();
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkyCompassModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
|
||||
return new SkyCompassModel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,17 +19,23 @@
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
|
||||
import appeng.client.render.model.SkyCompassModel;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.Atlases;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.client.model.animation.FastTESR;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -41,56 +47,52 @@ import appeng.tile.misc.TileSkyCompass;
|
||||
|
||||
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public class SkyCompassTESR extends FastTESR<TileSkyCompass>
|
||||
public class SkyCompassTESR extends TileEntityRenderer<TileSkyCompass>
|
||||
{
|
||||
|
||||
private static BlockRendererDispatcher blockRenderer;
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast( TileSkyCompass te, double x, double y, double z, float partialTicks, int destroyStage, float var10, BufferBuilder buffer )
|
||||
{
|
||||
public SkyCompassTESR(TileEntityRendererDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
if( !te.hasWorld() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void render(TileSkyCompass te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffers, int combinedLightIn, int combinedOverlayIn) {
|
||||
|
||||
if( blockRenderer == null )
|
||||
{
|
||||
blockRenderer = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
}
|
||||
|
||||
BlockPos pos = te.getPos();
|
||||
IBlockReader world = MinecraftForgeClient.getRegionRenderCache( te.getWorld(), pos );
|
||||
BlockState state = world.getBlockState( pos );
|
||||
if( state.getPropertyKeys().contains( Properties.StaticProperty ) )
|
||||
{
|
||||
state = state.with( Properties.StaticProperty, false );
|
||||
}
|
||||
IVertexBuilder buffer = buffers.getBuffer(Atlases.getTranslucentBlockType());
|
||||
|
||||
if( state instanceof IExtendedBlockState )
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState) state.getBlock().getExtendedState( state, world, pos );
|
||||
BlockState blockState = te.getBlockState();
|
||||
IBakedModel model = blockRenderer.getBlockModelShapes().getModel( blockState );
|
||||
|
||||
IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState( exState.getClean() );
|
||||
exState = exState.with( BlockSkyCompass.ROTATION, getRotation( te ) );
|
||||
ModelDataMap modelData = new ModelDataMap.Builder()
|
||||
.withInitial(SkyCompassBakedModel.ROTATION, getRotation(te))
|
||||
.build();
|
||||
|
||||
// Flip forward/up for rendering, the base model is facing up without any rotation
|
||||
Direction forward = exState.getValue( AEBaseTileBlock.FORWARD );
|
||||
Direction up = exState.getValue( AEBaseTileBlock.UP );
|
||||
// This ensures the needle isn't flipped by the model rotator. Since the model is symmetrical, this should
|
||||
// not affect the appearance
|
||||
if( forward == Direction.UP || forward == Direction.DOWN )
|
||||
{
|
||||
up = Direction.NORTH;
|
||||
}
|
||||
exState = exState.with( AEBaseTileBlock.FORWARD, up )
|
||||
.with( AEBaseTileBlock.UP, forward );
|
||||
ms.push();
|
||||
// FIXME: Rotation was previously handled by an auto rotating model I think, but
|
||||
// FIXME: Should be handled using matrices instead
|
||||
// // Flip forward/up for rendering, the base model is facing up without any rotation
|
||||
// Direction forward = exState.getValue( AEBaseTileBlock.FORWARD );
|
||||
// Direction up = exState.getValue( AEBaseTileBlock.UP );
|
||||
// // This ensures the needle isn't flipped by the model rotator. Since the model is symmetrical, this should
|
||||
// // not affect the appearance
|
||||
// if( forward == Direction.UP || forward == Direction.DOWN )
|
||||
// {
|
||||
// up = Direction.NORTH;
|
||||
// }
|
||||
// exState = exState.with( AEBaseTileBlock.FORWARD, up )
|
||||
// .with( AEBaseTileBlock.UP, forward );
|
||||
//
|
||||
// buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() );
|
||||
|
||||
buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() );
|
||||
blockRenderer.getBlockModelRenderer().renderModel( ms.getLast(), buffer, null, model, 1, 1, 1, combinedLightIn, combinedOverlayIn, modelData );
|
||||
ms.pop();
|
||||
|
||||
blockRenderer.getBlockModelRenderer().renderModel( world, model, exState, pos, buffer, false );
|
||||
}
|
||||
}
|
||||
|
||||
private static float getRotation( TileSkyCompass skyCompass )
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.File;
|
||||
import appeng.bootstrap.components.IClientSetupComponent;
|
||||
import appeng.client.ClientHelper;
|
||||
import appeng.client.render.model.GlassModelLoader;
|
||||
import appeng.client.render.model.SkyCompassModelLoader;
|
||||
import appeng.server.ServerHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EntityType;
|
||||
@@ -122,8 +123,7 @@ public final class AppEng
|
||||
final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
definitions.getRegistry().getBootstrapComponents( IClientSetupComponent.class ).forEachRemaining(IClientSetupComponent::setup);
|
||||
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "glass"), GlassModelLoader.INSTANCE);
|
||||
|
||||
|
||||
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "sky_compass"), SkyCompassModelLoader.INSTANCE);
|
||||
}
|
||||
|
||||
// @Nonnull
|
||||
|
||||
@@ -27,6 +27,8 @@ import appeng.client.render.effects.ChargedOreFX;
|
||||
import appeng.client.render.effects.LightningFX;
|
||||
import appeng.client.render.effects.VibrantFX;
|
||||
import appeng.client.render.model.GlassModelLoader;
|
||||
import appeng.client.render.model.SkyCompassBakedModel;
|
||||
import appeng.client.render.model.SkyCompassModel;
|
||||
import appeng.client.render.tesr.SkyChestTESR;
|
||||
import appeng.container.implementations.ContainerGrinder;
|
||||
import appeng.container.implementations.ContainerSkyChest;
|
||||
@@ -51,6 +53,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.extensions.IForgeContainerType;
|
||||
@@ -201,6 +204,10 @@ final class Registration
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
public void modelRegistryEvent( ModelRegistryEvent event )
|
||||
{
|
||||
// Sky compass parts
|
||||
for (ResourceLocation dependency : SkyCompassModel.DEPENDENCIES) {
|
||||
ModelLoader.addSpecialModel(dependency);
|
||||
}
|
||||
|
||||
final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
final IModelRegistry registry = new IModelRegistry() {
|
||||
|
||||
@@ -25,6 +25,8 @@ import appeng.api.definitions.ITileDefinition;
|
||||
import appeng.block.grindstone.BlockCrank;
|
||||
import appeng.block.grindstone.BlockGrinder;
|
||||
import appeng.block.misc.BlockQuartzFixture;
|
||||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.block.misc.SkyCompassRendering;
|
||||
import appeng.block.spatial.BlockMatrixFrame;
|
||||
import appeng.block.storage.BlockSkyChest;
|
||||
import appeng.bootstrap.*;
|
||||
@@ -37,6 +39,7 @@ import appeng.decorative.AEDecorativeBlock;
|
||||
import appeng.decorative.solid.*;
|
||||
import appeng.tile.grindstone.TileCrank;
|
||||
import appeng.tile.grindstone.TileGrinder;
|
||||
import appeng.tile.misc.TileSkyCompass;
|
||||
import appeng.tile.storage.TileSkyChest;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
@@ -229,11 +232,12 @@ public final class ApiBlocks implements IBlocks
|
||||
.tileEntity( skyChestTile )
|
||||
.build();
|
||||
|
||||
// this.skyCompass = registry.block( "sky_compass", BlockSkyCompass::new )
|
||||
// .features( AEFeature.METEORITE_COMPASS )
|
||||
// .tileEntity( new TileEntityDefinition( TileSkyCompass.class ) )
|
||||
// .rendering( new SkyCompassRendering() )
|
||||
// .build();
|
||||
this.skyCompass = registry.block( "sky_compass", () -> new BlockSkyCompass(Block.Properties.create(Material.MISCELLANEOUS)) )
|
||||
.features( AEFeature.METEORITE_COMPASS )
|
||||
.tileEntity( registry.tileEntity("sky_compass", TileSkyCompass.class, TileSkyCompass::new)
|
||||
.rendering( new SkyCompassRendering() )
|
||||
.build() )
|
||||
.build();
|
||||
this.grindstone = registry.block( "grindstone", () -> new BlockGrinder(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.2f)) )
|
||||
.features( AEFeature.GRIND_STONE )
|
||||
.tileEntity( registry.tileEntity("grindstone", TileGrinder.class, TileGrinder::new ).build() )
|
||||
@@ -252,17 +256,17 @@ public final class ApiBlocks implements IBlocks
|
||||
.build();
|
||||
// this.inscriber = registry.block( "inscriber", BlockInscriber::new )
|
||||
// .features( AEFeature.INSCRIBER )
|
||||
// .tileEntity( new TileEntityDefinition( TileInscriber.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileInscriber.class, TileInscriber::new).build() )
|
||||
// .rendering( new InscriberRendering() )
|
||||
// .build();
|
||||
// this.wirelessAccessPoint = registry.block( "wireless_access_point", BlockWireless::new )
|
||||
// .features( AEFeature.WIRELESS_ACCESS_TERMINAL )
|
||||
// .tileEntity( new TileEntityDefinition( TileWireless.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileWireless.class, TileWireless::new).build() )
|
||||
// .rendering( new WirelessRendering() )
|
||||
// .build();
|
||||
// this.charger = registry.block( "charger", BlockCharger::new )
|
||||
// .features( AEFeature.CHARGER )
|
||||
// .tileEntity( new TileEntityDefinition( TileCharger.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCharger.class, TileCharger::new).build() )
|
||||
// .rendering( new BlockRenderingCustomizer()
|
||||
// {
|
||||
// @Override
|
||||
@@ -290,7 +294,7 @@ public final class ApiBlocks implements IBlocks
|
||||
// .build();
|
||||
// this.securityStation = registry.block( "security_station", BlockSecurityStation::new )
|
||||
// .features( AEFeature.SECURITY )
|
||||
// .tileEntity( new TileEntityDefinition( TileSecurityStation.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileSecurityStation.class, TileSecurityStation::new).build() )
|
||||
// .rendering( new SecurityStationRendering() )
|
||||
// .build();
|
||||
// this.quantumRing = registry.block( "quantum_ring", BlockQuantumRing::new )
|
||||
@@ -305,79 +309,79 @@ public final class ApiBlocks implements IBlocks
|
||||
// .build();
|
||||
// this.spatialPylon = registry.block( "spatial_pylon", BlockSpatialPylon::new )
|
||||
// .features( AEFeature.SPATIAL_IO )
|
||||
// .tileEntity( new TileEntityDefinition( TileSpatialPylon.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileSpatialPylon.class, TileSpatialPylon::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .rendering( new SpatialPylonRendering() )
|
||||
// .build();
|
||||
// this.spatialIOPort = registry.block( "spatial_io_port", BlockSpatialIOPort::new )
|
||||
// .features( AEFeature.SPATIAL_IO )
|
||||
// .tileEntity( new TileEntityDefinition( TileSpatialIOPort.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileSpatialIOPort.class, TileSpatialIOPort::new).build() )
|
||||
// .build();
|
||||
// this.controller = registry.block( "controller", BlockController::new )
|
||||
// .features( AEFeature.CHANNELS )
|
||||
// .tileEntity( new TileEntityDefinition( TileController.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileController.class, TileController::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .rendering( new ControllerRendering() )
|
||||
// .build();
|
||||
// this.drive = registry.block( "drive", BlockDrive::new )
|
||||
// .features( AEFeature.STORAGE_CELLS, AEFeature.ME_DRIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileDrive.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileDrive.class, TileDrive::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .rendering( new DriveRendering() )
|
||||
// .build();
|
||||
// this.chest = registry.block( "chest", BlockChest::new )
|
||||
// .features( AEFeature.STORAGE_CELLS, AEFeature.ME_CHEST )
|
||||
// .tileEntity( new TileEntityDefinition( TileChest.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileChest.class, TileChest::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .rendering( new ChestRendering() )
|
||||
// .build();
|
||||
// this.iface = registry.block( "interface", BlockInterface::new )
|
||||
// .features( AEFeature.INTERFACE )
|
||||
// .tileEntity( new TileEntityDefinition( TileInterface.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileInterface.class, TileInterface::new).build() )
|
||||
// .build();
|
||||
// this.fluidIface = registry.block( "fluid_interface", BlockFluidInterface::new )
|
||||
// .features( AEFeature.FLUID_INTERFACE )
|
||||
// .tileEntity( new TileEntityDefinition( TileFluidInterface.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileFluidInterface.class, TileFluidInterface::new).build() )
|
||||
// .build();
|
||||
// this.cellWorkbench = registry.block( "cell_workbench", BlockCellWorkbench::new )
|
||||
// .features( AEFeature.STORAGE_CELLS )
|
||||
// .tileEntity( new TileEntityDefinition( TileCellWorkbench.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCellWorkbench.class, TileCellWorkbench::new).build() )
|
||||
// .build();
|
||||
// this.iOPort = registry.block( "io_port", BlockIOPort::new )
|
||||
// .features( AEFeature.STORAGE_CELLS, AEFeature.IO_PORT )
|
||||
// .tileEntity( new TileEntityDefinition( TileIOPort.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileIOPort.class, TileIOPort::new).build() )
|
||||
// .build();
|
||||
// this.condenser = registry.block( "condenser", BlockCondenser::new )
|
||||
// .features( AEFeature.CONDENSER )
|
||||
// .tileEntity( new TileEntityDefinition( TileCondenser.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCondenser.class, TileCondenser::new).build() )
|
||||
// .build();
|
||||
// this.energyAcceptor = registry.block( "energy_acceptor", BlockEnergyAcceptor::new )
|
||||
// .features( AEFeature.ENERGY_ACCEPTOR )
|
||||
// .tileEntity( new TileEntityDefinition( TileEnergyAcceptor.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileEnergyAcceptor.class, TileEnergyAcceptor::new).build() )
|
||||
// .build();
|
||||
// this.vibrationChamber = registry.block( "vibration_chamber", BlockVibrationChamber::new )
|
||||
// .features( AEFeature.POWER_GEN )
|
||||
// .tileEntity( new TileEntityDefinition( TileVibrationChamber.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileVibrationChamber.class, TileVibrationChamber::new).build() )
|
||||
// .build();
|
||||
// this.quartzGrowthAccelerator = registry.block( "quartz_growth_accelerator", BlockQuartzGrowthAccelerator::new )
|
||||
// .tileEntity( new TileEntityDefinition( TileQuartzGrowthAccelerator.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileQuartzGrowthAccelerator.class, TileQuartzGrowthAccelerator::new).build() )
|
||||
// .features( AEFeature.CRYSTAL_GROWTH_ACCELERATOR )
|
||||
// .build();
|
||||
// this.energyCell = registry.block( "energy_cell", BlockEnergyCell::new )
|
||||
// .features( AEFeature.ENERGY_CELLS )
|
||||
// .item( AEBaseBlockItemChargeable::new )
|
||||
// .tileEntity( new TileEntityDefinition( TileEnergyCell.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileEnergyCell.class, TileEnergyCell::new).build() )
|
||||
// .rendering( new BlockEnergyCellRendering( new ResourceLocation( AppEng.MOD_ID, "energy_cell" ) ) )
|
||||
// .build();
|
||||
// this.energyCellDense = registry.block( "dense_energy_cell", BlockDenseEnergyCell::new )
|
||||
// .features( AEFeature.ENERGY_CELLS, AEFeature.DENSE_ENERGY_CELLS )
|
||||
// .item( AEBaseBlockItemChargeable::new )
|
||||
// .tileEntity( new TileEntityDefinition( TileDenseEnergyCell.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileDenseEnergyCell.class, TileDenseEnergyCell::new).build() )
|
||||
// .rendering( new BlockEnergyCellRendering( new ResourceLocation( AppEng.MOD_ID, "dense_energy_cell" ) ) )
|
||||
// .build();
|
||||
// this.energyCellCreative = registry.block( "creative_energy_cell", BlockCreativeEnergyCell::new )
|
||||
// .features( AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileCreativeEnergyCell.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCreativeEnergyCell.class, TileCreativeEnergyCell::new).build() )
|
||||
// .build();
|
||||
//
|
||||
// FeatureFactory crafting = registry.features( AEFeature.CRAFTING_CPU );
|
||||
@@ -416,23 +420,23 @@ public final class ApiBlocks implements IBlocks
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.craftingMonitor = crafting.block( "crafting_monitor", BlockCraftingMonitor::new )
|
||||
// .tileEntity( new TileEntityDefinition( TileCraftingMonitorTile.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCraftingMonitorTile.class, TileCraftingMonitorTile::new).build() )
|
||||
// .rendering( new CraftingCubeRendering( "crafting_monitor", CraftingUnitType.MONITOR ) )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
//
|
||||
// this.molecularAssembler = registry.block( "molecular_assembler", BlockMolecularAssembler::new )
|
||||
// .features( AEFeature.MOLECULAR_ASSEMBLER )
|
||||
// .tileEntity( new TileEntityDefinition( TileMolecularAssembler.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileMolecularAssembler.class, TileMolecularAssembler::new).build() )
|
||||
// .build();
|
||||
// this.lightDetector = registry.block( "light_detector", BlockLightDetector::new )
|
||||
// .features( AEFeature.LIGHT_DETECTOR )
|
||||
// .tileEntity( new TileEntityDefinition( TileLightDetector.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileLightDetector.class, TileLightDetector::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.paint = registry.block( "paint", BlockPaint::new )
|
||||
// .features( AEFeature.PAINT_BALLS )
|
||||
// .tileEntity( new TileEntityDefinition( TilePaint.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TilePaint.class, TilePaint::new).build() )
|
||||
// .rendering( new PaintRendering() )
|
||||
// .build();
|
||||
//
|
||||
@@ -498,27 +502,27 @@ public final class ApiBlocks implements IBlocks
|
||||
|
||||
// this.itemGen = registry.block( "debug_item_gen", BlockItemGen::new )
|
||||
// .features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileItemGen.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileItemGen.class, TileItemGen::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.chunkLoader = registry.block( "debug_chunk_loader", BlockChunkloader::new )
|
||||
// .features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileChunkLoader.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileChunkLoader.class, TileChunkLoader::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.phantomNode = registry.block( "debug_phantom_node", BlockPhantomNode::new )
|
||||
// .features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TilePhantomNode.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TilePhantomNode.class, TilePhantomNode::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.cubeGenerator = registry.block( "debug_cube_gen", BlockCubeGenerator::new )
|
||||
// .features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileCubeGenerator.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileCubeGenerator.class, TileCubeGenerator::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
// this.energyGenerator = registry.block( "debug_energy_gen", BlockEnergyGenerator::new )
|
||||
// .features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
// .tileEntity( new TileEntityDefinition( TileEnergyGenerator.class ) )
|
||||
// .tileEntity( registry.tileEntity("", TileEnergyGenerator.class, TileEnergyGenerator::new).build() )
|
||||
// .useCustomItemModel()
|
||||
// .build();
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ import appeng.core.AELog;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
@@ -65,7 +65,6 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile,
|
||||
private String customName;
|
||||
private Direction forward = null;
|
||||
private Direction up = null;
|
||||
private BlockState state;
|
||||
private boolean markDirtyQueued = false;
|
||||
|
||||
public AEBaseTile(TileEntityType<?> tileEntityTypeIn) {
|
||||
@@ -338,8 +337,9 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile,
|
||||
Platform.notifyBlocksOfNeighbors( this.world, this.pos );
|
||||
}
|
||||
|
||||
public void onPlacement( final ItemStack stack, final PlayerEntity player, final Direction side )
|
||||
public void onPlacement(BlockItemUseContext context)
|
||||
{
|
||||
ItemStack stack = context.getItem();
|
||||
if( stack.hasTag() )
|
||||
{
|
||||
this.uploadSettings( SettingsFrom.DISMANTLE_ITEM, stack.getTag() );
|
||||
|
||||
@@ -20,15 +20,14 @@ package appeng.tile.misc;
|
||||
|
||||
|
||||
import appeng.tile.AEBaseTile;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
|
||||
|
||||
public class TileSkyCompass extends AEBaseTile
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer()
|
||||
{
|
||||
return true;
|
||||
public TileSkyCompass(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user