public override void Use(Player p, params string[] args) { if (World.Find(args[0]) != null && p.level.name != args[0]) { Player.players.ForEach(delegate(Player p1) { if (p1.level == p.level) p1.SendDespawn(p.id); p.SendDespawn(p1.id); }); foreach (Chunk c in p.level.chunkData.Values) { p.SendPreChunk(c, 0); } p.level = World.Find(args[0]); p.Teleport_Player(p.level.SpawnX, p.level.SpawnY, p.level.SpawnZ); foreach (Chunk c in p.level.chunkData.Values) { p.SendPreChunk(c, 1); System.Threading.Thread.Sleep(10); p.SendChunk(c); c.RecalculateLight(); } p.VisibleChunks.Clear(); p.UpdateChunks(true, true); return; } p.SendMessage("GOTO FAILED"); }
public void UpdateChunks(bool force, bool forcesend, int queue = 0) { if (c == null) { level.LoadChunk((int)pos.x >> 4, (int)pos.z >> 4, false, false); } if (c == null || (c == CurrentChunk && !force)) { return; } try { if (CurrentChunk != null) { CurrentChunk.RemoveEntity(this); } c.AddEntity(this); CurrentChunk = c; } catch { Logger.Log("Error updating chunk: " + this.ToString()); } if (isPlayer && p.LoggedIn) { //p.SendMessage(level.chunkManager.getBiomeGenAt(CurrentChunk.x << 4, CurrentChunk.z << 4).biomeName); // Debug! //bool locked = false; List <Point> templist = new List <Point>(); int sx = CurrentChunk.x - p.viewdistance; //StartX int ex = CurrentChunk.x + p.viewdistance; //EndX int sz = CurrentChunk.z - p.viewdistance; //StartZ int ez = CurrentChunk.z + p.viewdistance; //EndZ // This can cause severe lag! DO NOT USE IT!!! /*Parallel.For(sx, ex + 1, delegate(int x) * { * Parallel.For(sz, ez + 1, delegate(int z) * { * Point po = new Point(x, z); * while (locked) Thread.Sleep(1); * * lock (templist) * { * templist.Add(po); * } * //templist.Add(po); * * if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) * { * if (!p.level.chunkData.ContainsKey(po)) * p.level.LoadChunk(po.x, po.z); * p.SendChunk(p.level.chunkData[po]); * } * }); * });*/ for (int x = sx; x <= ex; x++) { for (int z = sz; z <= ez; z++) { Point po = new Point(x, z); templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) { p.level.LoadChunk(po.x, po.z, queue != -1, queue != -1); } try { if (p.level.chunkData.ContainsKey(po)) { if (!p.level.chunkData[po].generated) { World.chunker.QueueChunk(po, p.level); if (queue == -1) { while (!p.level.chunkData[po].generated) { Thread.Sleep(50); } p.SendChunk(p.level.chunkData[po]); } else { World.chunker.QueueChunkSend(po, p); } } else if (queue == 1) { if (!p.level.chunkData[po].populated) { World.chunker.QueueChunk(po, p.level, false); } World.chunker.QueueChunkSend(po, p); } else { if (!p.level.chunkData[po].populated) { World.chunker.QueueChunk(po, p.level, false); } p.SendChunk(p.level.chunkData[po]); //p.level.chunkData[po].Update(p.level, p); } } else { if (queue == -1) { while (!p.level.chunkData.ContainsKey(po)) { Thread.Sleep(50); } p.SendChunk(p.level.chunkData[po]); } else { World.chunker.QueueChunkSend(po, p); } } } catch { p.SendPreChunk(po.x, po.z, 0); } } } } //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(point.x, point.z, 0); lock (p.VisibleChunks) p.VisibleChunks.Remove(point); bool unloadChunk = true; Player.players.ForEach(delegate(Player pl) { if (pl.VisibleChunks.Contains(point)) { unloadChunk = false; return; } }); if (unloadChunk) { World.chunker.QueueChunkLoad(point.x, point.z, true, p.level); //p.level.UnloadChunk(point.x, point.z); } } } } }