Example #1
0
        /// <summary>
        /// Applies the damage to affected chunks.
        /// </summary>
        /// <param name="damage">Damage.</param>
        private void ApplyDamage(List <IntPoint> damage)
        {
            long minX = long.MaxValue, minY = long.MaxValue,
                 maxX = long.MinValue, maxY = long.MinValue;

            for (int i = 0; i < damage.Count; ++i)
            {
                if (damage[i].X < minX)
                {
                    minX = damage[i].X;
                }
                if (damage[i].X > maxX)
                {
                    maxX = damage[i].X;
                }

                if (damage[i].Y < minY)
                {
                    minY = damage[i].Y;
                }
                if (damage[i].Y > maxY)
                {
                    maxY = damage[i].Y;
                }
            }

            minX = Helper.NegDivision(minX, Chunk.SIZE);
            maxX = Helper.NegDivision(maxX, Chunk.SIZE);
            minY = Helper.NegDivision(minY, Chunk.SIZE);
            maxY = Helper.NegDivision(maxY, Chunk.SIZE);

            var clipper = new Clipper();

            for (int y = (int)minY; y <= maxY; ++y)
            {
                for (int x = (int)minX; x <= maxX; ++x)
                {
                    var chunk = GetChunk(TerrainHelper.PackCoordinates(x, y));

                    clipper.Clear();
                    clipper.AddPolygon(new List <IntPoint>()
                    {
                        new IntPoint(chunk.Left, chunk.Top),
                        new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top),
                        new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top + Chunk.SIZE),
                        new IntPoint(chunk.Left, chunk.Top + Chunk.SIZE)
                    }, PolyType.ptSubject);
                    clipper.AddPolygon(damage, PolyType.ptClip);
                    clipper.AddPolygons(chunk.Damage, PolyType.ptClip);
                    clipper.Execute(ClipType.ctIntersection, chunk.Damage,
                                    PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    chunk.Recalculate = true;
                    if (ActiveChunks.Contains(chunk))
                    {
                        Task.Run(() => { PlaceChunk(chunk); });
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Sets a region around a point as active.
        /// </summary>
        /// <param name="center">Center.</param>
        public override void SetActiveArea(Vector2 center)
        {
            _activeX = Helper.NegDivision((int)center.X, Chunk.SIZE);
            _activeY = Helper.NegDivision((int)center.Y, Chunk.SIZE);

            Chunk[] newActive = new Chunk[CHUNK_CACHE * CHUNK_CACHE];
            for (int y = 0; y < CHUNK_CACHE; ++y)
            {
                for (int x = 0; x < CHUNK_CACHE; ++x)
                {
                    var   cX    = x + _activeX - CHUNK_CACHE / 2;
                    var   cY    = y + _activeY - CHUNK_CACHE / 2;
                    var   id    = TerrainHelper.PackCoordinates(cX, cY);
                    Chunk chunk = null;
                    if (ActiveChunks.Any(c => c != null && c.ID == id))
                    {
                        chunk = ActiveChunks.First(c => c != null && c.ID == id);
                    }
                    else
                    {
                        chunk = GetChunk(id);
                        if (Multithreaded)
                        {
                            Task.Run(() => { PlaceChunk(chunk); });
                        }
                        else
                        {
                            PlaceChunk(chunk);
                        }
                    }
                    newActive[x + y * CHUNK_CACHE] = chunk;
                }
            }

            for (int i = 0; i < ActiveChunks.Length; ++i)
            {
                if (ActiveChunks[i] != null && !newActive.Contains(ActiveChunks[i]))
                {
                    UnplaceChunk(ActiveChunks[i]);
                    if (!ActiveChunks[i].ShouldSave)
                    {
                        ChunkCache.Remove(ActiveChunks[i].ID);
                    }
                }
            }
            ActiveChunks = newActive;
        }
Example #3
0
 public Chunk(int x, int y) :
     this(TerrainHelper.PackCoordinates(x, y))
 {
 }
Example #4
0
 /// <summary>
 /// Get the ID of a chunk at a given position.
 /// </summary>
 /// <returns>ID.</returns>
 /// <param name="x">The x coordinate.</param>
 /// <param name="y">The y coordinate.</param>
 public ulong ChunkID(float x, float y)
 {
     return(TerrainHelper.PackCoordinates(Helper.NegDivision((int)x, Chunk.SIZE),
                                          Helper.NegDivision((int)y, Chunk.SIZE)));
 }