Skip to content

Commit

Permalink
Fix ProximityExternalCondition ignoring the owner change event
Browse files Browse the repository at this point in the history
  • Loading branch information
PunkPun committed Aug 3, 2023
1 parent d217ab3 commit b783c9a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
8 changes: 7 additions & 1 deletion OpenRA.Mods.Common/Traits/Conditions/ExternalCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class ExternalConditionInfo : TraitInfo
public override object Create(ActorInitializer init) { return new ExternalCondition(this); }
}

public class ExternalCondition : ITick, INotifyCreated
public class ExternalCondition : ITick, INotifyCreated, INotifyOwnerChanged
{
readonly struct TimedToken
{
Expand Down Expand Up @@ -222,6 +222,12 @@ void ITick.Tick(Actor self)

bool Notifies(IConditionTimerWatcher watcher) { return watcher.Condition == Info.Condition; }

void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
foreach (var pair in self.World.ActorsWithTrait<INotifyProximityOwnerChanged>())
pair.Trait.OnProximityOwnerChanged(self, oldOwner, newOwner);
}

void INotifyCreated.Created(Actor self)
{
watchers = self.TraitsImplementing<IConditionTimerWatcher>().Where(Notifies).ToArray();
Expand Down
42 changes: 36 additions & 6 deletions OpenRA.Mods.Common/Traits/Conditions/ProximityExternalCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class ProximityExternalConditionInfo : ConditionalTraitInfo
public override object Create(ActorInitializer init) { return new ProximityExternalCondition(init.Self, this); }
}

public class ProximityExternalCondition : ConditionalTrait<ProximityExternalConditionInfo>, ITick, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyOtherProduction
public class ProximityExternalCondition : ConditionalTrait<ProximityExternalConditionInfo>, ITick, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyOtherProduction, INotifyProximityOwnerChanged
{
readonly Actor self;

Expand Down Expand Up @@ -123,19 +123,18 @@ void ActorEntered(Actor a)

public void UnitProducedByOther(Actor self, Actor producer, Actor produced, string productionType, TypeDictionary init)
{
// If the produced Actor doesn't occupy space, it can't be in range
// If the produced Actor doesn't occupy space, it can't be in range.
if (produced.OccupiesSpace == null)
return;

// We don't grant conditions when disabled
// We don't grant conditions when disabled.
if (IsTraitDisabled)
return;

// Work around for actors produced within the region not triggering until the second tick
// Work around for actors produced within the region not triggering until the second tick.
if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= Info.Range.LengthSquared)
{
var stance = self.Owner.RelationshipWith(produced.Owner);
if (!Info.ValidRelationships.HasRelationship(stance))
if (!Info.ValidRelationships.HasRelationship(self.Owner.RelationshipWith(produced.Owner)))
return;

var external = produced.TraitsImplementing<ExternalCondition>()
Expand All @@ -159,5 +158,36 @@ void ActorExited(Actor a)
if (external.TryRevokeCondition(a, self, token))
break;
}

void INotifyProximityOwnerChanged.OnProximityOwnerChanged(Actor actor, Player oldOwner, Player newOwner)
{
// If the Actor doesn't occupy space, it can't be in range.
if (actor.OccupiesSpace == null)
return;

// We don't grant conditions when disabled.
if (IsTraitDisabled)
return;

// Work around for actors changin owner within the region.
if ((actor.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= Info.Range.LengthSquared)
{
var hasRelationship = Info.ValidRelationships.HasRelationship(self.Owner.RelationshipWith(actor.Owner));
var contains = tokens.TryGetValue(actor, out var token);
if (hasRelationship && !contains)
{
var external = actor.TraitsImplementing<ExternalCondition>().FirstOrDefault(t => t.Info.Condition == Info.Condition && t.CanGrantCondition(self));
if (external != null)
tokens[actor] = external.GrantCondition(actor, self);
}
else if (!hasRelationship && contains)
{
tokens.Remove(actor);
foreach (var external in actor.TraitsImplementing<ExternalCondition>())
if (external.TryRevokeCondition(actor, self, token))
break;
}
}
}
}
}
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/TraitsInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public interface INotifyParachute { void OnParachute(Actor self); void OnLanded(

[RequireExplicitImplementation]
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet<CaptureType> captureTypes); }
public interface INotifyProximityOwnerChanged { void OnProximityOwnerChanged(Actor actor, Player oldOwner, Player newOwner); }
public interface INotifyDiscovered { void OnDiscovered(Actor self, Player discoverer, bool playNotification); }
public interface IRenderActorPreviewInfo : ITraitInfoInterface { IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init); }
public interface ICruiseAltitudeInfo : ITraitInfoInterface { WDist GetCruiseAltitude(); }
Expand Down

0 comments on commit b783c9a

Please sign in to comment.