diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs
index 3ceeca8b09..1a0956ae35 100755
--- a/OpenRa.Game/Actor.cs
+++ b/OpenRa.Game/Actor.cs
@@ -71,8 +71,7 @@ namespace OpenRa.Game
get
{
var firstSprite = Render().FirstOrDefault();
- if( firstSprite.Sprite == null )
- return new float2( 0, 0 );
+ if (firstSprite.Sprite == null) return float2.Zero;
return firstSprite.Sprite.size;
}
}
diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index 74d85740c5..3ea793d682 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -108,7 +108,9 @@
+
+
@@ -133,6 +135,8 @@
+
+
@@ -179,6 +183,7 @@
+
diff --git a/OpenRa.Game/Traits/Activities/Circle.cs b/OpenRa.Game/Traits/Activities/Circle.cs
new file mode 100644
index 0000000000..6f8eaefffd
--- /dev/null
+++ b/OpenRa.Game/Traits/Activities/Circle.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenRa.Game.Traits.Activities
+{
+ class Circle : IActivity
+ {
+ public IActivity NextActivity { get; set; }
+ bool isCanceled;
+ readonly int2 Cell;
+
+ public Circle(int2 cell) { Cell = cell; }
+
+ public IActivity Tick(Actor self)
+ {
+ if (isCanceled) return NextActivity;
+ var unit = self.traits.Get();
+ return new Fly(Util.CenterOfCell(Cell))
+ {
+ NextActivity =
+ new FlyTimed(50, 20)
+ {
+ NextActivity = this
+ }
+ };
+ }
+
+ public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
+ }
+}
diff --git a/OpenRa.Game/Traits/Activities/Fly.cs b/OpenRa.Game/Traits/Activities/Fly.cs
index ca4a631ad6..4f7a4241f7 100644
--- a/OpenRa.Game/Traits/Activities/Fly.cs
+++ b/OpenRa.Game/Traits/Activities/Fly.cs
@@ -43,154 +43,4 @@ namespace OpenRa.Game.Traits.Activities
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
}
-
- class Land : IActivity
- {
- readonly float2 Pos;
- bool isCanceled;
-
- public Land(float2 pos) { Pos = pos; }
-
- public IActivity NextActivity { get; set; }
-
- public IActivity Tick(Actor self)
- {
- if (isCanceled) return NextActivity;
-
- var d = Pos - self.CenterLocation;
- if (d.LengthSquared < 50) /* close enough */
- return NextActivity;
-
- var unit = self.traits.Get();
-
- if (unit.Altitude > 0)
- --unit.Altitude;
-
- var desiredFacing = Util.GetFacing(d, unit.Facing);
- Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
- var speed = .2f * Util.GetEffectiveSpeed(self);
- var angle = unit.Facing / 128f * Math.PI;
-
- self.CenterLocation += speed * -float2.FromAngle((float)angle);
- self.Location = ((1 / 24f) * self.CenterLocation).ToInt2();
-
- return this;
- }
-
- public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
- }
-
- class FlyTimed : IActivity
- {
- public IActivity NextActivity { get; set; }
- int remainingTicks;
- int targetAltitude;
-
- public FlyTimed(int ticks, int targetAltitude) { remainingTicks = ticks; this.targetAltitude = targetAltitude; }
-
- public IActivity Tick(Actor self)
- {
- if (remainingTicks == 0)
- return NextActivity;
-
- --remainingTicks;
-
- var unit = self.traits.Get();
- var speed = .2f * Util.GetEffectiveSpeed(self);
- var angle = unit.Facing / 128f * Math.PI;
-
- self.CenterLocation += speed * -float2.FromAngle((float)angle);
- self.Location = ((1 / 24f) * self.CenterLocation).ToInt2();
-
- unit.Altitude += Math.Sign(targetAltitude - unit.Altitude);
- return this;
- }
-
- public void Cancel(Actor self) { remainingTicks = 0; NextActivity = null; }
- }
-
- class Circle : IActivity
- {
- public IActivity NextActivity { get; set; }
- bool isCanceled;
- readonly int2 Cell;
-
- public Circle(int2 cell) { Cell = cell; }
-
- public IActivity Tick(Actor self)
- {
- if (isCanceled) return NextActivity;
- var unit = self.traits.Get();
- return new Fly(Util.CenterOfCell(Cell))
- {
- NextActivity =
- new FlyTimed(50, 20)
- {
- NextActivity = this
- }
- };
- }
-
- public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
- }
-
- class ReturnToBase : IActivity
- {
- public IActivity NextActivity { get; set; }
- bool isCanceled;
-
- readonly float2 w1, w2, w3; /* tangent points to turn circles */
- readonly float2 landPoint;
-
- public ReturnToBase(Actor self, float2 landPos)
- {
- var unit = self.traits.Get();
- var speed = .2f * Util.GetEffectiveSpeed(self);
- var approachStart = landPos - new float2(unit.Altitude * speed, 0);
- var turnRadius = (128f / self.Info.ROT) * speed / (float)Math.PI;
-
- /* work out the center points */
- var fwd = -float2.FromAngle(unit.Facing / 128f * (float)Math.PI);
- var side = new float2(-fwd.Y, fwd.X); /* rotate */
- var sideTowardBase = new [] { side, -side }
- .OrderBy( a => float2.Dot( a, self.CenterLocation - approachStart ) )
- .First();
-
- var c1 = self.CenterLocation + turnRadius * sideTowardBase;
- var c2 = approachStart + new float2(0,
- turnRadius * Math.Sign( self.CenterLocation.Y - approachStart.Y )); // above or below start point
-
- /* work out tangent points */
- var d = c2 - c1;
- var e = (turnRadius / d.Length) * d;
- var f = new float2(-e.Y, e.X); /* rotate */
-
- /* todo: support internal tangents, too! */
-
- if (f.X > 0) f = -f;
-
- w1 = c1 + f;
- w2 = c2 + f;
- w3 = approachStart;
- landPoint = landPos;
- }
-
- public IActivity Tick(Actor self)
- {
- if (isCanceled) return NextActivity;
- var unit = self.traits.Get();
- return new Fly(w1)
- {
- NextActivity = new Fly(w2)
- {
- NextActivity = new Fly(w3)
- {
- NextActivity = new Land(landPoint)
- }
- }
- };
- }
-
- public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
- }
}
diff --git a/OpenRa.Game/Traits/Activities/FlyTimed.cs b/OpenRa.Game/Traits/Activities/FlyTimed.cs
new file mode 100644
index 0000000000..c498dd008b
--- /dev/null
+++ b/OpenRa.Game/Traits/Activities/FlyTimed.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenRa.Game.Traits.Activities
+{
+ class FlyTimed : IActivity
+ {
+ public IActivity NextActivity { get; set; }
+ int remainingTicks;
+ int targetAltitude;
+
+ public FlyTimed(int ticks, int targetAltitude) { remainingTicks = ticks; this.targetAltitude = targetAltitude; }
+
+ public IActivity Tick(Actor self)
+ {
+ if (remainingTicks == 0)
+ return NextActivity;
+
+ --remainingTicks;
+
+ var unit = self.traits.Get();
+ var speed = .2f * Util.GetEffectiveSpeed(self);
+ var angle = unit.Facing / 128f * Math.PI;
+
+ self.CenterLocation += speed * -float2.FromAngle((float)angle);
+ self.Location = ((1 / 24f) * self.CenterLocation).ToInt2();
+
+ unit.Altitude += Math.Sign(targetAltitude - unit.Altitude);
+ return this;
+ }
+
+ public void Cancel(Actor self) { remainingTicks = 0; NextActivity = null; }
+ }
+}
diff --git a/OpenRa.Game/Traits/Activities/Land.cs b/OpenRa.Game/Traits/Activities/Land.cs
new file mode 100644
index 0000000000..5c4cf06ea5
--- /dev/null
+++ b/OpenRa.Game/Traits/Activities/Land.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenRa.Game.Traits.Activities
+{
+ class Land : IActivity
+ {
+ readonly float2 Pos;
+ bool isCanceled;
+
+ public Land(float2 pos) { Pos = pos; }
+
+ public IActivity NextActivity { get; set; }
+
+ public IActivity Tick(Actor self)
+ {
+ if (isCanceled) return NextActivity;
+
+ var d = Pos - self.CenterLocation;
+ if (d.LengthSquared < 50) /* close enough */
+ return NextActivity;
+
+ var unit = self.traits.Get();
+
+ if (unit.Altitude > 0)
+ --unit.Altitude;
+
+ var desiredFacing = Util.GetFacing(d, unit.Facing);
+ Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT);
+ var speed = .2f * Util.GetEffectiveSpeed(self);
+ var angle = unit.Facing / 128f * Math.PI;
+
+ self.CenterLocation += speed * -float2.FromAngle((float)angle);
+ self.Location = ((1 / 24f) * self.CenterLocation).ToInt2();
+
+ return this;
+ }
+
+ public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
+ }
+}
diff --git a/OpenRa.Game/Traits/Activities/ReturnToBase.cs b/OpenRa.Game/Traits/Activities/ReturnToBase.cs
new file mode 100644
index 0000000000..ee7af24ef4
--- /dev/null
+++ b/OpenRa.Game/Traits/Activities/ReturnToBase.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenRa.Game.Traits.Activities
+{
+ class ReturnToBase : IActivity
+ {
+ public IActivity NextActivity { get; set; }
+ bool isCanceled;
+
+ readonly float2 w1, w2, w3; /* tangent points to turn circles */
+ readonly float2 landPoint;
+
+ public ReturnToBase(Actor self, float2 landPos)
+ {
+ var unit = self.traits.Get();
+ var speed = .2f * Util.GetEffectiveSpeed(self);
+ var approachStart = landPos - new float2(unit.Altitude * speed, 0);
+ var turnRadius = (128f / self.Info.ROT) * speed / (float)Math.PI;
+
+ /* work out the center points */
+ var fwd = -float2.FromAngle(unit.Facing / 128f * (float)Math.PI);
+ var side = new float2(-fwd.Y, fwd.X); /* rotate */
+ var sideTowardBase = new[] { side, -side }
+ .OrderBy(a => float2.Dot(a, self.CenterLocation - approachStart))
+ .First();
+
+ var c1 = self.CenterLocation + turnRadius * sideTowardBase;
+ var c2 = approachStart + new float2(0,
+ turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point
+
+ /* work out tangent points */
+ var d = c2 - c1;
+ var e = (turnRadius / d.Length) * d;
+ var f = new float2(-e.Y, e.X); /* rotate */
+
+ /* todo: support internal tangents, too! */
+
+ if (f.X > 0) f = -f;
+
+ w1 = c1 + f;
+ w2 = c2 + f;
+ w3 = approachStart;
+ landPoint = landPos;
+ }
+
+ public IActivity Tick(Actor self)
+ {
+ if (isCanceled) return NextActivity;
+ var unit = self.traits.Get();
+ return new Fly(w1)
+ {
+ NextActivity = new Fly(w2)
+ {
+ NextActivity = new Fly(w3)
+ {
+ NextActivity = new Land(landPoint)
+ }
+ }
+ };
+ }
+
+ public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
+ }
+}
diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs
index 640f9143d1..f916f05dc5 100755
--- a/OpenRa.Game/Traits/Production.cs
+++ b/OpenRa.Game/Traits/Production.cs
@@ -57,34 +57,4 @@ namespace OpenRa.Game.Traits
yield return (true) ? TagType.Primary : TagType.None;
}
}
-
- class ProductionSurround : Production
- {
- public ProductionSurround( Actor self ) : base( self ) { }
-
- static int2? FindAdjacentTile(Actor a, UnitMovementType umt)
- {
- var tiles = Footprint.Tiles(a, a.traits.Get());
- var min = tiles.Aggregate(int2.Min) - new int2(1, 1);
- var max = tiles.Aggregate(int2.Max) + new int2(1, 1);
-
- for (var j = min.Y; j <= max.Y; j++)
- for (var i = min.X; i <= max.X; i++)
- if (Game.IsCellBuildable(new int2(i, j), umt))
- return new int2(i, j);
-
- return null;
- }
-
- public override int2? CreationLocation( Actor self, UnitInfo producee )
- {
- return FindAdjacentTile( self, producee.WaterBound ?
- UnitMovementType.Float : UnitMovementType.Wheel); /* hackety hack */
- }
-
- public override int CreationFacing( Actor self, Actor newUnit )
- {
- return Util.GetFacing( newUnit.CenterLocation - self.CenterLocation, 128 );
- }
- }
}
diff --git a/OpenRa.Game/Traits/ProductionSurround.cs b/OpenRa.Game/Traits/ProductionSurround.cs
new file mode 100644
index 0000000000..4fb0091697
--- /dev/null
+++ b/OpenRa.Game/Traits/ProductionSurround.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenRa.Game.GameRules;
+
+namespace OpenRa.Game.Traits
+{
+ class ProductionSurround : Production
+ {
+ public ProductionSurround(Actor self) : base(self) { }
+
+ static int2? FindAdjacentTile(Actor a, UnitMovementType umt)
+ {
+ var tiles = Footprint.Tiles(a, a.traits.Get());
+ var min = tiles.Aggregate(int2.Min) - new int2(1, 1);
+ var max = tiles.Aggregate(int2.Max) + new int2(1, 1);
+
+ for (var j = min.Y; j <= max.Y; j++)
+ for (var i = min.X; i <= max.X; i++)
+ if (Game.IsCellBuildable(new int2(i, j), umt))
+ return new int2(i, j);
+
+ return null;
+ }
+
+ public override int2? CreationLocation(Actor self, UnitInfo producee)
+ {
+ return FindAdjacentTile(self, producee.WaterBound ?
+ UnitMovementType.Float : UnitMovementType.Wheel); /* hackety hack */
+ }
+
+ public override int CreationFacing(Actor self, Actor newUnit)
+ {
+ return Util.GetFacing(newUnit.CenterLocation - self.CenterLocation, 128);
+ }
+ }
+}