public static void SetBlockByte(int x, int y, int z, byte type) { int chunkX = Mathf.FloorToInt(x / 16f); int chunkZ = Mathf.FloorToInt(z / 16f); int xInChunk = x - chunkX * 16; int zInChunk = z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); NBTBlock oldGenerator = NBTGeneratorManager.GetMeshGenerator(chunk.GetBlockByte(xInChunk, y, zInChunk)); UpdateFlags updateFlag = GetUpdateFlags(oldGenerator); if (type == 0) { chunk.GetBlockData(xInChunk, y + 1, zInChunk, out byte topType, out byte topData); NBTBlock topGenerator = NBTGeneratorManager.GetMeshGenerator(topType); if (topGenerator != null && topGenerator is NBTPlant) { BreakBlockEffect.Create(topType, topData, new Vector3(x, y + 1, z)); chunk.SetBlockByte(xInChunk, y + 1, zInChunk, 0); updateFlag |= UpdateFlags.NotCollidable; } } chunk.SetBlockByte(xInChunk, y, zInChunk, type); if (updateFlag.HasFlag(UpdateFlags.Lighting)) { UpdateLighting(x, y, z); } chunk.RebuildMesh(updateFlag); NBTChunk leftChunk = GetChunk(chunkX - 1, chunkZ); if (xInChunk == 0) { leftChunk.RebuildMesh(); } NBTChunk rightChunk = GetChunk(chunkX + 1, chunkZ); if (xInChunk == 15) { rightChunk.RebuildMesh(); } NBTChunk backChunk = GetChunk(chunkX, chunkZ - 1); if (zInChunk == 0) { backChunk.RebuildMesh(); } NBTChunk frontChunk = GetChunk(chunkX, chunkZ + 1); if (zInChunk == 15) { frontChunk.RebuildMesh(); } }
public static void GetBlockData(int x, int y, int z, out byte blockType, out byte blockData) { UnityEngine.Profiling.Profiler.BeginSample("GetBlockData"); int chunkX = Mathf.FloorToInt(x / 16f); int chunkY = Mathf.FloorToInt(y / 16f); int chunkZ = Mathf.FloorToInt(z / 16f); int xInChunk = x - chunkX * 16; int yInChunk = y - chunkY * 16; int zInChunk = z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); if (chunk != null) { chunk.GetBlockData(xInChunk, y, zInChunk, out blockType, out blockData); } else { blockType = 0; blockData = 0; //UnityEngine.Profiling.Profiler.BeginSample("GetChunkNode"); //TagNodeCompound Chunk = GetChunkNode(chunkX, chunkZ); //UnityEngine.Profiling.Profiler.EndSample(); //if (Chunk != null) //{ // UnityEngine.Profiling.Profiler.BeginSample("GetBlockData new block"); // TagNodeCompound Level = Chunk["Level"] as TagNodeCompound; // TagNodeList Sections = Level["Sections"] as TagNodeList; // if (chunkY < Sections.Count) // { // TagNodeCompound section = Sections[chunkY] as TagNodeCompound; // TagNodeByteArray Blocks = section["Blocks"] as TagNodeByteArray; // byte[] blocks = new byte[4096]; // Buffer.BlockCopy(Blocks, 0, blocks, 0, 4096); // int blockPos = yInChunk * 16 * 16 + zInChunk * 16 + xInChunk; // blockType = blocks[blockPos]; // TagNodeByteArray Data = section["Data"] as TagNodeByteArray; // byte[] data = Data.Data; // blockData = GetNibble(data, blockPos); // } // UnityEngine.Profiling.Profiler.EndSample(); //} } UnityEngine.Profiling.Profiler.EndSample(); }
protected override Color GetTintColorByData(NBTChunk chunk, Vector3Int pos, byte data) { if (data == 3 || data == 2) { return(TintManager.tintColor); } else if (data == 10) { chunk.GetBlockData(pos.x, pos.y - 1, pos.z, out byte bottomType, out byte bottomData); if (bottomData == 3 || bottomData == 2) { return(TintManager.tintColor); } } return(Color.white); }
public override string GetBreakEffectTexture(NBTChunk chunk, byte data) { switch (data) { case 1: return("double_plant_syringa_bottom"); case 2: return("double_plant_grass_bottom"); case 3: return("double_plant_fern_bottom"); case 4: return("double_plant_rose_bottom"); case 5: return("double_plant_paeonia_bottom"); case 10: byte bottomType = 0; byte bottomData = 0; chunk.GetBlockData(pos.x, pos.y - 1, pos.z, ref bottomType, ref bottomData); switch (bottomData) { case 1: return("double_plant_syringa_top"); case 2: return("double_plant_syringa_top"); case 3: return("double_plant_fern_top"); case 4: return("double_plant_rose_top"); case 5: return("double_plant_paeonia_top"); } break; } Debug.Log("large flowers no break effect texture, data=" + data); return("double_plant_syringa_bottom"); }
public override int GetPlantIndexByData(NBTChunk chunk, int data) { switch (data) { case 1: return(TextureArrayManager.GetIndexByName("double_plant_syringa_bottom")); case 2: return(TextureArrayManager.GetIndexByName("double_plant_grass_bottom")); case 3: return(TextureArrayManager.GetIndexByName("double_plant_fern_bottom")); case 4: return(TextureArrayManager.GetIndexByName("double_plant_rose_bottom")); case 5: return(TextureArrayManager.GetIndexByName("double_plant_paeonia_bottom")); case 10: byte bottomType = 0; byte bottomData = 0; chunk.GetBlockData(pos.x, pos.y - 1, pos.z, ref bottomType, ref bottomData); switch (bottomData) { case 1: return(TextureArrayManager.GetIndexByName("double_plant_syringa_top")); case 2: return(TextureArrayManager.GetIndexByName("double_plant_grass_top")); case 3: return(TextureArrayManager.GetIndexByName("double_plant_fern_top")); case 4: return(TextureArrayManager.GetIndexByName("double_plant_rose_top")); case 5: return(TextureArrayManager.GetIndexByName("double_plant_paeonia_top")); } break; } throw new System.Exception("no index"); }
MeshData GetMesh(NBTChunk chunk, Vector3Int localPosition, byte blockData) { MeshData mesh = meshes[blockData]; if (blockData == 0) { chunk.GetBlockData(localPosition.x - 1, localPosition.y, localPosition.z, out byte leftType, out byte leftData); chunk.GetBlockData(localPosition.x + 1, localPosition.y, localPosition.z, out byte rightType, out byte rightData); if (rightType == 53) { if (rightData == 2) { // +y-x-z_outer mesh = meshes[11]; } else if (rightData == 3) { // +y-x+z_outer mesh = meshes[9]; } } else if (leftType == 53) { if (leftData == 2) { // +y-x-z_inner mesh = meshes[10]; } else if (leftData == 3) { // +y-x+z_inner mesh = meshes[8]; } } } else if (blockData == 1) { chunk.GetBlockData(localPosition.x - 1, localPosition.y, localPosition.z, out byte leftType, out byte leftData); chunk.GetBlockData(localPosition.x + 1, localPosition.y, localPosition.z, out byte rightType, out byte rightData); if (leftType == 53) { if (leftData == 2) { // +y+x-z_outer mesh = meshes[15]; } else if (leftData == 3) { // +y+x+z_outer mesh = meshes[13]; } } else if (rightType == 53) { if (rightData == 2) { // +y+x-z_inner mesh = meshes[14]; } else if (rightData == 3) { // +y+x+z_inner mesh = meshes[12]; } } } else if (blockData == 2) { chunk.GetBlockData(localPosition.x, localPosition.y, localPosition.z + 1, out byte backType, out byte backData); chunk.GetBlockData(localPosition.x, localPosition.y, localPosition.z - 1, out byte frontType, out byte frontData); if (backType == 53) { if (backData == 0) { // +y-x-z_outer mesh = meshes[11]; } else if (backData == 1) { // +y+x-z_outer mesh = meshes[15]; } } else if (frontType == 53) { if (frontData == 0) { // +y-x-z_inner mesh = meshes[10]; } else if (frontData == 1) { // +y+x-z_inner mesh = meshes[14]; } } } else if (blockData == 3) { chunk.GetBlockData(localPosition.x, localPosition.y, localPosition.z + 1, out byte backType, out byte backData); chunk.GetBlockData(localPosition.x, localPosition.y, localPosition.z - 1, out byte frontType, out byte frontData); if (frontType == 53) { if (frontData == 0) { // +y-x+z_outer mesh = meshes[9]; } else if (frontData == 1) { // +y+x+z_outer mesh = meshes[13]; } } else if (backType == 53) { if (backData == 0) { // +y-x+z_inner mesh = meshes[8]; } else if (backData == 1) { // +y+x+z_inner mesh = meshes[12]; } } } return(mesh); }
public override void AddCube(NBTChunk chunk, byte blockData, Vector3Int pos, NBTGameObject nbtGO) { ca.pos = pos; ca.blockData = blockData; chunk.GetBlockData(pos.x, pos.y, pos.z - 1, out byte frontType, out byte frontData); chunk.GetBlockData(pos.x, pos.y, pos.z + 1, out byte backType, out byte backData); chunk.GetBlockData(pos.x - 1, pos.y, pos.z, out byte leftType, out byte leftData); chunk.GetBlockData(pos.x + 1, pos.y, pos.z, out byte rightType, out byte rightData); chunk.GetBlockData(pos.x, pos.y - 1, pos.z, out byte bottomType, out byte bottomData); chunk.GetBlockData(pos.x, pos.y + 1, pos.z, out byte topType, out byte topData); bool selfIsVerticalWater = IsVerticalWater(blockData); chunk.GetLights(pos.x, pos.y, pos.z, out float skyLight, out float blockLight); fa.color = Color.white; fa.skyLight = skylight_default; fa.blockLight = blocklight_default; fa.uv = uv_zero; if (NBTGeneratorManager.IsTransparent(frontType) && frontType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = nearBottomLeft; fa.pos[1] = nearTopLeft; fa.pos[2] = nearTopRight; fa.pos[3] = nearBottomRight; } else { fa.pos[0] = nearBottomLeft; fa.pos[1] = nearTopLeft_still; fa.pos[2] = nearTopRight_still; fa.pos[3] = nearBottomRight; } fa.normal = Vector3.forward; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(backType) && backType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farBottomRight; fa.pos[1] = farTopRight; fa.pos[2] = farTopLeft; fa.pos[3] = farBottomLeft; } else { fa.pos[0] = farBottomRight; fa.pos[1] = farTopRight_still; fa.pos[2] = farTopLeft_still; fa.pos[3] = farBottomLeft; } fa.normal = Vector3.back; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(leftType) && leftType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farBottomLeft; fa.pos[1] = farTopLeft; fa.pos[2] = nearTopLeft; fa.pos[3] = nearBottomLeft; } else { fa.pos[0] = farBottomLeft; fa.pos[1] = farTopLeft_still; fa.pos[2] = nearTopLeft_still; fa.pos[3] = nearBottomLeft; } fa.normal = Vector3.left; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(rightType) && rightType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = nearBottomRight; fa.pos[1] = nearTopRight; fa.pos[2] = farTopRight; fa.pos[3] = farBottomRight; } else { fa.pos[0] = nearBottomRight; fa.pos[1] = nearTopRight_still; fa.pos[2] = farTopRight_still; fa.pos[3] = farBottomRight; } fa.normal = Vector3.right; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(topType) && topType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farTopRight; fa.pos[1] = nearTopRight; fa.pos[2] = nearTopLeft; fa.pos[3] = farTopLeft; } else { bool leftIsVerticalWater = IsVerticalWater(leftData, leftType); bool rightIsVerticalWater = IsVerticalWater(rightData, rightType); bool frontIsVerticalWater = IsVerticalWater(frontData, frontType); bool backIsVerticalWater = IsVerticalWater(backData, backType); fa.pos[0] = backIsVerticalWater || rightIsVerticalWater ? farTopRight : farTopRight_still; fa.pos[1] = frontIsVerticalWater || rightIsVerticalWater ? nearTopRight : nearTopRight_still; fa.pos[2] = frontIsVerticalWater || leftIsVerticalWater ? nearTopLeft : nearTopLeft_still; fa.pos[3] = backIsVerticalWater || leftIsVerticalWater ? farTopLeft : farTopLeft_still; } fa.normal = Vector3.up; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(bottomType) && bottomType != TYPE_WATER) { fa.pos[0] = nearBottomRight; fa.pos[1] = farBottomRight; fa.pos[2] = farBottomLeft; fa.pos[3] = nearBottomLeft; fa.normal = Vector3.down; AddFace(nbtGO.nbtMesh, fa, ca); } }
// upper door // 0x1: 0 if hinge is on the left (the default), 1 if on the right // 0x2: 0 if unpowered, 1 if powered // 0x4: unused // 0x8: Always 1 for the upper part of a door. // lower door // 0x1,0x2: Two bits storing a value from 0 to 3 specifying the direction the door is facing: // 0: Facing east // 1: Facing south // 2: Facing west // 3: Facing north // 0x4: 0 if the entire door is closed, 1 if open. // 0x8: Always 0 for the lower part of a door. void FillMesh(NBTChunk chunk, CubeAttributes ca, NBTMesh nbtMesh) { float skyLight, blockLight; if (ca.isItemMesh) { chunk.GetLights(ca.worldPos.x, ca.worldPos.y, ca.worldPos.z, out skyLight, out blockLight); } else { chunk.GetLights(ca.pos.x, ca.pos.y, ca.pos.z, out skyLight, out blockLight); } FaceAttributes fa = new FaceAttributes(); fa.color = Color.white; fa.skyLight = new float[] { skyLight, skyLight, skyLight, skyLight }; fa.blockLight = new float[] { blockLight, blockLight, blockLight, blockLight }; fa.normal = Vector3.zero; bool isUpper = (ca.blockData & 0b1000) > 0; int hinge; DoorDirection direction = 0; bool isOpen = false; if (isUpper) { chunk.GetBlockData(ca.pos.x, ca.pos.y - 1, ca.pos.z, out byte belowType, out byte belowData); if (belowType == 64) { isOpen = (belowData & 0b0100) > 0; direction = (DoorDirection)(belowData & 0b0011); } hinge = (ca.blockData & 0b0001); } else { isOpen = (ca.blockData & 0b0100) > 0; direction = (DoorDirection)(ca.blockData & 0b0011); chunk.GetBlockData(ca.pos.x, ca.pos.y + 1, ca.pos.z, out byte aboveType, out byte aboveData); hinge = (aboveData & 0b0001); } if (ca.isBreakingMesh) { ca.pos = Vector3Int.zero; } try { fa.faceIndex = TextureArrayManager.GetIndexByName(isUpper ? "door_wood_upper" : "door_wood_lower"); if ((direction == DoorDirection.East && isOpen == false) || (direction == DoorDirection.South && isOpen && hinge == 1) || (direction == DoorDirection.North && isOpen && hinge == 0)) { fa.uv = uv_top; fa.pos = topVertices_east; AddFace(nbtMesh, fa, ca); fa.pos = bottomVertices_east; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_flip : uv_zero; fa.pos = leftVertices_east; AddFace(nbtMesh, fa, ca); fa.pos = rightVertices_east; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_side_flip : uv_side; fa.pos = frontVertices_east; AddFace(nbtMesh, fa, ca); fa.pos = backVertices_east; AddFace(nbtMesh, fa, ca); } else if ((direction == DoorDirection.South && isOpen == false) || (direction == DoorDirection.East && isOpen && hinge == 0) || (direction == DoorDirection.West && isOpen && hinge == 1)) { fa.uv = hinge == 0 ? uv_flip : uv_zero; fa.pos = frontVertices_south; AddFace(nbtMesh, fa, ca); fa.pos = backVertices_south; AddFace(nbtMesh, fa, ca); fa.uv = uv_top; fa.pos = topVertices_south; AddFace(nbtMesh, fa, ca); fa.pos = bottomVertices_south; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_side_flip : uv_side; fa.pos = leftVertices_south; AddFace(nbtMesh, fa, ca); fa.pos = rightVertices_south; AddFace(nbtMesh, fa, ca); } else if ((direction == DoorDirection.West && isOpen == false) || (direction == DoorDirection.South && isOpen && hinge == 0) || (direction == DoorDirection.North && isOpen && hinge == 1)) { fa.uv = uv_top; fa.pos = topVertices_west; AddFace(nbtMesh, fa, ca); fa.pos = bottomVertices_west; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_flip : uv_zero; fa.pos = leftVertices_west; AddFace(nbtMesh, fa, ca); fa.pos = rightVertices_west; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_side_flip : uv_side; fa.pos = frontVertices_west; AddFace(nbtMesh, fa, ca); fa.pos = backVertices_west; AddFace(nbtMesh, fa, ca); } else if ((direction == DoorDirection.North && isOpen == false) || (direction == DoorDirection.East && isOpen && hinge == 1) || (direction == DoorDirection.West && isOpen && hinge == 0)) { fa.uv = hinge == 0 ? uv_flip : uv_zero; fa.pos = frontVertices_north; AddFace(nbtMesh, fa, ca); fa.pos = backVertices_north; AddFace(nbtMesh, fa, ca); fa.uv = uv_top; fa.pos = topVertices_north; AddFace(nbtMesh, fa, ca); fa.pos = bottomVertices_north; AddFace(nbtMesh, fa, ca); fa.uv = hinge == 0 ? uv_side_flip : uv_side; fa.pos = leftVertices_north; AddFace(nbtMesh, fa, ca); fa.pos = rightVertices_north; AddFace(nbtMesh, fa, ca); } } catch (System.Exception e) { Debug.Log(e.ToString() + "\n" + "pos=" + ca.pos + ",data=" + ca.blockData); } }