示例#1
0
        public BuildingInfluence(World world)
        {
            map = world.Map;

            influence = new CellLayer<Actor>(map);

            world.ActorAdded += a =>
            {
                var b = a.Info.TraitInfoOrDefault<BuildingInfo>();
                if (b == null)
                    return;

                foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location))
                    if (influence.Contains(u) && influence[u] == null)
                        influence[u] = a;
            };

            world.ActorRemoved += a =>
            {
                var b = a.Info.TraitInfoOrDefault<BuildingInfo>();
                if (b == null)
                    return;

                foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location))
                    if (influence.Contains(u) && influence[u] == a)
                        influence[u] = null;
            };
        }
示例#2
0
        void IRenderShroud.RenderShroud(Shroud shroud, WorldRenderer wr)
        {
            if (currentShroud != shroud)
            {
                if (currentShroud != null)
                {
                    currentShroud.CellsChanged -= DirtyCells;
                }

                if (shroud != null)
                {
                    shroud.CellsChanged += DirtyCells;
                }

                // Needs the anonymous function to ensure the correct overload is chosen
                if (shroud != null)
                {
                    visibleUnderShroud = puv => currentShroud.IsExplored(puv);
                }
                else
                {
                    visibleUnderShroud = puv => map.Contains(puv);
                }

                if (shroud != null)
                {
                    visibleUnderFog = puv => currentShroud.IsVisible(puv);
                }
                else
                {
                    visibleUnderFog = puv => map.Contains(puv);
                }

                currentShroud = shroud;
                DirtyCells(map.ProjectedCellBounds);
            }

            // We need to update newly dirtied areas of the shroud.
            // Expand the dirty area to cover the neighboring cells, since shroud is affected by neighboring cells.
            foreach (var uv in cellsDirty)
            {
                cellsAndNeighborsDirty.Add(uv);
                var cell = ((MPos)uv).ToCPos(map);
                foreach (var direction in CVec.Directions)
                {
                    cellsAndNeighborsDirty.Add((PPos)(cell + direction).ToMPos(map));
                }
            }

            foreach (var puv in cellsAndNeighborsDirty)
            {
                var uv = (MPos)puv;
                if (!tileInfos.Contains(uv))
                {
                    continue;
                }

                var tileInfo     = tileInfos[uv];
                var shroudSprite = GetSprite(shroudSprites, GetEdges(puv, visibleUnderShroud), tileInfo.Variant);
                var shroudPos    = tileInfo.ScreenPosition;
                if (shroudSprite != null)
                {
                    shroudPos += shroudSprite.Offset - 0.5f * shroudSprite.Size;
                }

                var fogSprite = GetSprite(fogSprites, GetEdges(puv, visibleUnderFog), tileInfo.Variant);
                var fogPos    = tileInfo.ScreenPosition;
                if (fogSprite != null)
                {
                    fogPos += fogSprite.Offset - 0.5f * fogSprite.Size;
                }

                shroudLayer.Update(uv, shroudSprite, shroudPos);
                fogLayer.Update(uv, fogSprite, fogPos);
            }

            cellsDirty.Clear();
            cellsAndNeighborsDirty.Clear();

            fogLayer.Draw(wr.Viewport);
            shroudLayer.Draw(wr.Viewport);
        }
示例#3
0
 public Player GetOwnerAt(CPos cell)
 {
     return(owners.Contains(cell) ? owners[cell] : null);
 }
示例#4
0
        void BuildDomains(World world)
        {
            ushort domain = 1;

            var visited = new CellLayer <bool>(map);

            var toProcess = new Queue <CPos>();

            toProcess.Enqueue(MPos.Zero.ToCPos(map));

            // Flood-fill over each domain.
            while (toProcess.Count != 0)
            {
                var start = toProcess.Dequeue();

                // Technically redundant with the check in the inner loop, but prevents
                // ballooning the domain counter.
                if (visited[start])
                {
                    continue;
                }

                var domainQueue = new Queue <CPos>();
                domainQueue.Enqueue(start);

                var currentPassable = CanTraverseTile(world, start);

                // Add all contiguous cells to our domain, and make a note of
                // any non-contiguous cells for future domains.
                while (domainQueue.Count != 0)
                {
                    var n = domainQueue.Dequeue();
                    if (visited[n])
                    {
                        continue;
                    }

                    var candidatePassable = CanTraverseTile(world, n);
                    if (candidatePassable != currentPassable)
                    {
                        toProcess.Enqueue(n);
                        continue;
                    }

                    visited[n] = true;
                    domains[n] = domain;

                    // PERF: Avoid LINQ.
                    foreach (var direction in CVec.Directions)
                    {
                        // Don't crawl off the map, or add already-visited cells.
                        var neighbor = direction + n;
                        if (visited.Contains(neighbor) && !visited[neighbor])
                        {
                            domainQueue.Enqueue(neighbor);
                        }
                    }
                }

                domain += 1;
            }

            Log.Write("debug", "Found {0} domains for movement class {1} on map {2}.", domain - 1, movementClass, map.Title);
        }
示例#5
0
        public void UpdateCell(CPos cell)
        {
            var uv = cell.ToMPos(Map);

            if (!Map.Resources.Contains(uv))
            {
                return;
            }

            var          tile = Map.Resources[uv];
            var          t    = Tiles[uv];
            ResourceType type;

            var newTile    = ResourceLayerContents.Empty;
            var newTerrain = byte.MaxValue;

            if (Resources.TryGetValue(tile.Type, out type))
            {
                newTile = new ResourceLayerContents
                {
                    Type    = type,
                    Density = CalculateCellDensity(type, cell)
                };

                newTerrain = Tileset.GetTerrainIndex(type.Info.TerrainType);
            }

            // Nothing has changed
            if (newTile.Type == t.Type && newTile.Density == t.Density)
            {
                return;
            }

            UpdateNetWorth(t.Type, t.Density, newTile.Type, newTile.Density);
            Tiles[uv]             = newTile;
            Map.CustomTerrain[uv] = newTerrain;
            if (CellChanged != null)
            {
                CellChanged(cell, type);
            }

            // Neighbouring cell density depends on this cell
            foreach (var d in CVec.Directions)
            {
                var neighbouringCell = cell + d;
                if (!Tiles.Contains(neighbouringCell))
                {
                    continue;
                }

                var neighbouringTile = Tiles[neighbouringCell];
                var density          = CalculateCellDensity(neighbouringTile.Type, neighbouringCell);
                if (neighbouringTile.Density == density)
                {
                    continue;
                }

                UpdateNetWorth(neighbouringTile.Type, neighbouringTile.Density, neighbouringTile.Type, density);
                neighbouringTile.Density = density;
                Tiles[neighbouringCell]  = neighbouringTile;

                if (CellChanged != null)
                {
                    CellChanged(neighbouringCell, type);
                }
            }
        }
示例#6
0
 ResourceLayerContents IResourceLayer.GetResource(CPos cell)
 {
     return(Tiles.Contains(cell) ? Tiles[cell] : default);
示例#7
0
 public bool Contains(PPos uv)
 {
     // Check that uv is inside the map area. There is nothing special
     // about explored here: any of the CellLayers would have been suitable.
     return(explored.Contains((MPos)uv));
 }
示例#8
0
 public Actor GetBuildingAt(CPos cell)
 {
     return(influence.Contains(cell) ? influence[cell] : null);
 }
示例#9
0
        /// <summary>
        /// Builds the domains.
        /// 构建域
        /// </summary>
        /// <param name="world">World.</param>
        void BuildDomains(World world)
        {
            ushort domain = 1;

            var visited = new CellLayer <bool>(map);

            var toProcess = new Queue <CPos>();

            toProcess.Enqueue(MPos.Zero.ToCPos(map));

            //Flood-fill over  each domain.
            //填充每个域
            while (toProcess.Count != 0)
            {
                var start = toProcess.Dequeue();

                //Technically redundant with the check in the inner loop,
                //but prevents ballooning the domain counter
                //技术上在内部循环检查冗余,防止膨胀域计数器
                if (visited[start])
                {
                    continue;
                }

                var domainQueue = new Queue <CPos>();
                domainQueue.Enqueue(start);


                var currentPassable = CanTraverseTile(world, start);


                //Add all contiguous cells to our domain,and make a not of an non-contiguous cells for future domain.
                //将所有连续的单元格添加到我们的域,并记录下未来域的非连续单元格
                while (domainQueue.Count != 0)
                {
                    var n = domainQueue.Dequeue();
                    if (visited[n])
                    {
                        continue;
                    }

                    var candidatePassable = CanTraverseTile(world, n);
                    if (candidatePassable != currentPassable)
                    {
                        toProcess.Enqueue(n);
                        continue;
                    }

                    visited[n] = true;
                    domains[n] = domain;


                    //PERF:Avoid LINQ
                    foreach (var direction in CVec.Directions)
                    {
                        //Don't crawl off the map ,or add already-visited cells.
                        //不要抓取地图,或添加已经访问的单元格
                        var neighbor = direction + n;
                        if (visited.Contains(neighbor) && !visited[neighbor])
                        {
                            domainQueue.Enqueue(neighbor);
                        }
                    }
                }

                domain += 1;
            }
        }