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; }
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); } }