コード例 #1
0
ファイル: EditorActorBrush.cs プロジェクト: ushalin/OpenRA
        public EditorActorBrush(EditorViewportControllerWidget editorWidget, ActorInfo actor, PlayerReference owner, WorldRenderer wr)
        {
            this.editorWidget = editorWidget;
            worldRenderer     = wr;
            world             = wr.World;
            editorLayer       = world.WorldActor.Trait <EditorActorLayer>();

            Actor      = actor;
            this.owner = owner;

            preview           = editorWidget.Get <ActorPreviewWidget>("DRAG_ACTOR_PREVIEW");
            preview.GetScale  = () => worldRenderer.Viewport.Zoom;
            preview.IsVisible = () => editorWidget.CurrentBrush == this;

            var buildingInfo = actor.Traits.GetOrDefault <BuildingInfo>();

            if (buildingInfo != null)
            {
                locationOffset = -FootprintUtils.AdjustForBuildingSize(buildingInfo);
                previewOffset  = FootprintUtils.CenterOffset(world, buildingInfo);
            }

            var td = new TypeDictionary();

            td.Add(new FacingInit(facing));
            td.Add(new TurretFacingInit(facing));
            td.Add(new OwnerInit(owner.Name));
            td.Add(new RaceInit(owner.Race));
            preview.SetPreview(actor, td);

            // The preview widget may be rendered by the higher-level code before it is ticked.
            // Force a manual tick to ensure the bounds are set correctly for this first draw.
            Tick();
        }
コード例 #2
0
        public BelowUnits(Actor self)
        {
            // Offset effective position to the top of the northernmost occupied cell
            var bi = self.Info.Traits.GetOrDefault <BuildingInfo>();

            offset = ((bi != null) ? -FootprintUtils.CenterOffset(self.World, bi).Y : 0) - 512;
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            var anim = new Animation(init.World, image, () => 0);

            anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence), () => 0);

            var bi     = init.Actor.TraitInfo <BuildingInfo>();
            var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512;             // Additional 512 units move from center -> top of cell

            yield return(new SpriteActorPreview(anim, () => WVec.Zero, () => offset, p, rs.Scale));
        }
コード例 #5
0
        public RenderBuildingWarFactory(ActorInitializer init, RenderBuildingInfo info)
            : base(init, info)
        {
            roof = new Animation(GetImage(init.self));
            var bi = init.self.Info.Traits.Get <BuildingInfo>();

            // Additional 512 units move from center -> top of cell
            var offset = FootprintUtils.CenterOffset(bi).Y + 512;

            anims.Add("roof", new AnimationWithOffset(roof, null,
                                                      () => !buildComplete, offset));
        }
コード例 #6
0
        public WithProductionDoorOverlay(Actor self, WithProductionDoorOverlayInfo info)
        {
            var renderSprites = self.Trait <RenderSprites>();

            door = new Animation(self.World, renderSprites.GetImage(self));
            door.PlayFetchDirection(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.Sequence),
                                    () => desiredFrame - door.CurrentFrame);

            var buildingInfo = self.Info.TraitInfo <BuildingInfo>();

            var offset = FootprintUtils.CenterOffset(self.World, buildingInfo).Y + 512;

            renderSprites.Add(new AnimationWithOffset(door, null, () => !buildComplete, offset));
        }
コード例 #7
0
        public override IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            foreach (var orig in base.RenderPreviewSprites(init, rs, image, facings, p))
            {
                yield return(orig);
            }

            // Show additional roof overlay
            var anim = new Animation(init.World, image, () => 0);

            anim.PlayRepeating("idle-top");

            var bi     = init.Actor.Traits.Get <BuildingInfo>();
            var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512;

            yield return(new SpriteActorPreview(anim, WVec.Zero, offset, p, rs.Scale));
        }
コード例 #8
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));
            }
        }
コード例 #9
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.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));
            }
        }
コード例 #10
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));
            }
        }