Fixes #2377: Paint blocks now render correctly.
This commit is contained in:
parent
070b35f3db
commit
c590e7f6e6
|
@ -16,15 +16,19 @@
|
|||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.block.misc;
|
||||
package appeng.block.paint;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.MaterialLiquid;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -34,16 +38,22 @@ import net.minecraft.util.math.AxisAlignedBB;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.helpers.Splotch;
|
||||
import appeng.tile.misc.TilePaint;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class BlockPaint extends AEBaseTileBlock
|
||||
{
|
||||
|
||||
static final PaintSplotchesProperty SPLOTCHES = new PaintSplotchesProperty();
|
||||
|
||||
public BlockPaint()
|
||||
{
|
||||
super( new MaterialLiquid( MapColor.AIR ) );
|
||||
|
@ -54,6 +64,28 @@ public class BlockPaint extends AEBaseTileBlock
|
|||
this.setOpaque( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState()
|
||||
{
|
||||
return new ExtendedBlockState( this, new IProperty[0], new IUnlistedProperty[] { SPLOTCHES } );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
IExtendedBlockState extState = (IExtendedBlockState) state;
|
||||
|
||||
TilePaint te = getTileEntity( world, pos );
|
||||
|
||||
Collection<Splotch> splotches = Collections.emptyList();
|
||||
if( te != null )
|
||||
{
|
||||
splotches = te.getDots();
|
||||
}
|
||||
|
||||
return extState.withProperty( SPLOTCHES, new PaintSplotches( splotches ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getBlockLayer()
|
||||
{
|
|
@ -0,0 +1,196 @@
|
|||
package appeng.block.paint;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
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.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import appeng.client.render.cablebus.CubeBuilder;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.helpers.Splotch;
|
||||
|
||||
|
||||
/**
|
||||
* Renders paint blocks, which render multiple "splotches" that have been applied to the sides of adjacent blocks using a
|
||||
* matter cannon with paint balls.
|
||||
*/
|
||||
class PaintBakedModel implements IBakedModel
|
||||
{
|
||||
|
||||
private static final ResourceLocation TEXTURE_PAINT1 = new ResourceLocation( AppEng.MOD_ID, "blocks/paint1" );
|
||||
private static final ResourceLocation TEXTURE_PAINT2 = new ResourceLocation( AppEng.MOD_ID, "blocks/paint2" );
|
||||
private static final ResourceLocation TEXTURE_PAINT3 = new ResourceLocation( AppEng.MOD_ID, "blocks/paint3" );
|
||||
|
||||
private final VertexFormat vertexFormat;
|
||||
|
||||
private final TextureAtlasSprite[] textures;
|
||||
|
||||
PaintBakedModel( VertexFormat vertexFormat, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
this.vertexFormat = vertexFormat;
|
||||
this.textures = new TextureAtlasSprite[] {
|
||||
bakedTextureGetter.apply( TEXTURE_PAINT1 ),
|
||||
bakedTextureGetter.apply( TEXTURE_PAINT2 ),
|
||||
bakedTextureGetter.apply( TEXTURE_PAINT3 )
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
|
||||
{
|
||||
if( side != null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if( !( state instanceof IExtendedBlockState ) )
|
||||
{
|
||||
// This is the inventory model which should usually not be used other than in special cases
|
||||
List<BakedQuad> quads = new ArrayList<>( 1 );
|
||||
CubeBuilder builder = new CubeBuilder( this.vertexFormat, quads );
|
||||
builder.setTexture( textures[0] );
|
||||
builder.addCube( 0, 0, 0, 16, 16, 16 );
|
||||
return quads;
|
||||
}
|
||||
|
||||
IExtendedBlockState extendedBlockState = (IExtendedBlockState) state;
|
||||
PaintSplotches splotchesState = extendedBlockState.getValue( BlockPaint.SPLOTCHES );
|
||||
|
||||
if( splotchesState == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Splotch> splotches = splotchesState.getSplotches();
|
||||
|
||||
CubeBuilder builder = new CubeBuilder( vertexFormat );
|
||||
|
||||
float offsetConstant = 0.001f;
|
||||
for( final Splotch s : splotches) {
|
||||
|
||||
if( s.isLumen() )
|
||||
{
|
||||
builder.setColorRGB( s.getColor().whiteVariant );
|
||||
builder.setRenderFullBright( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.setColorRGB( s.getColor().mediumVariant );
|
||||
builder.setRenderFullBright( false );
|
||||
}
|
||||
|
||||
float offset = offsetConstant;
|
||||
offsetConstant += 0.001f;
|
||||
|
||||
final float buffer = 0.1f;
|
||||
|
||||
float pos_x = s.x();
|
||||
float pos_y = s.y();
|
||||
|
||||
pos_x = Math.max( buffer, Math.min( 1.0f - buffer, pos_x ) );
|
||||
pos_y = Math.max( buffer, Math.min( 1.0f - buffer, pos_y ) );
|
||||
|
||||
TextureAtlasSprite ico = textures[s.getSeed() % textures.length];
|
||||
builder.setTexture( ico );
|
||||
builder.setCustomUv( s.getSide().getOpposite(), 0, 0, 16, 16 );
|
||||
|
||||
switch( s.getSide() )
|
||||
{
|
||||
case UP:
|
||||
offset = 1.0f - offset;
|
||||
builder.addQuad( EnumFacing.DOWN, pos_x - buffer, offset, pos_y - buffer,
|
||||
pos_x + buffer, offset, pos_y + buffer );
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
builder.addQuad( EnumFacing.UP, pos_x - buffer, offset, pos_y - buffer,
|
||||
pos_x + buffer, offset, pos_y + buffer );
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
offset = 1.0f - offset;
|
||||
builder.addQuad( EnumFacing.WEST, offset, pos_x - buffer, pos_y - buffer,
|
||||
offset, pos_x + buffer, pos_y + buffer );
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
builder.addQuad( EnumFacing.EAST, offset, pos_x - buffer, pos_y - buffer,
|
||||
offset, pos_x + buffer, pos_y + buffer );
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
offset = 1.0f - offset;
|
||||
builder.addQuad( EnumFacing.NORTH, pos_x - buffer, pos_y - buffer, offset,
|
||||
pos_x + buffer, pos_y + buffer, offset );
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
builder.addQuad( EnumFacing.SOUTH, pos_x - buffer, pos_y - buffer, offset,
|
||||
pos_x + buffer, pos_y + buffer, offset );
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return builder.getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return textures[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return ItemCameraTransforms.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
}
|
||||
|
||||
static List<ResourceLocation> getRequiredTextures()
|
||||
{
|
||||
return ImmutableList.of(
|
||||
TEXTURE_PAINT1, TEXTURE_PAINT2, TEXTURE_PAINT3
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package appeng.block.paint;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
class PaintModel implements IModel
|
||||
{
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getTextures()
|
||||
{
|
||||
return PaintBakedModel.getRequiredTextures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
return new PaintBakedModel( format, bakedTextureGetter );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package appeng.block.paint;
|
||||
|
||||
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
|
||||
|
||||
public class PaintRendering extends BlockRenderingCustomizer
|
||||
{
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
|
||||
{
|
||||
rendering.builtInModel( "models/block/paint", new PaintModel() );
|
||||
// Disable auto rotation
|
||||
rendering.modelCustomizer( ( location, model ) -> model );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package appeng.block.paint;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import appeng.helpers.Splotch;
|
||||
|
||||
|
||||
/**
|
||||
* Used to transfer the state about paint splotches from the game thread to the render thread.
|
||||
*/
|
||||
class PaintSplotches
|
||||
{
|
||||
|
||||
private final List<Splotch> splotches;
|
||||
|
||||
PaintSplotches( Collection<Splotch> splotches )
|
||||
{
|
||||
this.splotches = ImmutableList.copyOf( splotches );
|
||||
}
|
||||
|
||||
List<Splotch> getSplotches()
|
||||
{
|
||||
return splotches;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package appeng.block.paint;
|
||||
|
||||
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
|
||||
|
||||
class PaintSplotchesProperty implements IUnlistedProperty<PaintSplotches>
|
||||
{
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "paint_splots";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid( PaintSplotches value )
|
||||
{
|
||||
return value != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<PaintSplotches> getType()
|
||||
{
|
||||
return PaintSplotches.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToString( PaintSplotches value )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -103,6 +103,30 @@ public class CubeBuilder
|
|||
}
|
||||
}
|
||||
|
||||
public void addQuad( EnumFacing face, float x1, float y1, float z1, float x2, float y2, float z2 )
|
||||
{
|
||||
// If brightness is forced to specific values, extend the vertex format to contain the multi-texturing lightmap
|
||||
// offset
|
||||
VertexFormat savedFormat = null;
|
||||
if( renderFullBright )
|
||||
{
|
||||
savedFormat = format;
|
||||
format = new VertexFormat( savedFormat );
|
||||
if( !format.getElements().contains( DefaultVertexFormats.TEX_2S ) )
|
||||
{
|
||||
format.addElement( DefaultVertexFormats.TEX_2S );
|
||||
}
|
||||
}
|
||||
|
||||
putFace( face, x1, y1, z1, x2, y2, z2 );
|
||||
|
||||
// Restore old format
|
||||
if( savedFormat != null )
|
||||
{
|
||||
format = savedFormat;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UvVector
|
||||
{
|
||||
float u1;
|
||||
|
|
|
@ -46,7 +46,6 @@ import appeng.block.misc.BlockCondenser;
|
|||
import appeng.block.misc.BlockInscriber;
|
||||
import appeng.block.misc.BlockInterface;
|
||||
import appeng.block.misc.BlockLightDetector;
|
||||
import appeng.block.misc.BlockPaint;
|
||||
import appeng.block.misc.BlockQuartzFixture;
|
||||
import appeng.block.misc.BlockQuartzGrowthAccelerator;
|
||||
import appeng.block.misc.BlockSecurityStation;
|
||||
|
@ -67,6 +66,8 @@ import appeng.block.networking.BlockWireless;
|
|||
import appeng.block.networking.CableBusRendering;
|
||||
import appeng.block.networking.ControllerRendering;
|
||||
import appeng.block.networking.WirelessRendering;
|
||||
import appeng.block.paint.BlockPaint;
|
||||
import appeng.block.paint.PaintRendering;
|
||||
import appeng.block.qnb.BlockQuantumLinkChamber;
|
||||
import appeng.block.qnb.BlockQuantumRing;
|
||||
import appeng.block.qnb.QuantumBridgeRendering;
|
||||
|
@ -373,7 +374,10 @@ public final class ApiBlocks implements IBlocks
|
|||
this.lightDetector = registry.block( "light_detector", BlockLightDetector::new ).features( AEFeature.LightDetector )
|
||||
.useCustomItemModel()
|
||||
.build();
|
||||
this.paint = registry.block( "paint", BlockPaint::new ).features( AEFeature.PaintBalls ).build();
|
||||
this.paint = registry.block( "paint", BlockPaint::new )
|
||||
.features( AEFeature.PaintBalls )
|
||||
.rendering( new PaintRendering() )
|
||||
.build();
|
||||
|
||||
this.skyStoneStairs = makeStairs( "sky_stone_stairs", registry, this.skyStoneBlock() );
|
||||
this.smoothSkyStoneStairs = makeStairs( "smooth_sky_stone_stairs", registry, this.smoothSkyStoneBlock() );
|
||||
|
|
|
@ -62,7 +62,7 @@ import appeng.api.storage.data.IAEItemStack;
|
|||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.block.misc.BlockPaint;
|
||||
import appeng.block.paint.BlockPaint;
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.GuiText;
|
||||
|
|
|
@ -21,11 +21,10 @@ package appeng.tile.misc;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
|
@ -270,7 +269,7 @@ public class TilePaint extends AEBaseTile
|
|||
{
|
||||
if( this.dots == null )
|
||||
{
|
||||
return ImmutableList.of();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return this.dots;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": {
|
||||
"model": "appliedenergistics2:paint"
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 404 B |
Binary file not shown.
After Width: | Height: | Size: 386 B |
Binary file not shown.
After Width: | Height: | Size: 393 B |
Loading…
Reference in New Issue