public BCMTexture([NotNull] BlockTextureData texture) { Id = texture.ID; Name = texture.Name; Local = texture.LocalizedName; TextureId = texture.TextureID; }
private static void SetPaint(Vector3i p3, Vector3i size, Dictionary <long, Chunk> modifiedChunks) { var texture = 0; if (Options.ContainsKey("t")) { if (!int.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } } var num = 0L; for (var face = 0; face < 6; face++) { var num2 = face * 8; num &= ~(255L << num2); num |= (long)(texture & 255) << num2; } var textureFull = num; const int clrIdx = 0; var counter = 0; for (var j = 0; j < size.y; j++) { for (var i = 0; i < size.x; i++) { for (var k = 0; k < size.z; k++) { var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); var blockValue = GameManager.Instance.World.GetBlock(clrIdx, p5); if (blockValue.Block.shape.IsTerrain() || blockValue.Equals(BlockValue.Air)) { continue; } GameManager.Instance.World.ChunkClusters[clrIdx].SetTextureFull(p5, textureFull); counter++; } } } SendOutput($"Painting {counter} blocks with texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}' @ {p3} to {p3 + size}"); SendOutput("Use bc-wblock /undo to revert the changes"); Reload(modifiedChunks); }
protected BlockTextureData GetTextureUVMap(ResourceManager resources, ResourceLocation texture, float x1, float x2, float y1, float y2, int rot, Color color, TextureInfo textureInfo = null) { if (resources == null) { x1 = 0; x2 = 1 / 32f; y1 = 0; y2 = 1 / 32f; return(new BlockTextureData(new TextureInfo(new Vector2(), Vector2.Zero, 16, 16, false, true), new Microsoft.Xna.Framework.Vector2(x1, y1), new Microsoft.Xna.Framework.Vector2(x2, y1), new Microsoft.Xna.Framework.Vector2(x1, y2), new Microsoft.Xna.Framework.Vector2(x2, y2), color, color, color)); } if (textureInfo == null) { textureInfo = resources.Atlas.GetAtlasLocation(texture); } var tw = textureInfo.Width; var th = textureInfo.Height; x1 = (x1 * (tw)); x2 = (x2 * (tw)); y1 = (y1 * (th)); y2 = (y2 * (th)); var map = new BlockTextureData(textureInfo, new Microsoft.Xna.Framework.Vector2(x1, y1), new Microsoft.Xna.Framework.Vector2(x2, y1), new Microsoft.Xna.Framework.Vector2(x1, y2), new Microsoft.Xna.Framework.Vector2(x2, y2), color, color, color, textureInfo.Animated); return(map); }
private static void SetPaint(World world, Vector3i pos) { byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } } var blockValue = world.GetBlock(pos); if (blockValue.Equals(BlockValue.Air)) { SendOutput($"Target block is air @ {pos}"); return; } if (blockValue.Block.shape.IsTerrain()) { SendOutput($"Target block is terrain @ {pos}"); return; } GameManager.Instance.SetBlockTextureServer(pos, BlockFace.None, texture, -1); SendOutput($"Painting block with texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}' @ {pos}"); }
private static void SetPaintFace(Vector3i p3, Vector3i size, Dictionary <long, Chunk> modifiedChunks) { byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } } uint setFace = 0; if (Options.ContainsKey("face")) { if (!uint.TryParse(Options["face"], out setFace)) { SendOutput("Unable to parse face value"); return; } } if (setFace > 5) { SendOutput("Face must be between 0 and 5"); return; } const int clrIdx = 0; var counter = 0; for (var j = 0; j < size.y; j++) { for (var i = 0; i < size.x; i++) { for (var k = 0; k < size.z; k++) { var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); var blockValue = GameManager.Instance.World.GetBlock(clrIdx, p5); if (blockValue.Equals(BlockValue.Air)) { continue; } GameManager.Instance.World.ChunkClusters[clrIdx].SetBlockFaceTexture(p5, (BlockFace)setFace, texture); counter++; } } } SendOutput($"Painting {counter} blocks on face '{((BlockFace)setFace).ToString()}' with texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}' @ {p3} to {p3 + size}"); SendOutput("Use bc-wblock /undo to revert the changes"); Reload(modifiedChunks); }
protected BlockShaderVertex[] GetFaceVertices(BlockFace blockFace, Vector3 startPosition, Vector3 endPosition, BlockTextureData uvmap) { Color faceColor = Color.White; Vector3 normal = Vector3.Zero; Vector3 positionTopLeft = Vector3.Zero, positionBottomLeft = Vector3.Zero, positionBottomRight = Vector3.Zero, positionTopRight = Vector3.Zero; switch (blockFace) { case BlockFace.Up: //Positive Y positionTopLeft = new Vector3(startPosition.X, endPosition.Y, endPosition.Z); positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z); positionBottomLeft = new Vector3(startPosition.X, endPosition.Y, startPosition.Z); positionBottomRight = new Vector3(endPosition.X, endPosition.Y, startPosition.Z); normal = Vector3.Up; faceColor = uvmap.ColorTop; //new Color(0x00, 0x00, 0xFF); break; case BlockFace.Down: //Negative Y positionTopLeft = new Vector3(startPosition.X, startPosition.Y, endPosition.Z); positionTopRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z); positionBottomLeft = new Vector3(startPosition.X, startPosition.Y, startPosition.Z); positionBottomRight = new Vector3(endPosition.X, startPosition.Y, startPosition.Z); normal = Vector3.Down; faceColor = uvmap.ColorBottom; //new Color(0xFF, 0xFF, 0x00); break; case BlockFace.West: //Negative X positionTopLeft = new Vector3(startPosition.X, endPosition.Y, startPosition.Z); positionTopRight = new Vector3(startPosition.X, endPosition.Y, endPosition.Z); positionBottomLeft = new Vector3(startPosition.X, startPosition.Y, startPosition.Z); positionBottomRight = new Vector3(startPosition.X, startPosition.Y, endPosition.Z); normal = Vector3.Left; faceColor = uvmap.ColorLeft; // new Color(0xFF, 0x00, 0xFF); break; case BlockFace.East: //Positive X positionTopLeft = new Vector3(endPosition.X, endPosition.Y, startPosition.Z); positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z); positionBottomLeft = new Vector3(endPosition.X, startPosition.Y, startPosition.Z); positionBottomRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z); normal = Vector3.Right; faceColor = uvmap.ColorRight; //new Color(0x00, 0xFF, 0xFF); break; case BlockFace.South: //Positive Z positionTopLeft = new Vector3(startPosition.X, endPosition.Y, endPosition.Z); positionTopRight = new Vector3(endPosition.X, endPosition.Y, endPosition.Z); positionBottomLeft = new Vector3(startPosition.X, startPosition.Y, endPosition.Z); positionBottomRight = new Vector3(endPosition.X, startPosition.Y, endPosition.Z); normal = Vector3.Backward; faceColor = uvmap.ColorFront; // ew Color(0x00, 0xFF, 0x00); break; case BlockFace.North: //Negative Z positionTopLeft = new Vector3(startPosition.X, endPosition.Y, startPosition.Z); positionTopRight = new Vector3(endPosition.X, endPosition.Y, startPosition.Z); positionBottomLeft = new Vector3(startPosition.X, startPosition.Y, startPosition.Z); positionBottomRight = new Vector3(endPosition.X, startPosition.Y, startPosition.Z); normal = Vector3.Forward; faceColor = uvmap.ColorBack; // new Color(0xFF, 0x00, 0x00); break; case BlockFace.None: break; } var topLeft = new BlockShaderVertex(positionTopLeft, normal, uvmap.TopLeft, faceColor); var topRight = new BlockShaderVertex(positionTopRight, normal, uvmap.TopRight, faceColor); var bottomLeft = new BlockShaderVertex(positionBottomLeft, normal, uvmap.BottomLeft, faceColor); var bottomRight = new BlockShaderVertex(positionBottomRight, normal, uvmap.BottomRight, faceColor); switch (blockFace) { case BlockFace.Up: return(new BlockShaderVertex[] { bottomLeft, topLeft, topRight, bottomRight, bottomLeft, topRight }); case BlockFace.Down: return(new BlockShaderVertex[] { topLeft, bottomLeft, topRight, bottomLeft, bottomRight, topRight }); case BlockFace.South: return(new BlockShaderVertex[] { topLeft, bottomLeft, topRight, bottomLeft, bottomRight, topRight }); case BlockFace.East: return(new BlockShaderVertex[] { bottomLeft, topLeft, topRight, bottomRight, bottomLeft, topRight }); case BlockFace.North: return(new BlockShaderVertex[] { bottomLeft, topLeft, topRight, bottomRight, bottomLeft, topRight }); case BlockFace.West: return(new BlockShaderVertex[] { topLeft, bottomLeft, topRight, bottomLeft, bottomRight, topRight }); break; default: return(new BlockShaderVertex[0]); } }
private static void SetPaint(Vector3i p3, Vector3i size) { var texture = 0; if (Options.ContainsKey("t")) { if (!int.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput(string.Format("Unknown texture index {0}", texture)); return; } } var num = 0L; for (var face = 0; face < 6; face++) { var num2 = face * 8; num &= ~(255L << num2); num |= (long)(texture & 255) << num2; } var textureFull = num; const int clrIdx = 0; var counter = 0; for (var j = 0; j < size.y; j++) { for (var i = 0; i < size.x; i++) { for (var k = 0; k < size.z; k++) { var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); var blockValue = GameManager.Instance.World.GetBlock(clrIdx, p5); if (blockValue.Block.shape.IsTerrain() || blockValue.Equals(BlockValue.Air)) { continue; } GameManager.Instance.World.ChunkClusters[clrIdx].SetTextureFull(p5, textureFull); counter++; } } } var textureName = ""; if (BlockTextureData.GetDataByTextureID(texture) != null) { textureName = BlockTextureData.GetDataByTextureID(texture).Name; } SendOutput(string.Format("Painting {0} blocks with texture '{1}' @ {2} to {3}", counter, textureName, p3, p3 + size)); }
private static void SetPaintFace(Vector3i p3, Vector3i size) { byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput(string.Format("Unknown texture index {0}", texture)); return; } } uint setFace = 0; if (Options.ContainsKey("face")) { if (!uint.TryParse(Options["face"], out setFace)) { SendOutput("Unable to parse face value"); return; } } if (setFace > 5) { SendOutput("Face must be between 0 and 5"); return; } const int clrIdx = 0; var counter = 0; for (var j = 0; j < size.y; j++) { for (var i = 0; i < size.x; i++) { for (var k = 0; k < size.z; k++) { var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); var blockValue = GameManager.Instance.World.GetBlock(clrIdx, p5); if (blockValue.Equals(BlockValue.Air)) { continue; } GameManager.Instance.World.ChunkClusters[clrIdx].SetBlockFaceTexture(p5, (BlockFace)setFace, texture); counter++; } } } var textureName = ""; if (BlockTextureData.GetDataByTextureID(texture) != null) { textureName = BlockTextureData.GetDataByTextureID(texture).Name; } SendOutput(string.Format("Painting {0} blocks on face '{1}' with texture '{2}' @ {3} to {4}", counter, ((BlockFace)setFace).ToString(), textureName, p3, p3 + size)); }
public override void GetVertices(IBlockAccess blockAccess, ChunkData chunkBuilder, BlockCoordinates blockCoordinates, Vector3 vectorPos, BlockState baseBlock) { var position = new BlockCoordinates(vectorPos); var blocksUp = blockAccess.GetBlockStates(position.X, position.Y + 1, position.Z).ToArray(); //.GetType(); /* * (IsWater && blocksUp.Any( * x => x.State.Block.Renderable && (x.State.Block.BlockMaterial == Material.Water || x.State.Block.BlockMaterial == Material.WaterPlant))) || (IsLava * && blocksUp.Any(x => x.State.Block.Renderable && x.State.Block.BlockMaterial == Material.Lava)); */ bool aboveIsLiquid = blocksUp.Any(x => x.State?.VariantMapper.Model is LiquidBlockModel); List <BlockFace> renderedFaces = new List <BlockFace>(6); foreach (var face in Faces) { var pos = position + face.GetBlockCoordinates(); bool shouldRenderFace = true; foreach (var blockState in blockAccess.GetBlockStates(pos.X, pos.Y, pos.Z)) { if (blockState.Storage != 0 && (blockState.State == null || (blockState.State.Block is Air))) { continue; } var neighbor = blockState.State.Block; shouldRenderFace = baseBlock.Block.ShouldRenderFace(face, neighbor); } if (shouldRenderFace) { renderedFaces.Add(face); } } if (renderedFaces.Count == 0 && !aboveIsLiquid) { return; } int tl, tr, bl, br; int lowestFound = 999; BlockCoordinates lowestBlock = BlockCoordinates.Up; bool isFlowing = false; int rot = 0; if (aboveIsLiquid) { tl = 8; tr = 8; bl = 8; br = 8; rot = 180; isFlowing = true; } else { tl = GetAverageLiquidLevels(blockAccess, position, out lowestBlock, out lowestFound); tr = GetAverageLiquidLevels(blockAccess, position + BlockCoordinates.Right, out var trl, out var trv); if (trv < lowestFound) { lowestBlock = trl; lowestFound = trv; } bl = GetAverageLiquidLevels(blockAccess, position + BlockCoordinates.Forwards, out var bll, out var blv); if (blv < lowestFound) { lowestBlock = bll; lowestFound = blv; } br = GetAverageLiquidLevels(blockAccess, position + new BlockCoordinates(1, 0, 1), out var brl, out var brv); } double lowestDistance = 9999; isFlowing = isFlowing || (tl < 7 || tr < 7 || bl < 7 || br < 7); if (lowestBlock.Y <= position.Y && isFlowing) { for (int i = 0; i < 4; i++) { var rotation = 0; BlockCoordinates offset = BlockCoordinates.Zero; switch (i) { case 0: offset = BlockCoordinates.North; rotation = 180; break; case 1: offset = BlockCoordinates.South; rotation = 0; break; case 2: offset = BlockCoordinates.East; rotation = 270; break; case 3: offset = BlockCoordinates.West; rotation = 90; break; } var distance = Math.Abs( (position + offset).DistanceTo(lowestBlock)); if (distance < lowestDistance) { lowestDistance = distance; rot = rotation; } } } string texture = ""; if (IsLava) { texture = "block/lava"; } else { texture = "block/water"; } //texture = texture + "_flow"; if (isFlowing) { texture += "_flow"; } else { texture += "_still"; } BlockTextureData map = GetTextureUVMap(Alex.Instance.Resources, texture, 0, 16, 0, 16, 0, Color.White); var originalMap = new BlockTextureData(map.TextureInfo, map.TopLeft, map.TopRight, map.BottomLeft, map.BottomRight, map.ColorLeft, map.ColorTop, map.ColorBottom); map.Rotate(rot); foreach (var face in renderedFaces) { float s = 1f - Scale; var start = Vector3.One * s; var end = Vector3.One * Scale; var faceMap = map; if (face != BlockFace.Up) { faceMap = originalMap; } var vertices = GetFaceVertices(face, start, end, faceMap); Color vertColor; var bx = position.X; var y = position.Y; var bz = position.Z; if (ResourcePackBlockModel.SmoothLighting) { vertColor = CombineColors( GetBiomeColor(blockAccess, bx, y, bz), GetBiomeColor(blockAccess, bx - 1, y, bz - 1), GetBiomeColor(blockAccess, bx - 1, y, bz), GetBiomeColor(blockAccess, bx, y, bz - 1), GetBiomeColor(blockAccess, bx + 1, y, bz + 1), GetBiomeColor(blockAccess, bx + 1, y, bz), GetBiomeColor(blockAccess, bx, y, bz + 1), GetBiomeColor(blockAccess, bx - 1, y, bz + 1), GetBiomeColor(blockAccess, bx + 1, y, bz - 1)); } else { vertColor = GetBiomeColor(blockAccess, bx, y, bz); } var skyLight = blockAccess.GetSkyLight(position + face.GetBlockCoordinates()); var blockLight = blockAccess.GetBlockLight(position + face.GetBlockCoordinates()); float height = 0; for (var index = 0; index < vertices.Length; index++) { var vert = vertices[index]; if (vert.Position.Y > start.Y) { const float modifier = 2f; if (vert.Position.X < end.X && vert.Position.Z < end.Z) { height = (modifier * (tl)); rot = 0; } else if (vert.Position.X > start.X && vert.Position.Z < end.Z) { height = (modifier * (tr)); rot = 270; } else if (vert.Position.X < end.X && vert.Position.Z > start.Z) { height = (modifier * (bl)); rot = 90; } else { height = (modifier * (br)); rot = 270; } vert.Position.Y = height / 16.0f; //; + (position.Y); } vert.Position.Y += position.Y - s; vert.Position.X += position.X; vert.Position.Z += position.Z; vert.SkyLight = skyLight; vert.BlockLight = blockLight; if (IsWater) { vert.Color = vertColor; vert.Face = BlockFace.None; } else { vert.BlockLight = baseBlock.Block.LightValue; vert.Face = face; } vert.TexCoords += map.TextureInfo.Position; vert.TexCoords *= (Vector2.One / map.TextureInfo.AtlasSize); chunkBuilder.AddVertex(blockCoordinates, vert.Position, vert.TexCoords, vert.Color, blockLight, skyLight, RenderStage.Liquid); } } //return new VerticesResult(result.ToArray(), indexResult.ToArray()); }
private static void SetPaintFace(World world, Vector3i pos) { byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture value"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } } uint setFace = 0; if (Options.ContainsKey("face")) { if (!uint.TryParse(Options["face"], out setFace)) { SendOutput("Unable to parse face value"); return; } } if (setFace > 5) { SendOutput("Face must be between 0 and 5"); return; } var blockValue = world.GetBlock(pos); if (blockValue.Equals(BlockValue.Air)) { SendOutput($"Target block is air @ {pos}"); return; } if (blockValue.Block.shape.IsTerrain()) { SendOutput($"Target block is terrain @ {pos}"); return; } GameManager.Instance.SetBlockTextureServer(pos, (BlockFace)setFace, texture, -1); SendOutput($"Painting block on face '{((BlockFace)setFace).ToString()}' with texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}' @ {pos}"); }
private static void SetBlock(World world, Vector3i pos, BlockValue targetbv) { sbyte density = 0; if (Options.ContainsKey("d") && sbyte.TryParse(Options["d"], out density)) { SendOutput($"Using density {density}"); } byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture index"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } SendOutput($"Using texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}'"); } if (Options.ContainsKey("delmulti")) { return; } var bvCurrent = world.GetBlock(pos); //REMOVE PARENT OF MULTIDIM if (bvCurrent.Block.isMultiBlock && bvCurrent.ischild) { var parentPos = bvCurrent.Block.multiBlockPos.GetParentPos(pos, bvCurrent); var parent = world.GetBlock(parentPos); if (parent.ischild || parent.type != bvCurrent.type) { return; } world.ChunkClusters[0].SetBlock(parentPos, BlockValue.Air, false, false); } if (Options.ContainsKey("delmulti")) { return; } //REMOVE LCB's if (bvCurrent.Block.IndexName == "lpblock") { GameManager.Instance.persistentPlayers.RemoveLandProtectionBlock(pos); } var chunkSync = world.GetChunkFromWorldPos(pos.x, pos.y, pos.z) as Chunk; if (targetbv.Equals(BlockValue.Air)) { density = MarchingCubes.DensityAir; if (world.GetTerrainHeight(pos.x, pos.z) > pos.y) { chunkSync?.SetTerrainHeight(pos.x & 15, pos.z & 15, (byte)pos.y); } } else if (targetbv.Block.shape.IsTerrain()) { density = MarchingCubes.DensityTerrain; if (world.GetTerrainHeight(pos.x, pos.z) < pos.y) { chunkSync?.SetTerrainHeight(pos.x & 15, pos.z & 15, (byte)pos.y); } } else { //SET TEXTURE GameManager.Instance.SetBlockTextureServer(pos, BlockFace.None, texture, -1); } //SET BLOCK world.SetBlockRPC(pos, targetbv, density); }
private void CalculateModel(IBlockAccess world, BlockCoordinates blockCoordinates, ChunkData chunkBuilder, Vector3 position, Block baseBlock, BlockStateModel blockStateModel, ResourcePackModelBase model, Biome biome) { var positionOffset = baseBlock.GetOffset(NoiseGenerator, position); //bsModel.Y = Math.Abs(180 - bsModel.Y); //if (Resources.BlockModelRegistry.TryGet(blockStateModel.ModelName, out var registryEntry)) { //var model = registryEntry.Value; var baseColor = baseBlock.BlockMaterial.TintColor; for (var index = 0; index < model.Elements.Length; index++) { var element = model.Elements[index]; element.To *= Scale; element.From *= Scale; var faces = element.Faces.ToArray(); foreach (var face in faces) { var facing = face.Key; var cullFace = face.Value.CullFace ?? face.Key; if (blockStateModel.X > 0f) { var offset = blockStateModel.X / 90; cullFace = RotateDirection(cullFace, offset, FACE_ROTATION_X, INVALID_FACE_ROTATION_X); facing = RotateDirection(facing, offset, FACE_ROTATION_X, INVALID_FACE_ROTATION_X); } if (blockStateModel.Y > 0f) { var offset = blockStateModel.Y / 90; cullFace = RotateDirection(cullFace, offset, FACE_ROTATION, INVALID_FACE_ROTATION); facing = RotateDirection(facing, offset, FACE_ROTATION, INVALID_FACE_ROTATION); } float minX = float.MaxValue, minY = float.MaxValue, minZ = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue, maxZ = float.MinValue; if (!ShouldRenderFace(world, facing, position, baseBlock)) { continue; } var uv = face.Value.UV; float x1 = 0, x2 = 0, y1 = 0, y2 = 0; if (uv == null) { switch (face.Key) { case BlockFace.North: case BlockFace.South: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.West: case BlockFace.East: x1 = element.From.Z; x2 = element.To.Z; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.Down: case BlockFace.Up: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Z; y2 = 16f - element.From.Z; break; } } else { x1 = uv.X1; x2 = uv.X2; y1 = uv.Y1; y2 = uv.Y2; } var faceColor = baseColor; bool hasTint = (face.Value.TintIndex.HasValue && face.Value.TintIndex == 0); if (hasTint) { switch (baseBlock.BlockMaterial.TintType) { case TintType.Default: faceColor = Color.White; break; case TintType.Color: faceColor = baseBlock.BlockMaterial.TintColor; break; case TintType.Grass: if (SmoothLighting) { var bx = (int)position.X; var y = (int)position.Y; var bz = (int)position.Z; faceColor = CombineColors( GetGrassBiomeColor(world, bx, y, bz), GetGrassBiomeColor(world, bx - 1, y, bz), GetGrassBiomeColor(world, bx, y, bz - 1), GetGrassBiomeColor(world, bx + 1, y, bz), GetGrassBiomeColor(world, bx, y, bz + 1), GetGrassBiomeColor(world, bx + 1, y, bz - 1)); } else { faceColor = Resources.GetGrassColor( biome.Temperature, biome.Downfall, (int)position.Y); } break; case TintType.Foliage: if (face.Value.TintIndex.HasValue && face.Value.TintIndex == 0) { faceColor = Resources.GetFoliageColor( biome.Temperature, biome.Downfall, (int)position.Y); } break; default: throw new ArgumentOutOfRangeException(); } } faceColor = AdjustColor(faceColor, facing, element.Shade); BlockTextureData uvMap = GetTextureUVMap( Resources, face.Value.Texture, x1, x2, y1, y2, face.Value.Rotation, faceColor); var vertices = GetFaceVertices(face.Key, element.From, element.To, uvMap); vertices = ProcessVertices(vertices, blockStateModel, element, uvMap, facing, face.Value); RenderStage targetState = RenderStage.OpaqueFullCube; if (baseBlock.BlockMaterial.IsLiquid) { targetState = RenderStage.Liquid; } else if (uvMap.IsAnimated) { targetState = RenderStage.Animated; } else if (baseBlock.Transparent) { if (baseBlock.BlockMaterial.IsOpaque) { if (!Block.FancyGraphics && baseBlock.IsFullCube) { targetState = RenderStage.OpaqueFullCube; } else { targetState = RenderStage.Transparent; } } else { targetState = RenderStage.Translucent; } } else if (!baseBlock.IsFullCube) { targetState = RenderStage.Opaque; } for (int i = 0; i < vertices.Length; i++) { var vertex = vertices[i]; BlockModel.GetLight( world, vertex.Position + position + vertex.Face.GetVector3(), out var blockLight, out var skyLight, true); chunkBuilder.AddVertex( blockCoordinates, vertex.Position + position + positionOffset, vertex.TexCoords, vertex.Color, blockLight, skyLight, targetState); } } } } }