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