Example #1
0
        static void Emit(Actor self)
        {
            var info   = self.Info.Traits.Get <EmitInfantryOnSellInfo>();
            var csv    = self.Info.Traits.GetOrDefault <CustomSellValueInfo>();
            var valued = self.Info.Traits.GetOrDefault <ValuedInfo>();
            var cost   = csv != null ? csv.Value : (valued != null ? valued.Cost : 0);

            var health     = self.TraitOrDefault <Health>();
            var dudesValue = info.ValuePercent * cost;

            if (health != null)
            {
                dudesValue = dudesValue * health.HP / health.MaxHP;
            }
            dudesValue /= 100;

            var eligibleLocations = FootprintUtils.Tiles(self).ToList();
            var actorTypes        = info.ActorTypes.Select(a => new { Name = a, Cost = self.World.Map.Rules.Actors[a].Traits.Get <ValuedInfo>().Cost }).ToArray();

            while (eligibleLocations.Count > 0 && actorTypes.Any(a => a.Cost <= dudesValue))
            {
                var at  = actorTypes.Where(a => a.Cost <= dudesValue).Random(self.World.SharedRandom);
                var loc = eligibleLocations.Random(self.World.SharedRandom);

                eligibleLocations.Remove(loc);
                dudesValue -= at.Cost;

                self.World.AddFrameEndTask(w => w.CreateActor(at.Name, new TypeDictionary
                {
                    new LocationInit(loc),
                    new OwnerInit(self.Owner),
                }));
            }
        }
Example #2
0
        IEnumerable <Order> ClearBlockersOrders(World world, CPos topLeft)
        {
            var allTiles       = FootprintUtils.Tiles(world.Map.Rules, building, buildingInfo, topLeft).ToArray();
            var neightborTiles = Util.ExpandFootprint(allTiles, true).Except(allTiles)
                                 .Where(world.Map.Contains).ToList();

            var blockers = allTiles.SelectMany(world.ActorMap.GetActorsAt)
                           .Where(a => a.Owner == queue.Actor.Owner && a.IsIdle)
                           .Select(a => new TraitPair <Mobile>(a, a.TraitOrDefault <Mobile>()));

            foreach (var blocker in blockers.Where(x => x.Trait != null))
            {
                var availableCells = neightborTiles.Where(t => blocker.Trait.CanEnterCell(t)).ToList();
                if (availableCells.Count == 0)
                {
                    continue;
                }

                yield return(new Order("Move", blocker.Actor, false)
                {
                    TargetLocation = blocker.Actor.ClosestCell(availableCells),
                    SuppressVisualFeedback = true
                });
            }
        }
Example #3
0
        public D2ConcreteOwners(World world)
        {
            map = world.Map;

            owners = new CellLayer <Player>(map);

            world.ActorAdded += a =>
            {
                var c = a.Info.TraitInfoOrDefault <D2ConcreteInfo>();
                if (c == null)
                {
                    return;
                }

                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 (owners.Contains(u) && owners[u] == null)
                    {
                        owners[u] = a.Owner;
                    }
                }
            };
        }
        public void RenderAfterWorld(WorldRenderer wr, World world)
        {
            var position = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
            var topLeft  = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var actorInfo = Rules.Info[Building];

            foreach (var dec in actorInfo.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                dec.Render(wr, world, actorInfo, position.CenterPosition);                      /* hack hack */
            }
            var cells = new Dictionary <CPos, bool>();

            // Linebuild for walls.
            // Assumes a 1x1 footprint; weird things will happen for other footprints
            if (Rules.Info[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.Info[Building].Traits.Get <RenderBuildingInfo>();
                    var palette = rbi.Palette ?? (Producer.Owner != null ?
                                                  rbi.PlayerPalette + Producer.Owner.InternalName : null);

                    preview     = rbi.RenderPreview(Rules.Info[Building], wr.Palette(palette));
                    initialized = true;
                }

                var offset = topLeft.CenterPosition + FootprintUtils.CenterOffset(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(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, c.Key.CenterPosition,
                                     WVec.Zero, -511, pal, 1f, true).Render(wr);
            }
        }
        public void RenderBeforeWorld(WorldRenderer wr, World world)
        {
            var position = Game.viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft  = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var actorInfo = Rules.Info[Building];

            foreach (var dec in actorInfo.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                dec.Render(wr, world, actorInfo, Traits.Util.CenterOfCell(position));                   /* hack hack */
            }
            var cells = new Dictionary <CPos, bool>();

            // Linebuild for walls.
            // Assumes a 1x1 footprint; weird things will happen for other footprints
            if (Rules.Info[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.Info[Building].Traits.Get <RenderBuildingInfo>();
                    var palette = rbi.Palette ?? (Producer.Owner != null ?
                                                  rbi.PlayerPalette + Producer.Owner.InternalName : null);

                    preview     = rbi.RenderPreview(Rules.Info[Building], wr.Palette(palette));
                    initialized = true;
                }

                foreach (var r in preview)
                {
                    r.Sprite.DrawAt(topLeft.ToPPos().ToFloat2() + r.Pos,
                                    r.Palette.Index,
                                    r.Scale * r.Sprite.size);
                }

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

            foreach (var c in cells)
            {
                (c.Value ? buildOk : buildBlocked).DrawAt(wr, c.Key.ToPPos().ToFloat2(), "terrain");
            }
        }
Example #6
0
        public FrozenUnderFog(ActorInitializer init, FrozenUnderFogInfo info)
        {
            // Spawned actors (e.g. building husks) shouldn't be revealed
            startsRevealed = info.StartsRevealed && !init.Contains <ParentActorInit>();
            footprint      = FootprintUtils.Tiles(init.self);
            tooltip        = Lazy.New(() => init.self.TraitsImplementing <IToolTip>().FirstOrDefault());
            tooltip        = Lazy.New(() => init.self.TraitsImplementing <IToolTip>().FirstOrDefault());
            health         = Lazy.New(() => init.self.TraitOrDefault <Health>());

            frozen  = new Dictionary <Player, FrozenActor>();
            visible = init.world.Players.ToDictionary(p => p, p => false);
        }
Example #7
0
        void UpdateNeighbours(Actor self)
        {
            var footprint = FootprintUtils.Tiles(self).ToArray();
            var adjacent  = Util.ExpandFootprint(footprint, true).Except(footprint)
                            .Where(self.World.Map.Contains).ToList();

            var adjacentActorTraits = adjacent.SelectMany(self.World.ActorMap.GetActorsAt)
                                      .SelectMany(a => a.TraitsImplementing <IWallConnector>());

            foreach (var rb in adjacentActorTraits)
            {
                rb.SetDirty();
            }
        }
Example #8
0
        public void AddedToWorld(Actor self)
        {
            var map = self.World.Map;

            if (template.PickAny)
            {
                // Fill the footprint with random variants
                foreach (var c in FootprintUtils.Tiles(self))
                {
                    // Only place on allowed terrain types
                    if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type))
                    {
                        continue;
                    }

                    // Don't place under other buildings or custom terrain
                    if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue)
                    {
                        continue;
                    }

                    var index = Game.CosmeticRandom.Next(template.TilesCount);
                    layer.AddTile(c, new TerrainTile(template.Id, (byte)index));
                }

                return;
            }

            var origin = self.Location + info.Offset;

            for (var i = 0; i < template.TilesCount; i++)
            {
                var c = origin + new CVec(i % template.Size.X, i / template.Size.X);

                // Only place on allowed terrain types
                if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type))
                {
                    continue;
                }

                // Don't place under other buildings or custom terrain
                if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue)
                {
                    continue;
                }

                layer.AddTile(c, new TerrainTile(template.Id, (byte)i));
            }
        }
        public void RenderBeforeWorld(WorldRenderer wr, World world)
        {
            var position = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
            var topLeft  = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var actorInfo = Rules.Info[Building];

            foreach (var dec in actorInfo.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                dec.Render(wr, world, actorInfo, Traits.Util.CenterOfCell(position));                   /* hack hack */
            }
            var cells = new Dictionary <int2, bool>();

            // Linebuild for walls.
            // Assumes a 1x1 footprint; weird things will happen for other footprints
            if (Rules.Info[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
            {
                foreach (var r in Preview)
                {
                    r.Sprite.DrawAt(Game.CellSize * topLeft + r.Pos,
                                    wr.GetPaletteIndex(r.Palette),
                                    r.Scale * r.Sprite.size);
                }

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

            foreach (var c in cells)
            {
                (c.Value ? buildOk : buildBlocked).DrawAt(wr, Game.CellSize * c.Key, "terrain");
            }
        }
Example #10
0
        public CPos?ChooseBuildLocation(string actorType)
        {
            var bi = Rules.Info[actorType].Traits.Get <BuildingInfo>();

            foreach (var t in world.FindTilesInCircle(baseCenter, MaxBaseDistance))
            {
                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);                       // i don't know where to put it.
        }
Example #11
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            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 = rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, offset))
                {
                    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");
                }

                if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift))
                {
                    foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo))
                    {
                        cells.Add(t, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t));
                    }
                }
                else
                {
                    cells.Add(topLeft, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft));
                }
            }
            else
            {
                if (!initialized)
                {
                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.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 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));
            }
        }
        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.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy)))
                {
                    yield return(r);
                }
            }

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

            // Linebuild for walls.
            // Requires a 1x1 footprint
            if (rules.Actors[Building].Traits.Contains <LineBuildInfo>())
            {
                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 init = new ActorPreviewInitializer(rules.Actors[Building], Producer.Owner, wr, new TypeDictionary());
                    preview = rules.Actors[Building].Traits.WithInterface <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();

                    initialized = true;
                }

                var comparer           = new RenderableComparer(wr);
                var offset             = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, BuildingInfo);
                var previewRenderables = preview
                                         .SelectMany(p => p.Render(wr, offset))
                                         .OrderBy(r => r, comparer);

                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("terrain");

            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                yield return(new SpriteRenderable(tile, world.Map.CenterOfCell(c.Key),
                                                  WVec.Zero, -511, pal, 1f, true));
            }
        }
Example #13
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);
        }
Example #14
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)));
        }
        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));
            }
        }
Example #16
0
 public override void AddedToWorld(Actor self)
 {
     base.AddedToWorld(self);
     blockedPositions = FootprintUtils.Tiles(self);
 }