Ejemplo n.º 1
0
        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);
                        }
                    }
                }
            }
        }