Ejemplo n.º 1
0
		List<IRenderable> GenerateRenderables()
		{
			var comparer = new RenderableComparer(this);
			var actors = world.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight)
				.Append(world.WorldActor)
				.ToList();

			// Include player actor for the rendered player
			if (world.RenderPlayer != null)
				actors.Add(world.RenderPlayer.PlayerActor);

			var worldRenderables = actors.SelectMany(a => a.Render(this));
			if (world.OrderGenerator != null)
				worldRenderables = worldRenderables.Concat(world.OrderGenerator.Render(this, world));

			worldRenderables = worldRenderables.OrderBy(r => r, comparer);

			// Effects are drawn on top of all actors
			// TODO: Allow effects to be interleaved with actors
			var effectRenderables = world.Effects
				.SelectMany(e => e.Render(this));

			// Iterating via foreach() copies the structs, so enumerate by index
			var renderables = worldRenderables.Concat(effectRenderables).ToList();

			Game.Renderer.WorldVoxelRenderer.BeginFrame();
			for (var i = 0; i < renderables.Count; i++)
				renderables[i].BeforeRender(this);
			Game.Renderer.WorldVoxelRenderer.EndFrame();

			return renderables;
		}
Ejemplo n.º 2
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));
            }
        }
        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);
            }
        }