private Chunk _LoadChunk(int x, int z) { //CurrentBlock.X = x; //CurrentBlock.Z = z; Chunk c = new Chunk(this); c.Loading = true; c.Filename = GetChunkFilename(x, z); c.CreationDate = File.GetCreationTime(c.Filename); c.Creator = "?"; c.Size = ChunkScale; if (!File.Exists(c.Filename)) { Console.WriteLine("! {0}", c.Filename); return null; } #if !DEBUG || CATCH_CHUNK_ERRORS try { #endif mChunk = new NbtFile(c.Filename); mChunk.LoadFile(); NbtCompound level = (NbtCompound)mChunk.RootTag["Level"]; c.Position = new Vector3i( level.Get<NbtInt>("xPos").Value, level.Get<NbtInt>("zPos").Value, 0); if ((int)c.Position.X != x || (int)c.Position.Y != z) { throw new Exception(string.Format("Chunk pos is wrong. {0}!={1}", c.Filename, c.Position)); } NbtList TileEntities = (NbtList)level["TileEntities"]; if (TileEntities.Tags.Count > 0) { //Console.WriteLine("*** Found TileEntities."); LoadTileEnts(ref c, (int)x, (int)z, TileEntities); } NbtList Entities = (NbtList)level["Entities"]; Console.WriteLine("*** Found {0} Entities.",Entities.Tags.Count); if (Entities.Tags.Count > 0) { LoadEnts(ref c, (int)x, (int)z, Entities); } // Blocks c.Blocks = DecompressBlocks(level.Get<NbtByteArray>("Blocks").Value); c.BlockLight = DecompressLightmap(level.Get<NbtByteArray>("BlockLight").Value); c.SkyLight = DecompressLightmap(level.Get<NbtByteArray>("SkyLight").Value); c.Data = DecompressDatamap(level.Get<NbtByteArray>("Data").Value); c.Loading = false; c.UpdateOverview(); string ci = string.Format("{0},{1}", x, z); if (mChunks.ContainsKey(ci)) return mChunks[ci]; mChunks.Add(ci, c); //TODO: Make Pig spawner converter. for (int Z = 0; Z < ChunkScale.X; Z++) { for (int Y = 0; Y < ChunkScale.Y; Y++) { for (int X = 0; X < ChunkScale.X; X++) { byte b = c.Blocks[X, Y, Z]; if (b == 52) { MobSpawner ms = new MobSpawner(); ms.Pos=new Vector3i(X, Y, Z); ms.EntityId = "Pig"; ms.UUID = Guid.NewGuid(); mTileEntities.Add(ms.UUID, ms); //c++; } } } } //if (c>0) Console.WriteLine("*** {0} spawners found.", c); //Console.WriteLine("Loaded {0} bytes from chunk {1}.", CurrentChunks.Length, c.Filename); return c; #if !DEBUG || CATCH_CHUNK_ERRORS } catch (Exception e) { string err = string.Format(" *** ERROR: Chunk {0},{1} ({2}) failed to load:\n\n{3}", x, z, c.Filename, e); Console.WriteLine(err); if (CorruptChunk != null) CorruptChunk(x,z,err, c.Filename); return null; } #endif }
/// <summary> /// Load a TileEntity from an NbtCompound. /// </summary> /// <param name="CX">Chunk X Coordinate.</param> /// <param name="CY">Chunk Y Coordinate.</param> /// <param name="CS">Chunk horizontal scale (16 in /game/)</param> /// <param name="c"></param> /// <returns>TileEntity.</returns> public static TileEntity GetEntity(int CX, int CY, int CS, NbtCompound c) { TileEntity e; switch ((c["id"] as NbtString).Value) { case "Chest": e = new Chest(CX,CY,CS,c); break; case "MobSpawner": e = new MobSpawner(CX, CY, CS, c); break; case "Furnace": e = new Furnace(CX, CY, CS, c); break; case "Sign": e = new Sign(CX, CY, CS, c); break; case "NULL": // Ignore it :| return new TileEntity(CX, CY, CS, c); default: #if DEBUG Console.WriteLine("*** Unknown TileEntity: {0}", (c["id"] as NbtString).Value); Console.WriteLine(c); #endif File.WriteAllText(string.Format("UnknownTileEntity.{0}.txt", (c["id"] as NbtString).Value),c.ToString().Replace("\n","\r\n")); return new TileEntity(CX, CY, CS, c); } #if DEBUG Console.WriteLine("Loaded {1} @ {0}", e,e.Pos); #endif return e; }
/// <summary> /// Generate a chunk /// </summary> /// <param name="CX">Chunk X</param> /// <param name="CZ">Chunk Z</param> /// <param name="b">Blocks</param> /// <param name="mh">Map handler</param> /// <param name="r">Random</param> /// <returns></returns> public static bool MakeDungeon(int CX, int CZ, ref byte[, ,] b, ref IMapHandler mh, Random r) { int CH = (int)mh.ChunkScale.X; int CV = (int)mh.ChunkScale.Y; int x = r.Next(0+DungeonSizeX-1, CH-DungeonSizeX+1); int y = r.Next(0+DungeonSizeY-1, CV-DungeonSizeY+1); int z = r.Next(0+DungeonSizeZ-1, CH-DungeonSizeZ+1); Vector3i position = mh.Local2Global(CX,CZ,new Vector3i(x,y,z)); //Console.WriteLine("Creating dungeon in {0}...", position); if (!CheckForDungeonSpace(b, x, y, z)) return false; Vector3i size = new Vector3i((DungeonSizeX*2)+1,(DungeonSizeY*2)+1,(DungeonSizeZ*2)+1); Vector3i sizeAir = new Vector3i(size.X-1,size.Y-1,size.Z-1); FillRect(ref b, 48, position, size); // Do walls (RANDOMIZE) FillRect(ref b, 0, position, sizeAir); // Add air MobSpawner ms = new MobSpawner(); ms.Delay=20; ms.EntityId=Entity.GetRandomMonsterID(r); ms.Pos = mh.Local2Global(CX,CZ,new Vector3i(x, y - DungeonSizeZ + 1, z)); ms.UUID = Guid.NewGuid(); mh.SetTileEntity(ms); b[x, y - DungeonSizeZ + 1, z] = 52; return true; }