diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index 2463f7b8d6..4a421431f5 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -106,6 +106,7 @@
+
diff --git a/OpenRA.Mods.RA/ProximityCaptor.cs b/OpenRA.Mods.RA/ProximityCaptor.cs
new file mode 100644
index 0000000000..020106f5ba
--- /dev/null
+++ b/OpenRA.Mods.RA/ProximityCaptor.cs
@@ -0,0 +1,48 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation. For more information,
+ * see LICENSE.
+ */
+#endregion
+
+using System.Linq;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.RA
+{
+ public class ProximityCaptorInfo : ITraitInfo
+ {
+ public readonly string[] Types = {};
+ public object Create(ActorInitializer init) { return new ProximityCaptor(this); }
+ }
+
+ public class ProximityCaptor
+ {
+ public readonly ProximityCaptorInfo Info;
+
+ public string[] Types;
+
+ [Sync]
+ public int Hash { get { return string.Join(",", Types).GetHashCode(); } }
+
+ public ProximityCaptor(ProximityCaptorInfo info)
+ {
+ Info = info;
+
+ Types = info.Types.Select(t => t.ToLowerInvariant()).OrderBy(t => t).ToArray();
+ }
+
+ public bool HasAny(string[] typesList)
+ {
+ return typesList.Select(t => t.ToLowerInvariant()).Any(flag => Types.Contains(flag));
+ }
+
+ public bool HasAll(string[] typesList)
+ {
+ return typesList.Select(t => t.ToLowerInvariant()).All(flag => Types.Contains(flag));
+ }
+ }
+}
diff --git a/OpenRA.Mods.RA/ProximityCapturable.cs b/OpenRA.Mods.RA/ProximityCapturable.cs
index 7b7fd37c51..55b2f6c537 100644
--- a/OpenRA.Mods.RA/ProximityCapturable.cs
+++ b/OpenRA.Mods.RA/ProximityCapturable.cs
@@ -9,6 +9,7 @@ namespace OpenRA.Mods.RA
public readonly bool Permanent = false;
public readonly int Range = 5;
public readonly bool MustBeClear = false;
+ public readonly string[] CaptorTypes = {"Vehicle", "Tank", "Infantry"};
public object Create(ActorInitializer init) { return new ProximityCapturable(init.self, this); }
}
@@ -35,6 +36,13 @@ namespace OpenRA.Mods.RA
[Sync]
public bool MustBeClear = false;
+ public string[] CaptorTypes = {};
+
+ [Sync]
+ public int ActorTypesHash
+ {
+ get { return string.Join(",", CaptorTypes).GetHashCode(); }
+ }
public Actor Self;
public ProximityCapturable(Actor self, ProximityCapturableInfo info)
@@ -45,6 +53,7 @@ namespace OpenRA.Mods.RA
MustBeClear = info.MustBeClear;
Self = self;
OriginalOwner = self.Owner;
+ CaptorTypes = info.CaptorTypes;
}
public void Tick(Actor self)
@@ -55,11 +64,11 @@ namespace OpenRA.Mods.RA
if (!Captured)
{
- var captor = GetInRange(self, OriginalOwner, Range);
+ var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
if (captor != null)
{
- if (MustBeClear && !IsClear(self, captor.Owner, Range, OriginalOwner)) return;
+ if (MustBeClear && !IsClear(self, captor.Owner, Range, OriginalOwner, CaptorTypes)) return;
ChangeOwnership(self, captor, OriginalOwner);
}
@@ -68,7 +77,7 @@ namespace OpenRA.Mods.RA
}
// if the area must be clear, and there is more than 1 player nearby => return ownership to default
- if (MustBeClear && !IsClear(self, Owner, Range, OriginalOwner))
+ if (MustBeClear && !IsClear(self, Owner, Range, OriginalOwner, CaptorTypes))
{
// Revert Ownership
ChangeOwnership(self, Owner, OriginalOwner);
@@ -76,10 +85,10 @@ namespace OpenRA.Mods.RA
}
// See if the 'temporary' owner still is in range
- if (!IsStillInRange(self, self.Owner, Range))
+ if (!IsStillInRange(self, self.Owner, Range, CaptorTypes))
{
// no.. So find a new one
- var captor = GetInRange(self, OriginalOwner, Range);
+ var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
if (captor != null) // got one
{
@@ -140,26 +149,29 @@ namespace OpenRA.Mods.RA
b.Stances[a] == Stance.Ally;
}
- public static bool IsClear(Actor self, Player currentOwner, int range, Player originalOwner)
+ public static bool IsClear(Actor self, Player currentOwner, int range, Player originalOwner, string[] actorTypes)
{
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
-
+
return unitsInRange.Where(a => !a.Destroyed && a.IsInWorld && a != self && !a.Owner.NonCombatant && a.Owner != originalOwner)
- .Where(a => a.Owner != currentOwner).All(a => AreMutualAllies(a.Owner, currentOwner));
+ .Where(a => a.Owner != currentOwner)
+ .Where(a => actorTypes.Length == 0 || (a.HasTrait() && a.Trait().HasAny(actorTypes)))
+ .All(a => AreMutualAllies(a.Owner, currentOwner));
}
// TODO exclude other NeutralActor that arent permanent
- public static bool IsStillInRange(Actor self, Player currentOwner, int range)
+ public static bool IsStillInRange(Actor self, Player currentOwner, int range, string[] actorTypes)
{
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
return unitsInRange
.Where(a => a.Owner == currentOwner && !a.Destroyed && a.IsInWorld && a != self)
+ .Where(a => actorTypes.Length == 0 || (a.HasTrait() && a.Trait().HasAny(actorTypes)))
.Any();
}
// TODO exclude other NeutralActor that arent permanent
- public static Actor GetInRange(Actor self, Player originalOwner, int range)
+ public static Actor GetInRange(Actor self, Player originalOwner, int range, string[] actorTypes)
{
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
@@ -167,11 +179,12 @@ namespace OpenRA.Mods.RA
.Where(a => a.Owner != originalOwner && !a.Destroyed && a.IsInWorld && a != self)
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
.Where(a => !a.Owner.PlayerRef.NonCombatant)
+ .Where(a => actorTypes.Length == 0 || (a.HasTrait() && a.Trait().HasAny(actorTypes)))
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
.FirstOrDefault();
}
- public static int CountPlayersNear(Actor self, Player ignoreMe, int range)
+ public static int CountPlayersNear(Actor self, Player ignoreMe, int range, string[] actorTypes)
{
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
@@ -179,6 +192,7 @@ namespace OpenRA.Mods.RA
.Where(a => a.Owner != ignoreMe && !a.Destroyed && a.IsInWorld && a != self)
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
.Where(a => !a.Owner.PlayerRef.NonCombatant)
+ .Where(a =>actorTypes.Length == 0 || ( a.HasTrait() && a.Trait().HasAny(actorTypes)))
.Select(a => a.Owner)
.Distinct()
.Count();
diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml
index b9ef110dcd..46b467f237 100644
--- a/mods/cnc/rules/defaults.yaml
+++ b/mods/cnc/rules/defaults.yaml
@@ -28,6 +28,8 @@
ActorLostNotification:
Notification: unitlost.aud
AttackMove:
+ ProximityCaptor:
+ Types:Vehicle
^Tank:
AppearsOnRadar:
@@ -59,6 +61,8 @@
ActorLostNotification:
Notification: unitlost.aud
AttackMove:
+ ProximityCaptor:
+ Types:Tank
^Helicopter:
AppearsOnRadar:
@@ -79,6 +83,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlost.aud
+ ProximityCaptor:
+ Types:Helicopter
^Infantry:
AppearsOnRadar:
@@ -118,6 +124,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlost.aud
+ ProximityCaptor:
+ Types:Infantry
^CivInfantry:
Inherits: ^Infantry
@@ -141,6 +149,8 @@
# ActorLostNotification:
# Notification: civdead1.aud
# NotifyAll: true
+ ProximityCaptor:
+ Types:CivilianInfantry
^Plane:
AppearsOnRadar:
@@ -155,6 +165,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlost.aud
+ ProximityCaptor:
+ Types:Plane
^Ship:
AppearsOnRadar:
@@ -173,6 +185,8 @@
ActorLostNotification:
Notification: unitlost.aud
AttackMove:
+ ProximityCaptor:
+ Types:Ship
^Building:
AppearsOnRadar:
@@ -211,6 +225,8 @@
EditorAppearance:
RelativeToTopLeft: yes
ShakeOnDeath:
+ ProximityCaptor:
+ Types:Building
^CivBuilding:
Inherits: ^Building
@@ -226,6 +242,8 @@
# -FrozenUnderFog:
Tooltip:
Name: Civilian Building
+ ProximityCaptor:
+ Types:CivilianBuilding
^CivField:
Inherits: ^CivBuilding
@@ -237,6 +255,9 @@
RenderBuilding:
OverrideTileset: DESERT
OverrideImage: v23
+ -ProximityCaptor:
+ ProximityCaptor:
+ Types:CivilianField
^Wall:
AppearsOnRadar:
@@ -263,6 +284,8 @@
EditorAppearance:
RelativeToTopLeft: yes
AutoTargetIgnore:
+ ProximityCaptor:
+ Types:Wall
^Tree:
Tooltip:
@@ -277,6 +300,8 @@
Terrain: Tree
EditorAppearance:
RelativeToTopLeft: yes
+ ProximityCaptor:
+ Types:Tree
^Rock:
Tooltip:
@@ -291,6 +316,8 @@
Terrain: Tree
EditorAppearance:
RelativeToTopLeft: yes
+ ProximityCaptor:
+ Types:Rock
^Husk:
Health:
@@ -303,6 +330,8 @@
HiddenUnderFog:
AppearsOnRadar:
Burns:
+ ProximityCaptor:
+ Types:Husk
^Bridge:
Tooltip:
@@ -318,3 +347,5 @@
Building:
Footprint: ______ ______ ______ ______
Dimensions: 6,4
+ ProximityCaptor:
+ Types:Bridge
diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml
index b629ba35d7..c8c4cf19d7 100644
--- a/mods/cnc/rules/system.yaml
+++ b/mods/cnc/rules/system.yaml
@@ -191,3 +191,5 @@ CRATE:
Unit: mcv
RenderUnit:
BelowUnits:
+ ProximityCaptor:
+ Types:Crate
diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml
index d8f9b5fc4f..9693cbcae1 100644
--- a/mods/ra/rules/defaults.yaml
+++ b/mods/ra/rules/defaults.yaml
@@ -25,7 +25,9 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlst1.aud
-
+ ProximityCaptor:
+ Types:Vehicle
+
^Tank:
AppearsOnRadar:
Mobile:
@@ -53,6 +55,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlst1.aud
+ ProximityCaptor:
+ Types:Tank
^Infantry:
AppearsOnRadar:
@@ -87,6 +91,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: unitlst1.aud
+ ProximityCaptor:
+ Types:Infantry
^Ship:
AppearsOnRadar:
@@ -107,6 +113,8 @@
DrawLineToTarget:
ActorLostNotification:
Notification: navylst1.aud
+ ProximityCaptor:
+ Types:Ship
^Plane:
AppearsOnRadar:
@@ -122,10 +130,13 @@
DrawLineToTarget:
ActorLostNotification:
Notification: aunitl1.aud
+<<<<<<< HEAD
DebugAircraftFacing:
DebugAircraftSubPxX:
DebugAircraftSubPxY:
DebugAircraftAltitude:
+ ProximityCaptor:
+ Types:Plane
^Building:
AppearsOnRadar:
@@ -151,6 +162,8 @@
EditorAppearance:
RelativeToTopLeft: yes
ShakeOnDeath:
+ ProximityCaptor:
+ Types:Building
^Wall:
AppearsOnRadar:
@@ -179,6 +192,8 @@
EditorAppearance:
RelativeToTopLeft: yes
AutoTargetIgnore:
+ ProximityCaptor:
+ Types:Wall
^CivBuilding:
Inherits: ^Building
@@ -189,12 +204,17 @@
Type: Wood
Tooltip:
Name: Civilian Building
+ ProximityCaptor:
+ Types:CivilianBuilding
^CivField:
Inherits: ^CivBuilding
-Selectable:
Tooltip:
Name: Field
+ -ProximityCaptor:
+ ProximityCaptor:
+ Types:CivilianField
^Tree:
Tooltip:
@@ -209,6 +229,8 @@
Terrain: Tree
EditorAppearance:
RelativeToTopLeft: yes
+ ProximityCaptor:
+ Types:Tree
^Husk:
Health:
@@ -221,6 +243,8 @@
HiddenUnderFog:
AppearsOnRadar:
Burns:
+ ProximityCaptor:
+ Types:Husk
^Bridge:
Tooltip:
@@ -233,3 +257,5 @@
Dimensions: 4,2
Health:
HP: 1000
+ ProximityCaptor:
+ Types:Bridge
diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml
index 0c6f5459ad..2cba4773ca 100644
--- a/mods/ra/rules/infantry.yaml
+++ b/mods/ra/rules/infantry.yaml
@@ -281,6 +281,9 @@ C1:
Range: 2
AttackFrontal:
PrimaryWeapon: Pistol
+ -ProximityCaptor:
+ ProximityCaptor:
+ Types:CivilianInfantry
C2:
Inherits: ^Infantry
@@ -299,6 +302,9 @@ C2:
Range: 2
AttackFrontal:
PrimaryWeapon: Pistol
+ -ProximityCaptor:
+ ProximityCaptor:
+ Types:CivilianInfantry
SHOK:
Inherits: ^Infantry
diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml
index ec7a139aaf..3a9d0ca1e8 100644
--- a/mods/ra/rules/system.yaml
+++ b/mods/ra/rules/system.yaml
@@ -208,6 +208,8 @@ MINP:
InvisibleToOthers:
Tooltip:
Name: Anti-Personnel Mine
+ ProximityCaptor:
+ Types:Mine
MINV:
Mine:
@@ -221,6 +223,8 @@ MINV:
InvisibleToOthers:
Tooltip:
Name: Anti-Tank Mine
+ ProximityCaptor:
+ Types:Mine
CRATE:
Tooltip:
@@ -279,13 +283,17 @@ CRATE:
Unit: 4tnk
RenderUnit:
BelowUnits:
+ ProximityCaptor:
+ Types:Crate
CAMERA:
Aircraft:
Health:
HP:1000
RevealsShroud:
- Range: 10
+ Range: 10
+ ProximityCaptor:
+ Types:Camera
FLARE:
Aircraft:
@@ -298,6 +306,8 @@ FLARE:
HiddenUnderFog:
Tooltip:
Name: Flare
+ ProximityCaptor:
+ Types: Flare
powerproxy.parabombs:
AirstrikePower:
@@ -318,4 +328,4 @@ powerproxy.sonarpulse:
AllowMultiple: yes
OneShot: yes
EndChargeSound: pulse1.aud
- SelectTargetSound: slcttgt1.aud
\ No newline at end of file
+ SelectTargetSound: slcttgt1.aud