From 576923a2f2d8d2f55f040f539996723fcb633b72 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Fri, 26 Aug 2016 13:07:37 +0200 Subject: [PATCH] Implemented the sky compass. --- .../appeng/block/misc/BlockSkyCompass.java | 38 ++- .../block/misc/SkyCompassRendering.java | 27 +++ .../render/model/MatrixVertexTransformer.java | 166 +++++++++++++ .../render/model/SkyCompassBakedModel.java | 223 ++++++++++++++++++ .../client/render/model/SkyCompassModel.java | 87 +++++++ .../client/render/tesr/SkyCompassTESR.java | 110 +++++++++ .../core/api/definitions/ApiBlocks.java | 6 +- .../java/appeng/tile/misc/TileSkyCompass.java | 7 + .../blockstates/sky_compass.json | 5 + .../models/block/sky_compass_base.json | 119 ++++++++++ .../models/block/sky_compass_pointer.json | 21 ++ .../textures/blocks/sky_compass.png | Bin 0 -> 279 bytes .../textures/models/compass.png | Bin 294 -> 0 bytes 13 files changed, 803 insertions(+), 6 deletions(-) create mode 100644 src/main/java/appeng/block/misc/SkyCompassRendering.java create mode 100644 src/main/java/appeng/client/render/model/MatrixVertexTransformer.java create mode 100644 src/main/java/appeng/client/render/model/SkyCompassBakedModel.java create mode 100644 src/main/java/appeng/client/render/model/SkyCompassModel.java create mode 100644 src/main/java/appeng/client/render/tesr/SkyCompassTESR.java create mode 100644 src/main/resources/assets/appliedenergistics2/blockstates/sky_compass.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/sky_compass_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/sky_compass_pointer.json create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/sky_compass.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/models/compass.png diff --git a/src/main/java/appeng/block/misc/BlockSkyCompass.java b/src/main/java/appeng/block/misc/BlockSkyCompass.java index f3d84b610..403de1fdf 100644 --- a/src/main/java/appeng/block/misc/BlockSkyCompass.java +++ b/src/main/java/appeng/block/misc/BlockSkyCompass.java @@ -24,12 +24,17 @@ import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; +import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; 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; @@ -38,12 +43,22 @@ import appeng.tile.misc.TileSkyCompass; public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision { + // Rotation is expressed as radians + public static final PropertyFloat ROTATION = new PropertyFloat( "rotation" ); + public BlockSkyCompass() { - super( Material.IRON ); + super( Material.CIRCUITS ); this.setTileEntity( TileSkyCompass.class ); - this.setOpaque( this.setFullSize( false ) ); - this.lightOpacity = 0; + this.setLightOpacity( 0 ); + this.setFullSize( false ); + this.setOpaque( false ); + } + + @Override + protected BlockStateContainer createBlockState() + { + return new ExtendedBlockState( this, getAEStates(), new IUnlistedProperty[] { ROTATION } ); } @Override @@ -66,7 +81,7 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision public void neighborChanged( final IBlockState state, final World w, final BlockPos pos, final Block neighborBlock ) { final TileSkyCompass sc = this.getTileEntity( w, pos ); - final EnumFacing up = sc.getForward(); + final EnumFacing up = sc.getUp(); if( !this.canPlaceAt( w, pos, up.getOpposite() ) ) { this.dropTorch( w, pos ); @@ -99,7 +114,7 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision final TileSkyCompass tile = this.getTileEntity( w, pos ); if( tile != null ) { - final EnumFacing forward = tile.getForward(); + final EnumFacing forward = tile.getUp(); double minX = 0; double minY = 0; @@ -160,4 +175,17 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision { } + + @Override + public EnumBlockRenderType getRenderType( IBlockState state ) + { + return EnumBlockRenderType.ENTITYBLOCK_ANIMATED; + } + + @Override + public boolean isFullBlock( IBlockState state ) + { + return false; + } + } diff --git a/src/main/java/appeng/block/misc/SkyCompassRendering.java b/src/main/java/appeng/block/misc/SkyCompassRendering.java new file mode 100644 index 000000000..55c0a8215 --- /dev/null +++ b/src/main/java/appeng/block/misc/SkyCompassRendering.java @@ -0,0 +1,27 @@ +package appeng.block.misc; + + +import net.minecraft.client.renderer.block.model.ModelResourceLocation; + +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 +{ + + private static final ModelResourceLocation ITEM_MODEL = new ModelResourceLocation( "appliedenergistics2:sky_compass", "normal" ); + + @Override + public void customize( IBlockRendering rendering, IItemRendering itemRendering ) + { + rendering.tesr( new SkyCompassTESR() ); + // This disables the default smart-rotating model + rendering.modelCustomizer( ( loc, model ) -> model ); + itemRendering.model( ITEM_MODEL ); + itemRendering.builtInModel( "models/block/builtin/sky_compass", new SkyCompassModel() ); + } +} diff --git a/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java new file mode 100644 index 000000000..a4ccff204 --- /dev/null +++ b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java @@ -0,0 +1,166 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import javax.vecmath.Matrix4f; +import javax.vecmath.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.EnumFacing; +import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer; + + +/** + * Applies an arbitrary transformation matrix to the vertices of a quad. + */ +final class MatrixVertexTransformer extends QuadGatheringTransformer +{ + + private final Matrix4f transform; + + public MatrixVertexTransformer( Matrix4f transform ) + { + this.transform = transform; + } + + @Override + protected void processQuad() + { + VertexFormat format = parent.getVertexFormat(); + int count = format.getElementCount(); + + 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 ) + { + parent.put( e, transform( quadData[e][v] ) ); + } + else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL ) + { + parent.put( e, transformNormal( quadData[e][v] ) ); + } + else + { + parent.put( e, quadData[e][v] ); + } + } + } + } + + @Override + public void setQuadTint( int tint ) + { + parent.setQuadTint( tint ); + } + + @Override + public void setQuadOrientation( EnumFacing orientation ) + { + parent.setQuadOrientation( orientation ); + } + + @Override + public void setApplyDiffuseLighting( boolean diffuse ) + { + parent.setApplyDiffuseLighting( diffuse ); + } + + @Override + public void setTexture( TextureAtlasSprite texture ) + { + parent.setTexture( texture ); + } + + private float[] transform( float[] fs ) + { + 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; + transform.transform( vec ); + vec.x += 0.5f; + vec.y += 0.5f; + vec.z += 0.5f; + return new float[] { + vec.x, + vec.y, + vec.z + }; + case 4: + Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); + vecc.x -= 0.5f; + vecc.y -= 0.5f; + vecc.z -= 0.5f; + transform.transform( vecc ); + vecc.x += 0.5f; + vecc.y += 0.5f; + vecc.z += 0.5f; + return new float[] { + vecc.x, + vecc.y, + vecc.z, + vecc.w + }; + + default: + return fs; + } + } + + private float[] transformNormal( float[] fs ) + { + Vector4f normal; + + switch( fs.length ) + { + case 3: + normal = new Vector4f( fs[0], fs[1], fs[2], 0 ); + this.transform.transform( normal ); + normal.normalize(); + return new float[] { + normal.x, + normal.y, + normal.z + }; + + case 4: + normal = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); + this.transform.transform( normal ); + normal.normalize(); + return new float[] { + normal.x, + normal.y, + normal.z, + normal.w + }; + + default: + return fs; + } + } +} diff --git a/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java b/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java new file mode 100644 index 000000000..a9c67bb79 --- /dev/null +++ b/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java @@ -0,0 +1,223 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; +import javax.vecmath.AxisAngle4f; +import javax.vecmath.Matrix4f; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.entity.EntityPlayerSP; +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.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +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 appeng.block.misc.BlockSkyCompass; +import appeng.hooks.CompassManager; +import appeng.hooks.CompassResult; + + +/** + * 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 +{ + + private final IBakedModel base; + + private final IBakedModel pointer; + + private float fallbackRotation = 0; + + public SkyCompassBakedModel( IBakedModel base, IBakedModel pointer ) + { + this.base = base; + this.pointer = pointer; + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + 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; + } + } + else if( state == null ) + { + // This is used to render a compass pointing in a specific direction when being held in hand + rotation = fallbackRotation; + } + + // Pre-compute the quad count to avoid list resizes + List quads = new ArrayList<>(); + + quads.addAll( base.getQuads( state, side, rand ) ); + + // We'll add the pointer as "sideless" + if( side == null ) + { + // 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 ) ); + + MatrixVertexTransformer transformer = new MatrixVertexTransformer( matrix ); + for( BakedQuad bakedQuad : pointer.getQuads( state, side, rand ) ) + { + UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( bakedQuad.getFormat() ); + + transformer.setParent( builder ); + transformer.setVertexFormat( builder.getVertexFormat() ); + bakedQuad.pipe( transformer ); + builder.setQuadOrientation( null ); // After rotation, facing a specific side cannot be guaranteed anymore + BakedQuad q = builder.build(); + quads.add( q ); + } + } + + return quads; + } + + @Override + public boolean isAmbientOcclusion() + { + return base.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() + { + return true; + } + + @Override + public boolean isBuiltInRenderer() + { + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return base.getParticleTexture(); + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return base.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() + { + /* + This handles setting the rotation of the compass when being held in hand. If it's not held in hand, it'll animate using the + spinning animation. + */ + return new ItemOverrideList( Collections.emptyList() ) + { + + @Override + public IBakedModel handleItemState( IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity ) + { + if( world != null && entity instanceof EntityPlayerSP ) + { + EntityPlayer player = (EntityPlayer) entity; + + float offRads = (float) ( player.rotationYaw / 180.0f * (float) Math.PI + Math.PI ); + + fallbackRotation = offRads + getAnimatedRotation( player.getPosition(), true ); + } + else + { + fallbackRotation = getAnimatedRotation( null, false ); + } + + return originalModel; + } + }; + } + + /** + * Gets the effective, animated rotation for the compass given the current position of the compass. + */ + public static float getAnimatedRotation( @Nullable BlockPos pos, boolean prefetch ) + { + + // 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(); + } + } + } + + long timeMillis = System.currentTimeMillis(); + // 3 seconds per full rotation + timeMillis %= 3000; + return timeMillis / 3000.f * (float) Math.PI * 2; + } +} diff --git a/src/main/java/appeng/client/render/model/SkyCompassModel.java b/src/main/java/appeng/client/render/model/SkyCompassModel.java new file mode 100644 index 000000000..f19939272 --- /dev/null +++ b/src/main/java/appeng/client/render/model/SkyCompassModel.java @@ -0,0 +1,87 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.model; + + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.google.common.base.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 +{ + + 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 DEPENDENCIES = ImmutableList.of( MODEL_BASE, MODEL_POINTER ); + + @Override + public Collection getDependencies() + { + return DEPENDENCIES; + } + + @Override + public Collection getTextures() + { + return Collections.emptyList(); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function 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(); + } +} diff --git a/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java b/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java new file mode 100644 index 000000000..00daa2804 --- /dev/null +++ b/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java @@ -0,0 +1,110 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.client.render.tesr; + + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.VertexBuffer; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.client.model.animation.FastTESR; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.common.property.Properties; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import appeng.block.misc.BlockSkyCompass; +import appeng.client.render.model.SkyCompassBakedModel; +import appeng.tile.misc.TileSkyCompass; + + +@SideOnly( Side.CLIENT ) +public class SkyCompassTESR extends FastTESR +{ + + private static BlockRendererDispatcher blockRenderer; + + @Override + public void renderTileEntityFast( TileSkyCompass te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer buffer ) + { + + if( !te.hasWorldObj() ) + { + return; + } + + if( blockRenderer == null ) + { + blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); + } + + BlockPos pos = te.getPos(); + IBlockAccess world = MinecraftForgeClient.getRegionRenderCache( te.getWorld(), pos ); + IBlockState state = world.getBlockState( pos ); + if( state.getPropertyNames().contains( Properties.StaticProperty ) ) + { + state = state.withProperty( Properties.StaticProperty, false ); + } + + if( state instanceof IExtendedBlockState ) + { + IExtendedBlockState exState = (IExtendedBlockState) state; + + IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState( exState.getClean() ); + exState = exState.withProperty( BlockSkyCompass.ROTATION, getRotation( te ) ); + + buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() ); + + blockRenderer.getBlockModelRenderer().renderModel( world, model, exState, pos, buffer, false ); + } + } + + private static float getRotation( TileSkyCompass skyCompass ) + { + float rotation; + + if( skyCompass.getUp() == EnumFacing.UP || skyCompass.getUp() == EnumFacing.DOWN ) + { + rotation = SkyCompassBakedModel.getAnimatedRotation( skyCompass.getPos(), false ); + } + else + { + rotation = SkyCompassBakedModel.getAnimatedRotation( null, false ); + } + + if( skyCompass.getUp() == EnumFacing.DOWN ) + { + rotation = flipidiy( rotation ); + } + + return rotation; + } + + private static float flipidiy( float rad ) + { + float x = (float) Math.cos( rad ); + float y = (float) Math.sin( rad ); + return (float) Math.atan2( -y, x ); + } +} diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java index 403d9e2dc..896ff258b 100644 --- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java +++ b/src/main/java/appeng/core/api/definitions/ApiBlocks.java @@ -52,6 +52,7 @@ import appeng.block.misc.BlockSecurityStation; import appeng.block.misc.BlockSkyCompass; import appeng.block.misc.BlockTinyTNT; import appeng.block.misc.BlockVibrationChamber; +import appeng.block.misc.SkyCompassRendering; import appeng.block.networking.BlockCableBus; import appeng.block.networking.BlockController; import appeng.block.networking.BlockCreativeEnergyCell; @@ -236,7 +237,10 @@ public final class ApiBlocks implements IBlocks .rendering( new SkyChestRenderingCustomizer( SkyChestType.BLOCK ) ) .build(); - this.skyCompass = registry.block( "sky_compass", BlockSkyCompass::new ).features( AEFeature.MeteoriteCompass ).build(); + this.skyCompass = registry.block( "sky_compass", BlockSkyCompass::new ) + .features( AEFeature.MeteoriteCompass ) + .rendering( new SkyCompassRendering() ) + .build(); this.grindstone = registry.block( "grindstone", BlockGrinder::new ).features( AEFeature.GrindStone ).build(); this.crank = registry.block( "crank", BlockCrank::new ) .features( AEFeature.GrindStone ) diff --git a/src/main/java/appeng/tile/misc/TileSkyCompass.java b/src/main/java/appeng/tile/misc/TileSkyCompass.java index 7937029b1..20e31b97d 100644 --- a/src/main/java/appeng/tile/misc/TileSkyCompass.java +++ b/src/main/java/appeng/tile/misc/TileSkyCompass.java @@ -30,4 +30,11 @@ public class TileSkyCompass extends AEBaseTile { return true; } + + @Override + public boolean hasFastRenderer() + { + return true; + } + } diff --git a/src/main/resources/assets/appliedenergistics2/blockstates/sky_compass.json b/src/main/resources/assets/appliedenergistics2/blockstates/sky_compass.json new file mode 100644 index 000000000..1be87a8e2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/blockstates/sky_compass.json @@ -0,0 +1,5 @@ +{ + "variants": { + "normal": { "model": "appliedenergistics2:builtin/sky_compass" } + } +} diff --git a/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_base.json b/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_base.json new file mode 100644 index 000000000..e31b39988 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_base.json @@ -0,0 +1,119 @@ +{ + "parent": "block/block", + "textures": { + "particle": "appliedenergistics2:blocks/sky_compass", + "0": "appliedenergistics2:blocks/sky_compass" + }, + "display": { + "gui": { + "rotation": [ 30, 225, 0 ], + "translation": [ 0, 8, 0], + "scale":[ 1.5, 1.5, 1.5 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "fixed": { + "rotation": [ 270, 0, 0 ], + "translation": [ 0, 0, -10.1 ], + "scale":[ 1.5, 1.5, 1.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 10, 0, 0 ], + "translation": [ 0, 8, -12 ], + "scale": [ 2, 2, 2 ] + }, + "firstperson_lefthand": { + "rotation": [ 10, 0, 0 ], + "translation": [ 0, 8, -12 ], + "scale": [ 2, 2, 2 ] + } + }, + "elements": [ + { + "name": "Base", + "from": [ 6.0, 0.0, 6.0 ], + "to": [ 10.0, 1.0, 10.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 0.0, 4.0, 4.0, 5.0 ] }, + "east": { "texture": "#0", "uv": [ 4.0, 4.0, 8.0, 5.0 ] }, + "south": { "texture": "#0", "uv": [ 8.0, 4.0, 12.0, 5.0 ] }, + "west": { "texture": "#0", "uv": [ 12.0, 4.0, 16.0, 5.0 ] }, + "up": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 4.0 ] }, + "down": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 4.0 ] } + } + }, + { + "name": "Border", + "from": [ 6.0, 1.0, 5.0 ], + "to": [ 10.0, 2.0, 6.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 1.0, 0.0, 5.0, 1.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 1.0, 1.0, 2.0 ] }, + "south": { "texture": "#0", "uv": [ 5.0, 0.0, 9.0, 1.0 ] }, + "west": { "texture": "#0", "uv": [ 4.0, 0.0, 5.0, 1.0 ] }, + "up": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] }, + "down": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] } + } + }, + { + "name": "Border", + "from": [ 6.0, 1.0, 10.0 ], + "to": [ 10.0, 2.0, 11.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 1.0, 0.0, 5.0, 1.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 1.0, 1.0, 2.0 ] }, + "south": { "texture": "#0", "uv": [ 5.0, 0.0, 9.0, 1.0 ] }, + "west": { "texture": "#0", "uv": [ 4.0, 0.0, 5.0, 1.0 ] }, + "up": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] }, + "down": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] } + } + }, + { + "name": "Border", + "from": [ 10.0, 1.0, 6.0 ], + "to": [ 11.0, 2.0, 10.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 2.0, 0.0, 3.0, 1.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 1.0, 4.0, 2.0 ] }, + "south": { "texture": "#0", "uv": [ 5.0, 0.0, 6.0, 1.0 ] }, + "west": { "texture": "#0", "uv": [ 4.0, 0.0, 8.0, 1.0 ] }, + "up": { "texture": "#0", "uv": [ 11.0, 0.0, 12.0, 4.0 ] }, + "down": { "texture": "#0", "uv": [ 10.0, 0.0, 11.0, 4.0 ] } + } + }, + { + "name": "Border", + "from": [ 5.0, 1.0, 6.0 ], + "to": [ 6.0, 2.0, 10.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 2.0, 0.0, 3.0, 1.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 1.0, 4.0, 2.0 ] }, + "south": { "texture": "#0", "uv": [ 5.0, 0.0, 6.0, 1.0 ] }, + "west": { "texture": "#0", "uv": [ 4.0, 0.0, 8.0, 1.0 ] }, + "up": { "texture": "#0", "uv": [ 9.0, 0.0, 10.0, 4.0 ] }, + "down": { "texture": "#0", "uv": [ 10.0, 0.0, 11.0, 4.0 ] } + } + }, + { + "name": "Nibble", + "from": [ 7.5, 1.0, 7.5 ], + "to": [ 8.5, 2.0, 8.5 ], + "faces": { + "north": { "texture": "#0", "uv": [ 4.0, 2.0, 6.0, 4.0 ] }, + "east": { "texture": "#0", "uv": [ 6.0, 2.0, 8.0, 4.0 ] }, + "south": { "texture": "#0", "uv": [ 7.0, 2.0, 9.0, 4.0 ] }, + "west": { "texture": "#0", "uv": [ 8.0, 2.0, 10.0, 4.0 ] }, + "up": { "texture": "#0", "uv": [ 10.0, 2.0, 12.0, 4.0 ] }, + "down": { "texture": "#0", "uv": [ 7.0, 2.0, 9.0, 4.0 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_pointer.json b/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_pointer.json new file mode 100644 index 000000000..bf209806b --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/sky_compass_pointer.json @@ -0,0 +1,21 @@ +{ + "parent": "block/block", + "textures": { + "0": "appliedenergistics2:blocks/sky_compass" + }, + "elements": [ + { + "name": "Pointer", + "from": [ 7.7, 1.0, 6 ], + "to": [ 8.2, 1.5, 8 ], + "faces": { + "north": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 5.0, 16, 8 ] }, + "south": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] }, + "west": { "texture": "#0", "uv": [ 0.0, 5.0, 16, 8 ] }, + "up": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] }, + "down": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/sky_compass.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/sky_compass.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae9458c1d42b53d2db55b848b89325a7e1cdda9 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFzobnaSW-r^`_sKuUSFBEuEqFV}_oI+|}7%RP;i1 z48G28IW|e}mPzKW7v3B^_Wk)Y_>L8dq%D(B?&Js!byZ}E-Ja|Hde@|_Vds};CRru6 zB~GZhY3Z)1Dk_oug)xhP(N42)>Bjff2N&;JmwCVZ)4kXKHtEb-cI1Mv!i{Zjk=)}dsf8;pbL;Loe4J_8qUQDL hKe+203xpFG;vM6&71}Z#7#J8BJYD@<);T3K0RU}JYm5K@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/models/compass.png b/src/main/resources/assets/appliedenergistics2/textures/models/compass.png deleted file mode 100644 index 899ec7703bfc40a7fbf9e586cf53f6c4292e257e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBp|jV_;zTP*y*kfq{V~-O<;Pfnj4m_n$;o z1_lPs0*}aI1_r)EAj~ML;nl#vz#vuP8c`CQpH@FNsoPmL1k*AAeh(_?y{*6M16a-v87iTJP3J5(Amz9>5=9ZS0PXDv`>$H=qQpa!2 ztvt-Qz4}6cB1_L>j^{FMi4Hx5YrQqMUi+O@AqLn_cT>?bv=zX=zCBXPd*- z|7ACbFTXUUcpamO@HL*uTXo%xmrd5Ht&=*odui@uLpB%njh*MO?`7MP8=d`kU7Pt? w;U5na@3hV?5Y;;rX~F6KaKq#Cj0d>$zQ2`uAjfl(fq{X+)78&qol`;+0JVQ>IRF3v