Skip to content

Commit

Permalink
Make AutoCrusher aware of Cloak and Disguise
Browse files Browse the repository at this point in the history
  • Loading branch information
abcdefg30 authored and PunkPun committed Oct 13, 2023
1 parent 72bb6c4 commit 1dc14ed
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions OpenRA.Mods.Common/Traits/AutoCrusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ sealed class AutoCrusher : PausableConditionalTrait<AutoCrusherInfo>, INotifyIdl
int nextScanTime;
readonly IMoveInfo moveInfo;
readonly bool isAircraft;
readonly bool ignoresDisguise;
readonly IMove move;

public AutoCrusher(Actor self, AutoCrusherInfo info)
Expand All @@ -50,19 +51,16 @@ public AutoCrusher(Actor self, AutoCrusherInfo info)
moveInfo = self.Info.TraitInfo<IMoveInfo>();
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
isAircraft = move is Aircraft;
ignoresDisguise = self.Info.HasTraitInfo<IgnoresDisguiseInfo>();
}

void INotifyIdle.TickIdle(Actor self)
{
if (nextScanTime-- > 0)
return;

// TODO: Add a proper Cloak and Disguise detection here.
var crushableActor = self.World.FindActorsInCircle(self.CenterPosition, Info.ScanRadius)
.Where(a => a != self && !a.IsDead && a.IsInWorld &&
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)))
.Where(a => IsValidCrushTarget(self, a))
.ClosestToWithPathFrom(self);

if (crushableActor == null)
Expand All @@ -75,5 +73,27 @@ void INotifyIdle.TickIdle(Actor self)

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));
}
}
}

0 comments on commit 1dc14ed

Please sign in to comment.