From 9020d39fccbf6c04cee1f49a272746573c1f9565 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 22 May 2016 18:48:02 +0200 Subject: [PATCH 1/4] Introduce PositionClosestTo util --- OpenRA.Game/WorldUtils.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index ffefd3b98c..e8fc849c41 100644 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -30,6 +30,11 @@ namespace OpenRA return actors.MinByOrDefault(a => (a.CenterPosition - pos).LengthSquared); } + public static WPos PositionClosestTo(this IEnumerable positions, WPos pos) + { + return positions.MinByOrDefault(p => (p - pos).LengthSquared); + } + public static IEnumerable FindActorsInCircle(this World world, WPos origin, WDist r) { // Target ranges are calculated in 2D, so ignore height differences From 610f08f65276159e5cf4775e8601c74339755f74 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 28 May 2016 23:52:18 +0200 Subject: [PATCH 2/4] Add RotateToIsometry to Rectangle HitShape This is a temporary measue until we have a more flexible Polygon HitShape. --- OpenRA.Mods.Common/HitShapes/Rectangle.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.Common/HitShapes/Rectangle.cs b/OpenRA.Mods.Common/HitShapes/Rectangle.cs index 5aeef01412..798e01b90f 100644 --- a/OpenRA.Mods.Common/HitShapes/Rectangle.cs +++ b/OpenRA.Mods.Common/HitShapes/Rectangle.cs @@ -33,6 +33,11 @@ namespace OpenRA.Mods.Common.HitShapes [Desc("Defines the bottom offset relative to the actor's target point.")] public readonly int VerticalBottomOffset = 0; + // This is just a temporary work-around until we have a customizable PolygonShape + [Desc("Rotates shape by 90 degree relative to actor facing. Mostly required for buildings on isometric terrain.", + "Mobile actors do NOT need this!")] + public readonly bool RotateToIsometry = false; + int2 quadrantSize; int2 center; @@ -89,22 +94,26 @@ namespace OpenRA.Mods.Common.HitShapes public WDist DistanceFromEdge(WPos pos, Actor actor) { var actorPos = actor.CenterPosition; + var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, + new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); if (pos.Z > actorPos.Z + VerticalTopOffset) - return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalTopOffset))).Rotate(-actor.Orientation)); + return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalTopOffset))).Rotate(-orientation)); if (pos.Z < actorPos.Z + VerticalBottomOffset) - return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalBottomOffset))).Rotate(-actor.Orientation)); + return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalBottomOffset))).Rotate(-orientation)); - return DistanceFromEdge((pos - new WPos(actorPos.X, actorPos.Y, pos.Z)).Rotate(-actor.Orientation)); + return DistanceFromEdge((pos - new WPos(actorPos.X, actorPos.Y, pos.Z)).Rotate(-orientation)); } public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor) { var actorPos = actor.CenterPosition; + var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, + new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); - var vertsTop = combatOverlayVertsTop.Select(v => wr.ScreenPosition(actorPos + v.Rotate(actor.Orientation))); - var vertsBottom = combatOverlayVertsBottom.Select(v => wr.ScreenPosition(actorPos + v.Rotate(actor.Orientation))); + var vertsTop = combatOverlayVertsTop.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); + var vertsBottom = combatOverlayVertsBottom.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); } From f25398c731c4aeca57df7460e11d033c80c71644 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 28 May 2016 23:57:49 +0200 Subject: [PATCH 3/4] Add option to apply Rectangle HitShape to all TargetablePositions This allows to simulate a footprint-shaped HitShape until we have a proper Polygon HitShape. --- OpenRA.Mods.Common/HitShapes/Rectangle.cs | 34 ++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/HitShapes/Rectangle.cs b/OpenRA.Mods.Common/HitShapes/Rectangle.cs index 798e01b90f..10d5d2f960 100644 --- a/OpenRA.Mods.Common/HitShapes/Rectangle.cs +++ b/OpenRA.Mods.Common/HitShapes/Rectangle.cs @@ -38,6 +38,10 @@ namespace OpenRA.Mods.Common.HitShapes "Mobile actors do NOT need this!")] public readonly bool RotateToIsometry = false; + // This is just a temporary work-around until we have a customizable PolygonShape + [Desc("Applies shape to every TargetablePosition instead of just CenterPosition.")] + public readonly bool ApplyToAllTargetablePositions = false; + int2 quadrantSize; int2 center; @@ -97,6 +101,13 @@ namespace OpenRA.Mods.Common.HitShapes var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); + var targetablePositions = actor.TraitsImplementing(); + if (ApplyToAllTargetablePositions && targetablePositions.Any()) + { + var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor)); + actorPos = positions.PositionClosestTo(pos); + } + if (pos.Z > actorPos.Z + VerticalTopOffset) return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalTopOffset))).Rotate(-orientation)); @@ -112,10 +123,25 @@ namespace OpenRA.Mods.Common.HitShapes var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); - var vertsTop = combatOverlayVertsTop.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); - var vertsBottom = combatOverlayVertsBottom.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); - wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); - wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); + var targetablePositions = actor.TraitsImplementing(); + if (ApplyToAllTargetablePositions && targetablePositions.Any()) + { + var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor)); + foreach (var pos in positions) + { + var vertsTop = combatOverlayVertsTop.Select(v => wr.ScreenPosition(pos + v.Rotate(orientation))); + var vertsBottom = combatOverlayVertsBottom.Select(v => wr.ScreenPosition(pos + v.Rotate(orientation))); + wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); + wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); + } + } + else + { + var vertsTop = combatOverlayVertsTop.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); + var vertsBottom = combatOverlayVertsBottom.Select(v => wr.ScreenPosition(actorPos + v.Rotate(orientation))); + wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); + wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); + } } } } From 2a268f80b2e24462d7d4261842fd2100164a278f Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 19 Jun 2016 21:48:32 +0200 Subject: [PATCH 4/4] Give TS walls rectangular HitShapes --- mods/ts/rules/defaults.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index dc9db81002..b6bc1a7693 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -218,8 +218,10 @@ ScriptTriggers: UpgradeManager: Health: - Shape: Circle - Radius: 363 + Shape: Rectangle + RotateToIsometry: true + TopLeft: -384, -384 + BottomRight: 384, 384 VerticalTopOffset: 512 ^BuildingPlug: