diff --git a/OpenRA.Game/Graphics/LineRenderer.cs b/OpenRA.Game/Graphics/LineRenderer.cs index c8390fc54a..a3379a3469 100644 --- a/OpenRA.Game/Graphics/LineRenderer.cs +++ b/OpenRA.Game/Graphics/LineRenderer.cs @@ -20,6 +20,7 @@ namespace OpenRA.Graphics readonly Renderer renderer; readonly IShader shader; + readonly Action renderAction; readonly Vertex[] vertices; int nv = 0; @@ -31,6 +32,11 @@ namespace OpenRA.Graphics this.renderer = renderer; this.shader = shader; vertices = new Vertex[renderer.TempBufferSize]; + renderAction = () => + { + renderer.SetLineWidth(LineWidth); + renderer.DrawBatch(vertices, nv, PrimitiveType.LineList); + }; } public float LineWidth @@ -54,11 +60,7 @@ namespace OpenRA.Graphics if (nv > 0) { renderer.Device.SetBlendMode(BlendMode.Alpha); - shader.Render(() => - { - renderer.SetLineWidth(LineWidth); - renderer.DrawBatch(vertices, nv, PrimitiveType.LineList); - }); + shader.Render(renderAction); renderer.Device.SetBlendMode(BlendMode.None); nv = 0; diff --git a/OpenRA.Game/Graphics/QuadRenderer.cs b/OpenRA.Game/Graphics/QuadRenderer.cs index a9e1356677..39733df5a6 100644 --- a/OpenRA.Game/Graphics/QuadRenderer.cs +++ b/OpenRA.Game/Graphics/QuadRenderer.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Drawing; namespace OpenRA.Graphics @@ -16,6 +17,7 @@ namespace OpenRA.Graphics { readonly Renderer renderer; readonly IShader shader; + readonly Action renderAction; readonly Vertex[] vertices; int nv = 0; @@ -25,6 +27,7 @@ namespace OpenRA.Graphics this.renderer = renderer; this.shader = shader; vertices = new Vertex[renderer.TempBufferSize]; + renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList); } public void Flush() @@ -32,7 +35,7 @@ namespace OpenRA.Graphics if (nv > 0) { renderer.Device.SetBlendMode(BlendMode.Alpha); - shader.Render(() => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList)); + shader.Render(renderAction); renderer.Device.SetBlendMode(BlendMode.None); nv = 0; diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index 6a4cf063ee..4712661ead 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -17,6 +17,7 @@ namespace OpenRA.Graphics { readonly Renderer renderer; readonly IShader shader; + readonly Action renderAction; readonly Vertex[] vertices; Sheet currentSheet; @@ -28,6 +29,7 @@ namespace OpenRA.Graphics this.renderer = renderer; this.shader = shader; vertices = new Vertex[renderer.TempBufferSize]; + renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList); } public void Flush() @@ -37,7 +39,7 @@ namespace OpenRA.Graphics shader.SetTexture("DiffuseTexture", currentSheet.GetTexture()); renderer.Device.SetBlendMode(currentBlend); - shader.Render(() => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList)); + shader.Render(renderAction); renderer.Device.SetBlendMode(BlendMode.None); nv = 0; diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 2ad548930c..80eaad3a3f 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -21,6 +21,10 @@ namespace OpenRA.Graphics public static readonly Func RenderableScreenZPositionComparisonKey = r => ZPosition(r.Pos, r.ZOffset); + const int RangeCircleSegments = 32; + static readonly int[][] RangeCircleStartRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i).AsMatrix()); + static readonly int[][] RangeCircleEndRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i + 6).AsMatrix()); + public readonly World World; public readonly Theater Theater; public Viewport Viewport { get; private set; } @@ -197,10 +201,10 @@ namespace OpenRA.Graphics public void DrawRangeCircle(WPos pos, WDist range, Color c) { var offset = new WVec(range.Length, 0, 0); - for (var i = 0; i < 32; i++) + for (var i = 0; i < RangeCircleSegments; i++) { - var pa = pos + offset.Rotate(WRot.FromFacing(8 * i)); - var pb = pos + offset.Rotate(WRot.FromFacing(8 * i + 6)); + var pa = pos + offset.Rotate(RangeCircleStartRotations[i]); + var pb = pos + offset.Rotate(RangeCircleEndRotations[i]); Game.Renderer.WorldLineRenderer.DrawLine(ScreenPosition(pa), ScreenPosition(pb), c); } } @@ -240,17 +244,28 @@ namespace OpenRA.Graphics } // For scaling vectors to pixel sizes in the voxel renderer - public float[] ScreenVector(WVec vec) + public void ScreenVectorComponents(WVec vec, out float x, out float y, out float z) { var ts = Game.ModData.Manifest.TileSize; - return new float[] { ts.Width * vec.X / 1024f, ts.Height * vec.Y / 1024f, ts.Height * vec.Z / 1024f, 1 }; + x = ts.Width * vec.X / 1024f; + y = ts.Height * vec.Y / 1024f; + z = ts.Height * vec.Z / 1024f; + } + + // For scaling vectors to pixel sizes in the voxel renderer + public float[] ScreenVector(WVec vec) + { + float x, y, z; + ScreenVectorComponents(vec, out x, out y, out z); + return new[] { x, y, z, 1f }; } public int2 ScreenPxOffset(WVec vec) { // Round to nearest pixel - var px = ScreenVector(vec); - return new int2((int)Math.Round(px[0]), (int)Math.Round(px[1] - px[2])); + float x, y, z; + ScreenVectorComponents(vec, out x, out y, out z); + return new int2((int)Math.Round(x), (int)Math.Round(y - z)); } public float ScreenZPosition(WPos pos, int offset) diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index d5856d24c9..0fb00d6296 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -32,6 +32,14 @@ namespace OpenRA.Traits Ally = 4, } + public static class StanceExts + { + public static bool HasStance(this Stance s, Stance stance) + { + return (s & stance) == stance; + } + } + [Flags] public enum ImpactType { diff --git a/OpenRA.Game/WVec.cs b/OpenRA.Game/WVec.cs index 87805fe91f..731acb0512 100644 --- a/OpenRA.Game/WVec.cs +++ b/OpenRA.Game/WVec.cs @@ -43,7 +43,12 @@ namespace OpenRA public WVec Rotate(WRot rot) { - var mtx = rot.AsMatrix(); + return Rotate(rot.AsMatrix()); + } + + public WVec Rotate(int[] rotationMatrix) + { + var mtx = rotationMatrix; var lx = (long)X; var ly = (long)Y; var lz = (long)Z; diff --git a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs index 8c5810c1af..06e9375541 100644 --- a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs @@ -151,8 +151,9 @@ namespace OpenRA.Mods.Common.Graphics var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, (x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix()))); - var pxOffset = wr.ScreenVector(v.OffsetFunc()); - var pxPos = pxOrigin + new float2(pxOffset[0], pxOffset[1]); + float sx, sy, sz; + wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz); + var pxPos = pxOrigin + new float2(sx, sy); var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform); DrawBoundsBox(pxPos, screenTransform, bounds, Color.Yellow); } @@ -204,8 +205,9 @@ namespace OpenRA.Mods.Common.Graphics var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, (x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix()))); - var pxOffset = wr.ScreenVector(v.OffsetFunc()); - var pxPos = pxOrigin + new float2(pxOffset[0], pxOffset[1]); + float sx, sy, sz; + wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz); + var pxPos = pxOrigin + new float2(sx, sy); var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform); for (var i = 0; i < 8; i++) diff --git a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs index cdee1d2959..e911a02c7e 100644 --- a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits return true; var stance = self.Owner.Stances[byPlayer]; - return info.AlwaysVisibleStances.HasFlag(stance) || visible[byPlayer]; + return info.AlwaysVisibleStances.HasStance(stance) || visible[byPlayer]; } public void Tick(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Modifiers/HiddenUnderShroud.cs b/OpenRA.Mods.Common/Traits/Modifiers/HiddenUnderShroud.cs index b1eb280991..9d45976aef 100644 --- a/OpenRA.Mods.Common/Traits/Modifiers/HiddenUnderShroud.cs +++ b/OpenRA.Mods.Common/Traits/Modifiers/HiddenUnderShroud.cs @@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits return true; var stance = self.Owner.Stances[byPlayer]; - return Info.AlwaysVisibleStances.HasFlag(stance) || IsVisibleInner(self, byPlayer); + return Info.AlwaysVisibleStances.HasStance(stance) || IsVisibleInner(self, byPlayer); } public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) diff --git a/OpenRA.Mods.Common/Traits/Passenger.cs b/OpenRA.Mods.Common/Traits/Passenger.cs index aa805dee37..0df46d9083 100644 --- a/OpenRA.Mods.Common/Traits/Passenger.cs +++ b/OpenRA.Mods.Common/Traits/Passenger.cs @@ -111,22 +111,22 @@ namespace OpenRA.Mods.Common.Traits public class Passenger : IIssueOrder, IResolveOrder, IOrderVoice, INotifyRemovedFromWorld { public readonly PassengerInfo Info; - public Passenger(PassengerInfo info) { Info = info; } + public Passenger(PassengerInfo info) + { + Info = info; + Func canTarget = IsCorrectCargoType; + Func useEnterCursor = CanEnter; + Orders = new EnterAlliedActorTargeter[] + { + new EnterTransportTargeter("EnterTransport", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode), + new EnterTransportsTargeter("EnterTransports", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode) + }; + } + public Actor Transport; public Cargo ReservedCargo { get; private set; } - public IEnumerable Orders - { - get - { - yield return new EnterTransportTargeter("EnterTransport", 5, - target => IsCorrectCargoType(target), target => CanEnter(target), - Info.AlternateTransportsMode); - yield return new EnterTransportsTargeter("EnterTransports", 5, - target => IsCorrectCargoType(target), target => CanEnter(target), - Info.AlternateTransportsMode); - } - } + public IEnumerable Orders { get; private set; } public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) { diff --git a/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs b/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs index 850ac087c1..7a3c33b6cf 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.Graphics; using OpenRA.Traits; @@ -87,27 +88,27 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable Render(Actor self, WorldRenderer wr) { if (IsTraitDisabled) - yield break; + return Enumerable.Empty(); if (self.IsDead || !self.IsInWorld) - yield break; + return Enumerable.Empty(); if (anim == null) - yield break; + return Enumerable.Empty(); var allied = self.Owner.IsAlliedWith(self.World.RenderPlayer); if (!allied && !info.ShowToEnemies) - yield break; + return Enumerable.Empty(); if (allied && !info.ShowToAllies) - yield break; + return Enumerable.Empty(); if (!ShouldRender(self)) - yield break; + return Enumerable.Empty(); if (self.World.FogObscures(self)) - yield break; + return Enumerable.Empty(); var pxPos = wr.ScreenPxPosition(self.CenterPosition); var actorBounds = self.Bounds; @@ -150,7 +151,7 @@ namespace OpenRA.Mods.Common.Traits anim.Tick(); - yield return new SpriteRenderable(img, renderPos, WVec.Zero, info.ZOffset, wr.Palette(info.Palette), info.Scale, true); + return new IRenderable[] { new SpriteRenderable(img, renderPos, WVec.Zero, info.ZOffset, wr.Palette(info.Palette), info.Scale, true) }; } } } diff --git a/OpenRA.Mods.Common/Traits/Tooltip.cs b/OpenRA.Mods.Common/Traits/Tooltip.cs index 3ab2986d34..6bfb944c02 100644 --- a/OpenRA.Mods.Common/Traits/Tooltip.cs +++ b/OpenRA.Mods.Common/Traits/Tooltip.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits public string TooltipForPlayerStance(Stance stance) { - if (stance == Stance.None || !GenericVisibility.HasFlag(stance)) + if (stance == Stance.None || !GenericVisibility.HasStance(stance)) return Name; if (GenericStancePrefix && stance == Stance.Ally) diff --git a/OpenRA.Mods.Common/Traits/Upgrades/UpgradeActorsNear.cs b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeActorsNear.cs index 9fbe748e11..75e803ea00 100644 --- a/OpenRA.Mods.Common/Traits/Upgrades/UpgradeActorsNear.cs +++ b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeActorsNear.cs @@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.Traits return; var stance = self.Owner.Stances[a.Owner]; - if (!info.ValidStances.HasFlag(stance)) + if (!info.ValidStances.HasStance(stance)) return; var um = a.TraitOrDefault(); @@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.LengthSquared) { var stance = self.Owner.Stances[produced.Owner]; - if (!info.ValidStances.HasFlag(stance)) + if (!info.ValidStances.HasStance(stance)) return; var um = produced.TraitOrDefault(); @@ -127,7 +127,7 @@ namespace OpenRA.Mods.Common.Traits return; var stance = self.Owner.Stances[a.Owner]; - if (!info.ValidStances.HasFlag(stance)) + if (!info.ValidStances.HasStance(stance)) return; var um = a.TraitOrDefault(); diff --git a/OpenRA.Mods.Common/Warheads/Warhead.cs b/OpenRA.Mods.Common/Warheads/Warhead.cs index cff1414ad0..7eb3bc0652 100644 --- a/OpenRA.Mods.Common/Warheads/Warhead.cs +++ b/OpenRA.Mods.Common/Warheads/Warhead.cs @@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Warheads return false; var stance = firedBy.Owner.Stances[victim.Owner]; - if (!ValidStances.HasFlag(stance)) + if (!ValidStances.HasStance(stance)) return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. @@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Warheads // AffectsParent checks do not make sense for FrozenActors, so skip to stance checks var stance = firedBy.Owner.Stances[victim.Owner]; - if (!ValidStances.HasFlag(stance)) + if (!ValidStances.HasStance(stance)) return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list.