diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index ac5b98c520..f38d139888 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -205,8 +205,7 @@
-
-
+
diff --git a/OpenRa.Game/Traits/APMine.cs b/OpenRa.Game/Traits/APMine.cs
deleted file mode 100644
index 4d443321ed..0000000000
--- a/OpenRa.Game/Traits/APMine.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Collections.Generic;
-using OpenRa.Game.Effects;
-
-namespace OpenRa.Game.Traits
-{
- class APMineInfo : ITraitInfo
- {
- public object Create(Actor self) { return new APMine(self); }
- }
-
- class APMine : ICrushable, IOccupySpace
- {
- readonly Actor self;
- public APMine(Actor self)
- {
- this.self = self;
- Game.UnitInfluence.Add(self, this);
- }
-
- public void OnCrush(Actor crusher)
- {
- if (crusher.traits.Contains() && crusher.Owner == self.Owner)
- return;
-
- Game.world.AddFrameEndTask(_ =>
- {
- Game.world.Remove(self);
- Game.world.Add(new Explosion(self.CenterLocation.ToInt2(), 5, false));
- crusher.InflictDamage(crusher, Rules.General.APMineDamage, Rules.WarheadInfo["APMine"]);
- });
- }
-
- public bool IsPathableCrush(UnitMovementType umt, Player player)
- {
- return (player != Game.LocalPlayer); // Units should avoid friendly mines
- }
-
- public bool IsCrushableBy(UnitMovementType umt, Player player)
- {
- // Mines should explode indiscriminantly of player
- switch (umt)
- {
- case UnitMovementType.Foot:
- case UnitMovementType.Wheel:
- case UnitMovementType.Track:
- return true;
-
- default: return false;
- }
- }
-
- public IEnumerable OccupiedCells() { yield return self.Location; }
- }
-}
diff --git a/OpenRa.Game/Traits/ATMine.cs b/OpenRa.Game/Traits/ATMine.cs
deleted file mode 100644
index 0a0bcda360..0000000000
--- a/OpenRa.Game/Traits/ATMine.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System.Collections.Generic;
-using OpenRa.Game.Effects;
-
-namespace OpenRa.Game.Traits
-{
- class ATMineInfo : ITraitInfo
- {
- public object Create(Actor self) { return new ATMine(self); }
- }
-
- class ATMine : ICrushable, IOccupySpace
- {
- readonly Actor self;
- public ATMine(Actor self)
- {
- this.self = self;
- Game.UnitInfluence.Add(self, this);
- }
-
- public void OnCrush(Actor crusher)
- {
- if (crusher.traits.Contains() && crusher.Owner == self.Owner)
- return;
-
- Game.world.AddFrameEndTask(_ =>
- {
- Game.world.Remove(self);
- Game.world.Add(new Explosion(self.CenterLocation.ToInt2(), 3, false));
- crusher.InflictDamage(crusher, Rules.General.AVMineDamage, Rules.WarheadInfo["ATMine"]);
- });
- }
-
- public bool IsPathableCrush(UnitMovementType umt, Player player)
- {
- return (player != Game.LocalPlayer); // Units should avoid friendly mines
- }
-
- public bool IsCrushableBy(UnitMovementType umt, Player player)
- {
- // Mines should explode indiscriminantly of player
- switch (umt)
- {
- case UnitMovementType.Wheel:
- case UnitMovementType.Track: return true;
- default: return false;
- }
- }
-
- public IEnumerable OccupiedCells() { yield return self.Location; }
- }
-}
diff --git a/OpenRa.Game/Traits/Mine.cs b/OpenRa.Game/Traits/Mine.cs
new file mode 100644
index 0000000000..c73d5b1ff6
--- /dev/null
+++ b/OpenRa.Game/Traits/Mine.cs
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using System.Linq;
+using OpenRa.Game.Effects;
+
+namespace OpenRa.Game.Traits
+{
+ class MineInfo : ITraitInfo
+ {
+ public readonly int Damage = 0;
+ public readonly UnitMovementType[] TriggeredBy = { };
+ public readonly string Warhead = "ATMine";
+ public readonly bool AvoidFriendly = true;
+
+ public object Create(Actor self) { return new Mine(self); }
+ }
+
+ class Mine : ICrushable, IOccupySpace
+ {
+ readonly Actor self;
+ public Mine(Actor self)
+ {
+ this.self = self;
+ Game.UnitInfluence.Add(self, this);
+ }
+
+ public void OnCrush(Actor crusher)
+ {
+ if (crusher.traits.Contains() && crusher.Owner == self.Owner)
+ return;
+
+ var info = self.Info.Traits.Get();
+ var warhead = Rules.WarheadInfo[info.Warhead];
+
+ Game.world.AddFrameEndTask(_ =>
+ {
+ Game.world.Remove(self);
+ Game.world.Add(new Explosion(self.CenterLocation.ToInt2(), warhead.Explosion, false));
+ crusher.InflictDamage(crusher, info.Damage, warhead);
+ });
+ }
+
+ public bool IsPathableCrush(UnitMovementType umt, Player player)
+ {
+ return !self.Info.Traits.Get().AvoidFriendly || (player != Game.LocalPlayer);
+ }
+
+ public bool IsCrushableBy(UnitMovementType umt, Player player)
+ {
+ return self.Info.Traits.Get().TriggeredBy.Contains(umt);
+ }
+
+ public IEnumerable OccupiedCells() { yield return self.Location; }
+ }
+}
diff --git a/merge-ra.yaml b/merge-ra.yaml
index 6504564f5a..0fcdddcbfb 100644
--- a/merge-ra.yaml
+++ b/merge-ra.yaml
@@ -12,3 +12,17 @@ MGG:
GAP:
GeneratesGap:
Range: 10
+
+MINP:
+ Mine:
+ Damage: 1000
+ Warhead: APMine
+ TriggeredBy: Foot, Wheel, Track
+ AvoidFriendly: yes
+
+MINV:
+ Mine:
+ Damage: 1200
+ Warhead: ATMine
+ TriggeredBy: Wheel, Track
+ AvoidFriendly: yes
\ No newline at end of file
diff --git a/ra.yaml b/ra.yaml
index 4b8fafd2b0..09b243261e 100644
--- a/ra.yaml
+++ b/ra.yaml
@@ -51,6 +51,36 @@ GAP:
RenderBuilding:
IronCurtainable:
+MINP:
+ Mine:
+ Damage: 1000
+ Warhead: APMine
+ TriggeredBy: Foot, Wheel, Track
+ AvoidFriendly: yes
+ Inherits: ^Building
+ Unit:
+ HP: 1
+ RenderUnit:
+ BelowUnits:
+ InvisibleToOthers:
+ -Selectable:
+ -Building:
+
+MINV:
+ Mine:
+ Damage: 1200
+ Warhead: ATMine
+ TriggeredBy: Wheel, Track
+ AvoidFriendly: yes
+ Inherits: ^Building
+ Unit:
+ HP: 1
+ RenderUnit:
+ BelowUnits:
+ InvisibleToOthers:
+ -Selectable:
+ -Building:
+
V2RL:
Inherits: ^Vehicle
Buildable:
@@ -1403,28 +1433,6 @@ DOMF:
Image: DOME
Fake:
-MINP:
- Inherits: ^Building
- Unit:
- HP: 1
- RenderUnit:
- APMine:
- BelowUnits:
- InvisibleToOthers:
- -Selectable:
- -Building:
-
-MINV:
- Inherits: ^Building
- Unit:
- HP: 1
- RenderUnit:
- ATMine:
- BelowUnits:
- InvisibleToOthers:
- -Selectable:
- -Building:
-
T01:
Inherits: ^Building
Building:
diff --git a/units.ini b/units.ini
index ca8f915bcf..85717ccbdf 100644
--- a/units.ini
+++ b/units.ini
@@ -526,11 +526,11 @@ LongDesc=Looks like a Radar Dome
[MINV]
-Traits=Unit,RenderUnit,ATMine,BelowUnits,InvisibleToOthers
+Traits=Unit,RenderUnit,BelowUnits,InvisibleToOthers
Selectable=no
[MINP]
-Traits=Unit,RenderUnit,APMine,BelowUnits,InvisibleToOthers
+Traits=Unit,RenderUnit,BelowUnits,InvisibleToOthers
Selectable=no
[InfantryTypes]