diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index 4f0bfbeb1e..20ad6b77ee 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -143,6 +143,7 @@
+
diff --git a/OpenRa.Game/Traits/Activities/Repair.cs b/OpenRa.Game/Traits/Activities/Repair.cs
new file mode 100644
index 0000000000..fa3019f5bc
--- /dev/null
+++ b/OpenRa.Game/Traits/Activities/Repair.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenRa.Game.Traits.Activities
+{
+ class Repair : IActivity
+ {
+ public IActivity NextActivity { get; set; }
+ bool isCanceled;
+ int remainingTicks = ticksPerPoint;
+
+ const int ticksPerPoint = 15;
+ const int hpPerPoint = 8;
+
+ public IActivity Tick(Actor self)
+ {
+ if (isCanceled) return NextActivity;
+ if (--remainingTicks == 0)
+ {
+ self.Health += hpPerPoint;
+ if (self.Health >= self.Info.Strength)
+ {
+ self.Health = self.Info.Strength;
+ return NextActivity;
+ }
+
+ var hostBuilding = Game.FindUnits(self.CenterLocation, self.CenterLocation)
+ .FirstOrDefault(a => a.traits.Contains());
+
+ if (hostBuilding != null)
+ hostBuilding.traits.Get().PlayCustomAnim(hostBuilding, "active" );
+
+ remainingTicks = ticksPerPoint;
+ }
+
+ return this;
+ }
+
+ public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
+ }
+}