Added ProximityCaptor and filtering of possible captors for KOTH
This commit is contained in:
@@ -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<ProximityCaptor>() && a.Trait<ProximityCaptor>().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<ProximityCaptor>() && a.Trait<ProximityCaptor>().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<ProximityCaptor>() && a.Trait<ProximityCaptor>().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<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.Select(a => a.Owner)
|
||||
.Distinct()
|
||||
.Count();
|
||||
|
||||
Reference in New Issue
Block a user