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);
            }
        }
Example #2
0
        IEnumerable <IRenderable> IOrderGenerator.RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft       = TopLeft;
            var footprint     = new Dictionary <CPos, PlaceBuildingCellType>();
            var activeVariant = variants[variant];
            var actorInfo     = activeVariant.ActorInfo;
            var buildingInfo  = activeVariant.BuildingInfo;
            var plugInfo      = activeVariant.PlugInfo;
            var lineBuildInfo = activeVariant.LineBuildInfo;
            var preview       = activeVariant.Preview;
            var owner         = queue.Actor.Owner;

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

                footprint.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo)));
            }
            else if (lineBuildInfo != null && owner.Shroud.IsExplored(topLeft))
            {
                // 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, actorInfo, buildingInfo, owner))
                    {
                        var lineBuildable   = world.IsCellBuildable(t.Cell, actorInfo, buildingInfo);
                        var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.Cell);
                        footprint.Add(t.Cell, MakeCellType(lineBuildable && lineCloseEnough, true));
                    }
                }

                var buildable   = world.IsCellBuildable(topLeft, actorInfo, buildingInfo);
                var closeEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                footprint[topLeft] = MakeCellType(buildable && closeEnough);
            }
            else
            {
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                foreach (var t in buildingInfo.Tiles(topLeft))
                {
                    footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (resourceLayer == null || resourceLayer.GetResource(t).Type == null)));
                }
            }

            return(preview?.Render(wr, topLeft, footprint) ?? Enumerable.Empty <IRenderable>());
        }
        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 #4
0
        protected override IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft   = TopLeft;
            var footprint = new Dictionary <CPos, PlaceBuildingCellType>();
            var plugInfo  = actorInfo.TraitInfoOrDefault <PlugInfo>();

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

                footprint.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo)));
            }
            else if (actorInfo.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, actorInfo, buildingInfo))
                    {
                        var lineBuildable   = world.IsCellBuildable(t.First, actorInfo, buildingInfo);
                        var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.First);
                        footprint.Add(t.First, MakeCellType(lineBuildable && lineCloseEnough, true));
                    }
                }

                var buildable   = world.IsCellBuildable(topLeft, actorInfo, buildingInfo);
                var closeEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                footprint[topLeft] = MakeCellType(buildable && closeEnough);
            }
            else
            {
                var res           = world.WorldActor.TraitOrDefault <ResourceLayer>();
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                foreach (var t in buildingInfo.Tiles(topLeft))
                {
                    footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (res == null || res.GetResource(t) == null)));
                }
            }

            return(preview != null?preview.Render(wr, topLeft, footprint) : Enumerable.Empty <IRenderable>());
        }
        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 #6
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 #8
0
        public void ResolveOrder(Actor self, Order order)
        {
            if (order.OrderString == "PlaceBuilding" || order.OrderString == "LineBuild")
            {
                self.World.AddFrameEndTask(w =>
                {
                    var prevItems = GetNumBuildables(self.Owner);

                    // Find the queue with the target actor
                    var queue = w.ActorsWithTrait <ProductionQueue>()
                                .Where(p => p.Actor.Owner == self.Owner &&
                                       p.Trait.CurrentItem() != null &&
                                       p.Trait.CurrentItem().Item == order.TargetString &&
                                       p.Trait.CurrentItem().RemainingTime == 0)
                                .Select(p => p.Trait)
                                .FirstOrDefault();

                    if (queue == null)
                    {
                        return;
                    }

                    var unit         = Rules.Info[order.TargetString];
                    var buildingInfo = unit.Traits.Get <BuildingInfo>();

                    if (order.OrderString == "LineBuild")
                    {
                        bool playSounds = true;
                        foreach (var t in BuildingUtils.GetLineBuildCells(w, order.TargetLocation, order.TargetString, buildingInfo))
                        {
                            var building = w.CreateActor(order.TargetString, new TypeDictionary
                            {
                                new LocationInit(t),
                                new OwnerInit(order.Player),
                            });

                            if (playSounds)
                            {
                                foreach (var s in buildingInfo.BuildSounds)
                                {
                                    Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
                                }
                            }
                            playSounds = false;
                        }
                    }
                    else
                    {
                        if (!self.World.CanPlaceBuilding(order.TargetString, buildingInfo, order.TargetLocation, null) ||
                            !buildingInfo.IsCloseEnoughToBase(self.World, order.Player, order.TargetString, order.TargetLocation))
                        {
                            return;
                        }

                        var building = w.CreateActor(order.TargetString, new TypeDictionary
                        {
                            new LocationInit(order.TargetLocation),
                            new OwnerInit(order.Player),
                        });
                        foreach (var s in buildingInfo.BuildSounds)
                        {
                            Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
                        }
                    }

                    PlayBuildAnim(self, unit);

                    queue.FinishProduction();

                    if (buildingInfo.RequiresBaseProvider)
                    {
                        // May be null if the build anywhere cheat is active
                        // BuildingInfo.IsCloseEnoughToBase has already verified that this is a valid build location
                        var producer = buildingInfo.FindBaseProvider(w, self.Owner, order.TargetLocation);
                        if (producer != null)
                        {
                            producer.Trait <BaseProvider>().BeginCooldown();
                        }
                    }

                    if (GetNumBuildables(self.Owner) > prevItems)
                    {
                        w.Add(new DelayedAction(10,
                                                () => Sound.PlayNotification(order.Player, "Speech", "NewOptions", order.Player.Country.Race)));
                    }
                });
            }
        }
Example #9
0
        public void ResolveOrder(Actor self, Order order)
        {
            if (order.OrderString == "PlaceBuilding" || order.OrderString == "LineBuild")
            {
                self.World.AddFrameEndTask(w =>
                {
                    var prevItems = GetNumBuildables(self.Owner);

                    // Find the queue with the target actor
                    var queue = w.ActorsWithTrait <ProductionQueue>()
                                .Where(p => p.Actor.Owner == self.Owner &&
                                       p.Trait.CurrentItem() != null &&
                                       p.Trait.CurrentItem().Item == order.TargetString &&
                                       p.Trait.CurrentItem().RemainingTime == 0)
                                .Select(p => p.Trait)
                                .FirstOrDefault();

                    if (queue == null)
                    {
                        return;
                    }

                    var unit         = Rules.Info[order.TargetString];
                    var buildingInfo = unit.Traits.Get <BuildingInfo>();

                    if (order.OrderString == "LineBuild")
                    {
                        bool playSounds = true;
                        foreach (var t in BuildingUtils.GetLineBuildCells(w, order.TargetLocation, order.TargetString, buildingInfo))
                        {
                            var building = w.CreateActor(order.TargetString, new TypeDictionary
                            {
                                new LocationInit(t),
                                new OwnerInit(order.Player),
                            });

                            if (playSounds)
                            {
                                foreach (var s in buildingInfo.BuildSounds)
                                {
                                    Sound.PlayToPlayer(order.Player, s, building.CenterLocation);
                                }
                            }
                            playSounds = false;
                        }
                    }
                    else
                    {
                        if (!self.World.CanPlaceBuilding(order.TargetString, buildingInfo, order.TargetLocation, null))
                        {
                            return;
                        }

                        var building = w.CreateActor(order.TargetString, new TypeDictionary
                        {
                            new LocationInit(order.TargetLocation),
                            new OwnerInit(order.Player),
                        });
                        foreach (var s in buildingInfo.BuildSounds)
                        {
                            Sound.PlayToPlayer(order.Player, s, building.CenterLocation);
                        }
                    }

                    PlayBuildAnim(self, unit);

                    queue.FinishProduction();

                    if (buildingInfo.RequiresBaseProvider)
                    {
                        var center = buildingInfo.CenterLocation(order.TargetLocation);
                        foreach (var bp in w.ActorsWithTrait <BaseProvider>())
                        {
                            if (bp.Actor.Owner.Stances[self.Owner] != Stance.Ally || !bp.Trait.Ready())
                            {
                                continue;
                            }

                            if (Combat.IsInRange(center, bp.Trait.Info.Range, bp.Actor.CenterLocation))
                            {
                                bp.Trait.BeginCooldown();
                                break;
                            }
                        }
                    }

                    if (GetNumBuildables(self.Owner) > prevItems)
                    {
                        w.Add(new DelayedAction(10,
                                                () => Sound.PlayNotification(order.Player, "Speech", "NewOptions", order.Player.Country.Race)));
                    }
                });
            }
        }
Example #10
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft        = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
            var centerPosition = world.Map.CenterOfCell(topLeft) + centerOffset;
            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, centerPosition))
                {
                    yield return(r);
                }
            }

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

            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, MakeCellType(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.First, MakeCellType(buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t.First), true));
                    }
                }

                cells[topLeft] = MakeCellType(buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft));
            }
            else
            {
                if (!initialized)
                {
                    var actor = rules.Actors[building];

                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.Owner),
                    };

                    foreach (var api in actor.TraitInfos <IActorPreviewInitInfo>())
                    {
                        foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.PlaceBuilding))
                        {
                            td.Add(o);
                        }
                    }

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

                    initialized = true;
                }

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

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

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

            var cellPalette = wr.Palette(placeBuildingInfo.Palette);
            var linePalette = wr.Palette(placeBuildingInfo.LineBuildSegmentPalette);
            var topLeftPos  = world.Map.CenterOfCell(topLeft);

            foreach (var c in cells)
            {
                var tile = !c.Value.HasFlag(CellType.Invalid) ? buildOk : buildBlocked;
                var pal  = c.Value.HasFlag(CellType.LineBuild) ? linePalette : cellPalette;
                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 #11
0
        public void ResolveOrder(Actor self, Order order)
        {
            if (order.OrderString == "PlaceBuilding" || order.OrderString == "LineBuild")
            {
                self.World.AddFrameEndTask(w =>
                {
                    var prevItems = GetNumBuildables(self.Owner);

                    // Find the queue with the target actor
                    var queue = w.ActorsWithTrait <ProductionQueue>()
                                .Where(p => p.Actor.Owner == self.Owner &&
                                       p.Trait.CurrentItem() != null &&
                                       p.Trait.CurrentItem().Item == order.TargetString &&
                                       p.Trait.CurrentItem().RemainingTime == 0)
                                .Select(p => p.Trait)
                                .FirstOrDefault();

                    if (queue == null)
                    {
                        return;
                    }

                    var unit         = Rules.Info[order.TargetString];
                    var buildingInfo = unit.Traits.Get <BuildingInfo>();

                    if (order.OrderString == "LineBuild")
                    {
                        bool playSounds = true;
                        foreach (var t in BuildingUtils.GetLineBuildCells(w, order.TargetLocation, order.TargetString, buildingInfo))
                        {
                            var building = w.CreateActor(order.TargetString, new TypeDictionary
                            {
                                new LocationInit(t),
                                new OwnerInit(order.Player),
                            });

                            if (playSounds)
                            {
                                foreach (var s in buildingInfo.BuildSounds)
                                {
                                    Sound.PlayToPlayer(order.Player, s, building.CenterLocation);
                                }
                            }
                            playSounds = false;
                        }
                    }
                    else
                    {
                        if (!self.World.CanPlaceBuilding(order.TargetString, buildingInfo, order.TargetLocation, null))
                        {
                            return;
                        }

                        var building = w.CreateActor(order.TargetString, new TypeDictionary
                        {
                            new LocationInit(order.TargetLocation),
                            new OwnerInit(order.Player),
                        });
                        foreach (var s in buildingInfo.BuildSounds)
                        {
                            Sound.PlayToPlayer(order.Player, s, building.CenterLocation);
                        }
                    }

                    PlayBuildAnim(self, unit);

                    queue.FinishProduction();

                    if (GetNumBuildables(self.Owner) > prevItems)
                    {
                        w.Add(new DelayedAction(10,
                                                () => Sound.PlayToPlayer(order.Player,
                                                                         w.WorldActor.Info.Traits.Get <EvaAlertsInfo>().NewOptions)));
                    }
                });
            }
        }