void InitTileEntity() { if (hasInitTileEntity) { return; } foreach (Vector3Int pos in tileEntityList) { if (!tileEntityObjs.ContainsKey(pos)) { int sectionIndex = pos.y / 16; TagNodeCompound Section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray Blocks = Section["Blocks"] as TagNodeByteArray; TagNodeByteArray Data = Section["Data"] as TagNodeByteArray; int yInSection = pos.y % 16; int blockPos = yInSection * 16 * 16 + pos.z * 16 + pos.x; byte rawType = Blocks.Data[blockPos]; NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(rawType); byte blockData = NBTHelper.GetNibble(Data.Data, blockPos); GameObject obj = generator.GetTileEntityGameObject(this, blockData, pos); tileEntityObjs[pos] = obj; } } hasInitTileEntity = true; }
//input is local position public void GetBlockData(int xInChunk, int worldY, int zInChunk, out byte blockType, out byte blockData) { blockType = 0; blockData = 0; if (worldY < 0 || worldY > 255) { return; } if (xInChunk < 0 || xInChunk > 15 || zInChunk < 0 || zInChunk > 15) { NBTHelper.GetBlockData(xInChunk + 16 * x, worldY, zInChunk + 16 * z, out blockType, out blockData); return; } int sectionIndex = Mathf.FloorToInt(worldY / 16f); if (sectionIndex >= 0 && sectionIndex < Sections.Count) { TagNodeCompound section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray blocks = section["Blocks"] as TagNodeByteArray; TagNodeByteArray data = section["Data"] as TagNodeByteArray; int yInSection = worldY - sectionIndex * 16; int blockPos = yInSection * 16 * 16 + zInChunk * 16 + xInChunk; if (blockPos >= 0 && blockPos < 4096) { blockType = blocks.Data[blockPos]; blockData = NBTHelper.GetNibble(data.Data, blockPos); return; } } return; }
public void GetLightsByte(int xInChunk, int yInChunk, int zInChunk, out byte skyLight, out byte blockLight, bool extends = false) { skyLight = 15; blockLight = 0; if (xInChunk < 0 || xInChunk > 15 || zInChunk < 0 || zInChunk > 15) { if (extends) { int xOffset = 0; int zOffset = 0; if (xInChunk < 0) { xOffset = -1; } else if (xInChunk > 15) { xOffset = 1; } if (zInChunk < 0) { zOffset = -1; } else if (zInChunk > 15) { zOffset = 1; } NBTChunk chunk = NBTHelper.GetChunk(x + xOffset, z + zOffset); if (chunk != null) { chunk.GetLightsByte(xInChunk - xOffset * 16, yInChunk, zInChunk - zOffset * 16, out skyLight, out blockLight); } } return; } int sectionIndex = yInChunk / 16; if (sectionIndex >= Sections.Count || yInChunk < 0 || yInChunk > 255) { return; } int yInSection = yInChunk % 16; int blockPos = yInSection * 16 * 16 + zInChunk * 16 + xInChunk; TagNodeCompound Section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray SkyLight = Section["SkyLight"] as TagNodeByteArray; skyLight = NBTHelper.GetNibble(SkyLight.Data, blockPos); TagNodeByteArray BlockLight = Section["BlockLight"] as TagNodeByteArray; blockLight = NBTHelper.GetNibble(BlockLight.Data, blockPos); }
//input is local position public void GetBlockData(int xInChunk, int worldY, int zInChunk, ref byte blockType, ref byte blockData) { if (xInChunk < 0 || xInChunk > 15 || worldY < 0 || worldY > 255 || zInChunk < 0 || zInChunk > 15) { //if (xInChunk < 0) //{ // NBTChunk chunk = NBTHelper.GetChunk(x - 1, z); // chunk.GetBlockData(xInChunk + 16, worldY, zInChunk, ref blockType, ref blockData); //} //else if (xInChunk > 15) //{ // NBTChunk chunk = NBTHelper.GetChunk(x + 1, z); // chunk.GetBlockData(xInChunk - 16, worldY, zInChunk, ref blockType, ref blockData); //} //else if (zInChunk < 0) //{ // NBTChunk chunk = NBTHelper.GetChunk(x, z - 1); // chunk.GetBlockData(xInChunk, worldY, zInChunk + 16, ref blockType, ref blockData); //} //else if (zInChunk > 15) //{ // NBTChunk chunk = NBTHelper.GetChunk(x, z + 1); // chunk.GetBlockData(xInChunk, worldY, zInChunk - 16, ref blockType, ref blockData); //} //NBTHelper.GetBlockData(xInChunk + 16 * x, worldY, zInChunk + 16 * z, ref blockType, ref blockData); return; } int sectionIndex = Mathf.FloorToInt(worldY / 16f); if (sectionIndex >= 0 && sectionIndex < Sections.Count) { TagNodeCompound section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray blocks = section["Blocks"] as TagNodeByteArray; TagNodeByteArray data = section["Data"] as TagNodeByteArray; int yInSection = worldY - sectionIndex * 16; int blockPos = yInSection * 16 * 16 + zInChunk * 16 + xInChunk; if (blockPos >= 0 && blockPos < 4096) { blockType = blocks.Data[blockPos]; blockData = NBTHelper.GetNibble(data.Data, blockPos); return; } } return; }
public byte GetLightByte(int xInChunk, int yInChunk, int zInChunk, bool extends = false) { if (xInChunk < 0 || xInChunk > 15 || zInChunk < 0 || zInChunk > 15) { if (extends) { int xOffset = 0; int zOffset = 0; if (xInChunk < 0) { xOffset = -1; } else if (xInChunk > 15) { xOffset = 1; } if (zInChunk < 0) { zOffset = -1; } else if (zInChunk > 15) { zOffset = 1; } NBTChunk chunk = NBTHelper.GetChunk(x + xOffset, z + zOffset); if (chunk != null) { return(chunk.GetLightByte(xInChunk - xOffset * 16, yInChunk, zInChunk - zOffset * 16)); } else { return(15); } } else { return(15); } } int sectionIndex = yInChunk / 16; if (sectionIndex >= Sections.Count || yInChunk < 0 || yInChunk > 255) { return(15); } int yInSection = yInChunk % 16; int blockPos = yInSection * 16 * 16 + zInChunk * 16 + xInChunk; TagNodeCompound Section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray SkyLight = Section["SkyLight"] as TagNodeByteArray; byte skyLight = NBTHelper.GetNibble(SkyLight.Data, blockPos); TagNodeByteArray BlockLight = Section["BlockLight"] as TagNodeByteArray; byte blockLight = NBTHelper.GetNibble(BlockLight.Data, blockPos); //Debug.Log("y=" + x + "," + z + ",section=" + sectionIndex); return(skyLight > blockLight ? skyLight : blockLight); }
public void RefreshMeshData(UpdateFlags updateFlag = UpdateFlags.All) { //Debug.Log("RefreshMeshData,chunk=" + x + ",z=" + z); UnityEngine.Profiling.Profiler.BeginSample("RefreshMeshData"); if (updateFlag.HasFlag(UpdateFlags.Collidable)) { collidable.Clear(); } if (updateFlag.HasFlag(UpdateFlags.NotCollidable)) { notCollidable.Clear(); } if (updateFlag.HasFlag(UpdateFlags.Water)) { water.Clear(); } for (int sectionIndex = 0; sectionIndex < Sections.Count; sectionIndex++) { TagNodeCompound Section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray Blocks = Section["Blocks"] as TagNodeByteArray; TagNodeByteArray Data = Section["Data"] as TagNodeByteArray; for (int yInSection = 0; yInSection < 16; yInSection++) { for (int zInSection = 0; zInSection < 16; zInSection++) { for (int xInSection = 0; xInSection < 16; xInSection++) { int blockPos = yInSection * 16 * 16 + zInSection * 16 + xInSection; byte rawType = Blocks.Data[blockPos]; NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(rawType); int worldY = yInSection + sectionIndex * 16; if (generator != null) { pos.Set(xInSection, worldY, zInSection); byte blockData = NBTHelper.GetNibble(Data.Data, blockPos); try { if (generator.isTileEntity) { tileEntityList.Add(pos); } else { AddCube(generator, blockData, updateFlag); } } catch (System.Exception e) { int worldX = x * 16 + xInSection; int worldZ = z * 16 + zInSection; Vector3Int worldPos = new Vector3Int(worldX, worldY, worldZ); Debug.LogError(generator.GetType() + ",pos=" + worldPos + "\n" + e.ToString()); } } else if (rawType != 0 && rawType != 11) { int worldX = x * 16 + xInSection; int worldZ = z * 16 + zInSection; Vector3Int worldPos = new Vector3Int(worldX, worldY, worldZ); Debug.LogWarning("generator not exist" + ",pos=" + worldPos + ", type=" + rawType); } } } } } UnityEngine.Profiling.Profiler.EndSample(); }
private void OnGUI() { save = EditorGUILayout.TextField("save", save); pos = EditorGUILayout.Vector3IntField("pos", pos); GUILayout.Label("type=" + type); GUILayout.Label("data=" + blockdata); GUILayout.Label("biome=" + biomeType); GUILayout.Label("skyLight=" + skyLight); if (GUILayout.Button("Update")) { int chunkX = Mathf.FloorToInt(pos.x / 16f); int chunkY = Mathf.FloorToInt(pos.y / 16f); int chunkZ = Mathf.FloorToInt(pos.z / 16f); int xInChunk = pos.x - chunkX * 16; int yInChunk = pos.y - chunkY * 16; int zInChunk = pos.z - chunkZ * 16; TagNodeCompound Chunk = null; int regionX = NBTHelper.GetRegionCoordinate(chunkX); int regionZ = NBTHelper.GetRegionCoordinate(chunkZ); string path = Environment.ExpandEnvironmentVariables("%APPDATA%"); if (!Directory.Exists(path)) { path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); } path = Path.Combine(path, ".minecraft"); path = Path.Combine(path, "saves"); path = Path.Combine(path, save); path = Path.Combine(path, "region"); path = Path.Combine(path, "r." + regionX + "." + regionZ + ".mca"); RegionFile region = new RegionFile(path); if (region != null) { int _x = chunkX - regionX * 32; int _z = chunkZ - regionZ * 32; if (region.HasChunk(_x, _z)) { NbtTree _tree = new NbtTree(); using (Stream stream = region.GetChunkDataInputStream(_x, _z)) { _tree.ReadFrom(stream); } Chunk = _tree.Root; } } if (Chunk != null) { 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; type = blocks[blockPos]; TagNodeByteArray Data = section["Data"] as TagNodeByteArray; blockdata = NBTHelper.GetNibble(Data.Data, blockPos); TagNodeByteArray SkyLight = section["SkyLight"] as TagNodeByteArray; skyLight = NBTHelper.GetNibble(SkyLight.Data, blockPos); } TagNodeByteArray Biomes = Level["Biomes"] as TagNodeByteArray; biomeType = Biomes[xInChunk * 16 + zInChunk]; } Biome biome; if (biomeType < 6) { biome = gBiomes[biomeType]; } else { biome = gBiomes[0]; Debug.Log("no biome,type=" + biomeType); } float temp = biome.temp - Mathf.Max(pos.y - 64, 0) * 0.0016f; AdjTemp = Mathf.Clamp01(temp); AdjRainfall = Mathf.Clamp01(biome.rainfall) * AdjTemp; Vector2 uv = new Vector2(AdjTemp, AdjRainfall); Texture2D grass = Resources.Load <Texture2D>("GUI/grass"); c = grass.GetPixelBilinear(1 - AdjTemp, AdjRainfall); } GUILayout.Label("temp=" + AdjTemp); GUILayout.Label("rainfall=" + AdjRainfall); EditorGUILayout.ColorField(c, GUILayout.Height(30)); }
public void RefreshMeshData() { //Debug.Log("RefreshMeshData,chunk=" + x + ",z=" + z); collidable.Clear(); notCollidable.Clear(); water.Clear(); Vector3Int pos = new Vector3Int(); for (int sectionIndex = 0; sectionIndex < Sections.Count; sectionIndex++) { TagNodeCompound Section = Sections[sectionIndex] as TagNodeCompound; TagNodeByteArray Blocks = Section["Blocks"] as TagNodeByteArray; TagNodeByteArray Data = Section["Data"] as TagNodeByteArray; TagNodeByteArray SkyLight = Section["SkyLight"] as TagNodeByteArray; for (int yInSection = 0; yInSection < 16; yInSection++) { for (int zInSection = 0; zInSection < 16; zInSection++) { for (int xInSection = 0; xInSection < 16; xInSection++) { int blockPos = yInSection * 16 * 16 + zInSection * 16 + xInSection; byte rawType = Blocks.Data[blockPos]; NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(rawType); if (generator != null) { int worldY = yInSection + sectionIndex * 16; pos.Set(xInSection, worldY, zInSection); byte blockData = NBTHelper.GetNibble(Data.Data, blockPos); byte skyLight = NBTHelper.GetNibble(SkyLight.Data, blockPos); try { if (generator is NBTStationaryWater) { //generator.GenerateMeshInChunk(this, blockData, pos, water); } else if (generator is NBTPlant) { generator.AddCube(this, blockData, skyLight, pos, notCollidable); } else { generator.AddCube(this, blockData, skyLight, pos, collidable); } } catch (System.Exception e) { Debug.LogWarning(generator.GetType() + "\n" + e.ToString()); } } else if (rawType != 0 && rawType != 11) { Debug.LogWarning("generator not exist, type=" + rawType); } } } } } hasBuiltMesh = true; isDirty = false; }