Exemplo n.º 1
0
        public void RenderAfterWorld(WorldRenderer wr, World world)
        {
            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var rules = world.Map.Rules;

            var actorInfo = rules.Actors[Building];

            foreach (var dec in actorInfo.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy));
            }

            var cells = new Dictionary <CPos, bool>();

            // Linebuild for walls.
            // Assumes a 1x1 footprint; weird things will happen for other footprints
            if (rules.Actors[Building].Traits.Contains <LineBuildInfo>())
            {
                foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, Building, BuildingInfo))
                {
                    cells.Add(t, BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, t));
                }
            }
            else
            {
                if (!initialized)
                {
                    var rbi = rules.Actors[Building].Traits.GetOrDefault <RenderBuildingInfo>();
                    if (rbi == null)
                    {
                        preview = new IRenderable[0];
                    }
                    else
                    {
                        var palette = rbi.Palette ?? (Producer.Owner != null ?
                                                      rbi.PlayerPalette + Producer.Owner.InternalName : null);

                        preview = rbi.RenderPreview(world, rules.Actors[Building], wr.Palette(palette));
                    }

                    initialized = true;
                }

                var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, BuildingInfo) - WPos.Zero;
                foreach (var r in preview)
                {
                    r.OffsetBy(offset).Render(wr);
                }

                var res           = world.WorldActor.Trait <ResourceLayer>();
                var isCloseEnough = BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, Building, BuildingInfo, topLeft))
                {
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, BuildingInfo) && res.GetResource(t) == null);
                }
            }

            var pal = wr.Palette("terrain");

            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                new SpriteRenderable(tile, world.Map.CenterOfCell(c.Key),
                                     WVec.Zero, -511, pal, 1f, true).Render(wr);
            }
        }
Exemplo n.º 2
0
        public CPos?ChooseBuildLocation(string actorType, bool distanceToBaseIsImportant, int maxBaseDistance, BuildingType type)
        {
            var bi = Rules.Info[actorType].Traits.GetOrDefault <BuildingInfo>();

            if (bi == null)
            {
                return(null);
            }

            Func <WPos, CPos, CPos?> findPos = (pos, center) =>
            {
                for (var k = MaxBaseDistance; k >= 0; k--)
                {
                    var tlist = world.FindTilesInCircle(center, k)
                                .OrderBy(a => (a.CenterPosition - pos).LengthSquared);

                    foreach (var t in tlist)
                    {
                        if (world.CanPlaceBuilding(actorType, bi, t, null))
                        {
                            if (bi.IsCloseEnoughToBase(world, p, actorType, t))
                            {
                                if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(actorType, bi, t), false)))
                                {
                                    return(t);
                                }
                            }
                        }
                    }
                }

                return(null);
            };

            switch (type)
            {
            case BuildingType.Defense:
                Actor enemyBase = FindEnemyBuildingClosestToPos(baseCenter.CenterPosition);
                return(enemyBase != null?findPos(enemyBase.CenterPosition, defenseCenter) : null);

            case BuildingType.Refinery:
                var tilesPos = world.FindTilesInCircle(baseCenter, MaxBaseDistance)
                               .Where(a => resourceTypes.Contains(world.GetTerrainType(new CPos(a.X, a.Y))))
                               .OrderBy(a => (a.CenterPosition - baseCenter.CenterPosition).LengthSquared);
                return(tilesPos.Any() ? findPos(tilesPos.First().CenterPosition, baseCenter) : null);

            case BuildingType.Building:
                for (var k = 0; k < maxBaseDistance; k++)
                {
                    foreach (var t in world.FindTilesInCircle(baseCenter, k))
                    {
                        if (world.CanPlaceBuilding(actorType, bi, t, null))
                        {
                            if (distanceToBaseIsImportant && !bi.IsCloseEnoughToBase(world, p, actorType, t))
                            {
                                continue;
                            }

                            if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(actorType, bi, t), false)))
                            {
                                return(t);
                            }
                        }
                    }
                }

                break;
            }

            // Can't find a build location
            return(null);
        }
Exemplo n.º 3
0
        public override bool IsCloseEnoughToBase(World world, Player p, string buildingName, CPos topLeft)
        {
            if (base.IsCloseEnoughToBase(world, p, buildingName, topLeft))
            {
                return(true);
            }

            var shroud = p.Shroud;

            var hasVisibleCells  = false;
            var hasExploredCells = false;

            for (var y = topLeft.Y; y < topLeft.Y + Dimensions.Y; y++)
            {
                for (var x = topLeft.X; x < topLeft.X + Dimensions.X; x++)
                {
                    var pos = new CPos(x, y);

                    if (!shroud.IsExplored(pos))
                    {
                        if (AllCellsShouldBeExplored)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        hasExploredCells = true;
                    }

                    if (!shroud.IsVisible(pos))
                    {
                        if (AllCellsShouldBeVisible)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        hasVisibleCells = true;
                    }
                }
            }
            if (AnyCellShouldBeExplored && !hasExploredCells)
            {
                return(false);
            }
            if (AnyCellShouldBeVisible && !hasVisibleCells)
            {
                return(false);
            }

            var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent));
            var scanEnd   = world.Map.Clamp(topLeft + Dimensions + new CVec(Adjacent, Adjacent));

            var nearnessCandidates = new List <CPos>();
            var co = world.WorldActor.Trait <D2ConcreteOwners>();
            var allyBuildEnabled = world.WorldActor.Trait <MapBuildRadius>().AllyBuildRadiusEnabled;

            for (var y = scanStart.Y; y < scanEnd.Y; y++)
            {
                for (var x = scanStart.X; x < scanEnd.X; x++)
                {
                    var pos = new CPos(x, y);

                    if (shroud.IsExplored(pos) && shroud.IsVisible(pos))
                    {
                        var ownerAtPos = co.GetOwnerAt(pos);

                        if (ownerAtPos != null && (ownerAtPos == p || (allyBuildEnabled && ownerAtPos.Stances[p] == Stance.Ally)))
                        {
                            nearnessCandidates.Add(pos);
                        }
                    }
                }
            }

            var buildingTiles = FootprintUtils.Tiles(world.Map.Rules, buildingName, this, topLeft).ToList();

            return(nearnessCandidates
                   .Any(a => buildingTiles
                        .Any(b => Math.Abs(a.X - b.X) <= Adjacent &&
                             Math.Abs(a.Y - b.Y) <= Adjacent)));
        }
Exemplo n.º 4
0
        public IEnumerable <IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
        {
            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);

            var rules = world.Map.Rules;

            var actorInfo = rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy)))
                {
                    yield return(r);
                }
            }

            var cells = new Dictionary <CPos, bool>();

            var plugInfo = rules.Actors[building].TraitInfoOrDefault <PlugInfo>();

            if (plugInfo != null)
            {
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("Plug requires a 1x1 sized Building");
                }

                cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
            }
            else if (rules.Actors[building].HasTraitInfo <LineBuildInfo>())
            {
                // Linebuild for walls.
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");
                }

                foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo))
                {
                    cells.Add(t, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t));
                }
            }
            else
            {
                if (!initialized)
                {
                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(producer.Owner),
                        new HideBibPreviewInit()
                    };

                    var init = new ActorPreviewInitializer(rules.Actors[building], wr, td);
                    preview = rules.Actors[building].TraitInfos <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();

                    initialized = true;
                }

                var offset             = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
                var previewRenderables = preview
                                         .SelectMany(p => p.Render(wr, offset))
                                         .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

                foreach (var r in previewRenderables)
                {
                    yield return(r);
                }

                var res           = world.WorldActor.Trait <ResourceLayer>();
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft))
                {
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null);
                }
            }

            var pal        = wr.Palette(placeBuildingInfo.Palette);
            var topLeftPos = world.Map.CenterOfCell(topLeft);

            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                var pos  = world.Map.CenterOfCell(c.Key);
                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                                                  -511, pal, 1f, true));
            }
        }
Exemplo n.º 5
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            // Draw chrono range
            yield return(new RangeCircleRenderable(
                             self.CenterPosition,
                             WDist.FromCells(self.Trait <StructureChrono>().Info.MaxDistance),
                             0,
                             Color.FromArgb(128, Color.LawnGreen),
                             Color.FromArgb(96, Color.Black)));

            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
            var offset  = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
            var rules   = world.Map.Rules;

            var actorInfo = self.Info;             // rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, offset))
                {
                    yield return(r);
                }
            }

            // Cells, we are about to construct and occupy.
            var cells = new Dictionary <CPos, bool>();

            if (!initialized)
            {
                var td = new TypeDictionary()
                {
                    //new OpenRA.Mods.Common.FactionInit(faction),
                    new OpenRA.Mods.Common.FactionInit(""),
                    new OwnerInit(self.Owner),
                    new HideBibPreviewInit()
                };

                var init = new ActorPreviewInitializer(actorInfo, wr, td);
                preview = actorInfo.TraitInfos <IRenderActorPreviewInfo>()
                          .SelectMany(rpi => rpi.RenderPreview(init))
                          .ToArray();

                initialized = true;
            }

            var previewRenderables = preview
                                     .SelectMany(p => p.Render(wr, offset))
                                     .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

            foreach (var r in previewRenderables)
            {
                yield return(r);
            }

            var res           = world.WorldActor.Trait <ResourceLayer>();
            var selfPos       = self.Trait <IOccupySpace>().TopLeft;
            var isCloseEnough = ((topLeft - selfPos).Length) <= info.MaxDistance;

            foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft))
            {
                cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null);
            }

            var placeBuildingInfo = self.Owner.PlayerActor.Info.TraitInfo <PlaceBuildingInfo>();
            var pal        = wr.Palette(placeBuildingInfo.Palette);
            var topLeftPos = world.Map.CenterOfCell(topLeft);

            // draw red or white buildable cell indicator.
            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                var pos  = world.Map.CenterOfCell(c.Key);
                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                                                  -511, pal, 1f, true));
            }
        }
Exemplo n.º 6
0
 public override void AddedToWorld(Actor self)
 {
     base.AddedToWorld(self);
     blockedPositions = FootprintUtils.Tiles(self);
 }