package appeng.block.paint; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.google.common.collect.ImmutableList; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.ItemOverrideList; import net.minecraft.client.renderer.model.Material; import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.data.IDynamicBakedModel; import net.minecraftforge.client.model.data.IModelData; import appeng.client.render.cablebus.CubeBuilder; import appeng.core.AppEng; import appeng.helpers.Splotch; import appeng.tile.misc.PaintSplotchesTileEntity; /** * 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 PaintSplotchesBakedModel implements IDynamicBakedModel { private static final Material TEXTURE_PAINT1 = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation(AppEng.MOD_ID, "block/paint1")); private static final Material TEXTURE_PAINT2 = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation(AppEng.MOD_ID, "block/paint2")); private static final Material TEXTURE_PAINT3 = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation(AppEng.MOD_ID, "block/paint3")); private final TextureAtlasSprite[] textures; PaintSplotchesBakedModel(Function bakedTextureGetter) { this.textures = new TextureAtlasSprite[] { bakedTextureGetter.apply(TEXTURE_PAINT1), bakedTextureGetter.apply(TEXTURE_PAINT2), bakedTextureGetter.apply(TEXTURE_PAINT3) }; } @Nonnull @Override public List getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) { if (side != null) { return Collections.emptyList(); } PaintSplotches splotchesState = extraData.getData(PaintSplotchesTileEntity.SPLOTCHES); if (splotchesState == null) { // This is the inventory model which should usually not be used other than in // special cases List quads = new ArrayList<>(1); CubeBuilder builder = new CubeBuilder(quads); builder.setTexture(this.textures[0]); builder.addCube(0, 0, 0, 16, 16, 16); return quads; } List splotches = splotchesState.getSplotches(); CubeBuilder builder = new CubeBuilder(); 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 = this.textures[s.getSeed() % this.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(Direction.DOWN, pos_x - buffer, offset, pos_y - buffer, pos_x + buffer, offset, pos_y + buffer); break; case DOWN: builder.addQuad(Direction.UP, pos_x - buffer, offset, pos_y - buffer, pos_x + buffer, offset, pos_y + buffer); break; case EAST: offset = 1.0f - offset; builder.addQuad(Direction.WEST, offset, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer, pos_y + buffer); break; case WEST: builder.addQuad(Direction.EAST, offset, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer, pos_y + buffer); break; case SOUTH: offset = 1.0f - offset; builder.addQuad(Direction.NORTH, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer, pos_y + buffer, offset); break; case NORTH: builder.addQuad(Direction.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 this.textures[0]; } @Override public ItemOverrideList getOverrides() { return ItemOverrideList.EMPTY; } @Override public boolean func_230044_c_() { return false; } static List getRequiredTextures() { return ImmutableList.of(TEXTURE_PAINT1, TEXTURE_PAINT2, TEXTURE_PAINT3); } }