Make AutoCrusher aware of Cloak and Disguise
This commit is contained in:
@@ -41,6 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
int nextScanTime;
|
int nextScanTime;
|
||||||
readonly IMoveInfo moveInfo;
|
readonly IMoveInfo moveInfo;
|
||||||
readonly bool isAircraft;
|
readonly bool isAircraft;
|
||||||
|
readonly bool ignoresDisguise;
|
||||||
readonly IMove move;
|
readonly IMove move;
|
||||||
|
|
||||||
public AutoCrusher(Actor self, AutoCrusherInfo info)
|
public AutoCrusher(Actor self, AutoCrusherInfo info)
|
||||||
@@ -50,6 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
moveInfo = self.Info.TraitInfo<IMoveInfo>();
|
moveInfo = self.Info.TraitInfo<IMoveInfo>();
|
||||||
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
|
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
|
||||||
isAircraft = move is Aircraft;
|
isAircraft = move is Aircraft;
|
||||||
|
ignoresDisguise = self.Info.HasTraitInfo<IgnoresDisguiseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyIdle.TickIdle(Actor self)
|
void INotifyIdle.TickIdle(Actor self)
|
||||||
@@ -57,12 +59,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (nextScanTime-- > 0)
|
if (nextScanTime-- > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Add a proper Cloak and Disguise detection here.
|
|
||||||
var crushableActor = self.World.FindActorsInCircle(self.CenterPosition, Info.ScanRadius)
|
var crushableActor = self.World.FindActorsInCircle(self.CenterPosition, Info.ScanRadius)
|
||||||
.Where(a => a != self && !a.IsDead && a.IsInWorld &&
|
.Where(a => IsValidCrushTarget(self, a))
|
||||||
self.Location != a.Location && a.IsAtGroundLevel() &&
|
|
||||||
Info.TargetRelationships.HasRelationship(self.Owner.RelationshipWith(a.Owner)) &&
|
|
||||||
a.TraitsImplementing<ICrushable>().Any(c => c.CrushableBy(a, self, Info.CrushClasses)))
|
|
||||||
.ClosestToWithPathFrom(self);
|
.ClosestToWithPathFrom(self);
|
||||||
|
|
||||||
if (crushableActor == null)
|
if (crushableActor == null)
|
||||||
@@ -75,5 +73,27 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
|
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsValidCrushTarget(Actor self, Actor target)
|
||||||
|
{
|
||||||
|
if (target == self || target.IsDead || !target.IsInWorld || self.Location != target.Location || !target.IsAtGroundLevel())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var targetRelationship = self.Owner.RelationshipWith(target.Owner);
|
||||||
|
var effectiveOwner = target.EffectiveOwner?.Owner;
|
||||||
|
if (effectiveOwner != null && !ignoresDisguise && targetRelationship != PlayerRelationship.Ally)
|
||||||
|
{
|
||||||
|
// Check effective relationships if the target is disguised and we cannot see through the disguise. (By ignoring it or by being an ally.)
|
||||||
|
if (!Info.TargetRelationships.HasRelationship(self.Owner.RelationshipWith(effectiveOwner)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!Info.TargetRelationships.HasRelationship(targetRelationship))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target.TraitsImplementing<Cloak>().Any(c => !c.IsTraitDisabled && !c.IsVisible(target, self.Owner)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return target.TraitsImplementing<ICrushable>().Any(c => c.CrushableBy(target, self, Info.CrushClasses));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user