Move ValidRelations from Capturable to Captures
To better match weapon definitions
This commit is contained in:
committed by
Matthias Mailänder
parent
161f4cbdff
commit
5cc59ae3ac
@@ -38,32 +38,21 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Should units friendly to the capturing actor auto-target this actor while it is being captured?")]
|
||||
public readonly bool PreventsAutoTarget = true;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new CaptureManager(this); }
|
||||
|
||||
public bool CanBeTargetedBy(FrozenActor frozenActor, Actor captor, Captures captures)
|
||||
{
|
||||
if (captures.IsTraitDisabled)
|
||||
return false;
|
||||
|
||||
// TODO: FrozenActors don't yet have a way of caching conditions, so we can't filter disabled traits
|
||||
// This therefore assumes that all Capturable traits are enabled, which is probably wrong.
|
||||
// Actors with FrozenUnderFog should therefore not disable the Capturable trait.
|
||||
var stance = captor.Owner.RelationshipWith(frozenActor.Owner);
|
||||
return frozenActor.Info.TraitInfos<CapturableInfo>()
|
||||
.Any(c => c.ValidRelationships.HasRelationship(stance) && captures.Info.CaptureTypes.Overlaps(c.Types));
|
||||
}
|
||||
public override object Create(ActorInitializer init) { return new CaptureManager(init.Self, this); }
|
||||
}
|
||||
|
||||
public class CaptureManager : INotifyCreated, INotifyCapture, ITick, IDisableEnemyAutoTarget
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly CaptureManagerInfo info;
|
||||
|
||||
IMove move;
|
||||
ICaptureProgressWatcher[] progressWatchers;
|
||||
|
||||
BitSet<CaptureType> allyCapturableTypes;
|
||||
BitSet<CaptureType> neutralCapturableTypes;
|
||||
BitSet<CaptureType> enemyCapturableTypes;
|
||||
BitSet<CaptureType> capturesTypes;
|
||||
BitSet<CaptureType> allyCapturesTypes;
|
||||
BitSet<CaptureType> neutralCapturesTypes;
|
||||
BitSet<CaptureType> enemyCapturesTypes;
|
||||
BitSet<CaptureType> capturableTypes;
|
||||
|
||||
IEnumerable<Capturable> enabledCapturable;
|
||||
IEnumerable<Captures> enabledCaptures;
|
||||
@@ -81,8 +70,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public bool BeingCaptured { get; private set; }
|
||||
|
||||
public CaptureManager(CaptureManagerInfo info)
|
||||
public CaptureManager(Actor self, CaptureManagerInfo info)
|
||||
{
|
||||
this.self = self;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@@ -103,69 +93,74 @@ namespace OpenRA.Mods.Common.Traits
|
||||
RefreshCapturable();
|
||||
}
|
||||
|
||||
public void RefreshCapturable()
|
||||
public void RefreshCaptures()
|
||||
{
|
||||
allyCapturableTypes = neutralCapturableTypes = enemyCapturableTypes = default;
|
||||
foreach (var c in enabledCapturable)
|
||||
allyCapturesTypes = neutralCapturesTypes = enemyCapturesTypes = default;
|
||||
foreach (var c in enabledCaptures)
|
||||
{
|
||||
if (c.Info.ValidRelationships.HasRelationship(PlayerRelationship.Ally))
|
||||
allyCapturableTypes = allyCapturableTypes.Union(c.Info.Types);
|
||||
allyCapturesTypes = allyCapturesTypes.Union(c.Info.CaptureTypes);
|
||||
|
||||
if (c.Info.ValidRelationships.HasRelationship(PlayerRelationship.Neutral))
|
||||
neutralCapturableTypes = neutralCapturableTypes.Union(c.Info.Types);
|
||||
neutralCapturesTypes = neutralCapturesTypes.Union(c.Info.CaptureTypes);
|
||||
|
||||
if (c.Info.ValidRelationships.HasRelationship(PlayerRelationship.Enemy))
|
||||
enemyCapturableTypes = enemyCapturableTypes.Union(c.Info.Types);
|
||||
enemyCapturesTypes = enemyCapturesTypes.Union(c.Info.CaptureTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshCaptures()
|
||||
public void RefreshCapturable()
|
||||
{
|
||||
capturesTypes = enabledCaptures.Aggregate(
|
||||
capturableTypes = enabledCapturable.Aggregate(
|
||||
default(BitSet<CaptureType>),
|
||||
(a, b) => a.Union(b.Info.CaptureTypes));
|
||||
(a, b) => a.Union(b.Info.Types));
|
||||
}
|
||||
|
||||
public bool CanBeTargetedBy(Actor self, Actor captor, CaptureManager captorManager)
|
||||
/// <summary>Should only be called from the captor's CaptureManager.</summary>
|
||||
public bool CanTarget(CaptureManager target)
|
||||
{
|
||||
var relationship = captor.Owner.RelationshipWith(self.Owner);
|
||||
if (relationship.HasRelationship(PlayerRelationship.Enemy))
|
||||
return captorManager.capturesTypes.Overlaps(enemyCapturableTypes);
|
||||
|
||||
if (relationship.HasRelationship(PlayerRelationship.Neutral))
|
||||
return captorManager.capturesTypes.Overlaps(neutralCapturableTypes);
|
||||
|
||||
if (relationship.HasRelationship(PlayerRelationship.Ally))
|
||||
return captorManager.capturesTypes.Overlaps(allyCapturableTypes);
|
||||
|
||||
return false;
|
||||
return CanTarget(target.self.Owner, target.capturableTypes);
|
||||
}
|
||||
|
||||
public bool CanBeTargetedBy(Actor self, Actor captor, Captures captures)
|
||||
/// <summary>Should only be called from the captor CaptureManager.</summary>
|
||||
public bool CanTarget(FrozenActor target)
|
||||
{
|
||||
if (captures.IsTraitDisabled)
|
||||
if (!target.Info.HasTraitInfo<CaptureManagerInfo>())
|
||||
return false;
|
||||
|
||||
var relationship = captor.Owner.RelationshipWith(self.Owner);
|
||||
// TODO: FrozenActors don't yet have a way of caching conditions, so we can't filter disabled traits
|
||||
// This therefore assumes that all Capturable traits are enabled, which is probably wrong.
|
||||
// Actors with FrozenUnderFog should therefore not disable the Capturable trait.
|
||||
var targetTypes = target.Info.TraitInfos<CapturableInfo>().Aggregate(
|
||||
default(BitSet<CaptureType>),
|
||||
(a, b) => a.Union(b.Types));
|
||||
|
||||
return CanTarget(target.Owner, targetTypes);
|
||||
}
|
||||
|
||||
bool CanTarget(Player target, BitSet<CaptureType> captureTypes)
|
||||
{
|
||||
var relationship = self.Owner.RelationshipWith(target);
|
||||
if (relationship.HasRelationship(PlayerRelationship.Enemy))
|
||||
return captures.Info.CaptureTypes.Overlaps(enemyCapturableTypes);
|
||||
return captureTypes.Overlaps(enemyCapturesTypes);
|
||||
|
||||
if (relationship.HasRelationship(PlayerRelationship.Neutral))
|
||||
return captures.Info.CaptureTypes.Overlaps(neutralCapturableTypes);
|
||||
return captureTypes.Overlaps(neutralCapturesTypes);
|
||||
|
||||
if (relationship.HasRelationship(PlayerRelationship.Ally))
|
||||
return captures.Info.CaptureTypes.Overlaps(allyCapturableTypes);
|
||||
return captureTypes.Overlaps(allyCapturesTypes);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Captures ValidCapturesWithLowestSabotageThreshold(Actor self, Actor captee, CaptureManager capteeManager)
|
||||
public Captures ValidCapturesWithLowestSabotageThreshold(CaptureManager target)
|
||||
{
|
||||
if (captee.IsDead)
|
||||
if (target.self.IsDead)
|
||||
return null;
|
||||
|
||||
var relationship = self.Owner.RelationshipWith(target.self.Owner);
|
||||
foreach (var c in enabledCaptures.OrderBy(c => c.Info.SabotageThreshold).ThenBy(c => c.Info.CaptureDelay))
|
||||
if (capteeManager.CanBeTargetedBy(captee, self, c))
|
||||
if (c.Info.ValidRelationships.HasRelationship(relationship) && target.capturableTypes.Overlaps(c.Info.CaptureTypes))
|
||||
return c;
|
||||
|
||||
return null;
|
||||
@@ -182,7 +177,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
/// This method grants the capturing conditions on the captor and target and returns
|
||||
/// true if the captor is able to start entering or false if it needs to wait.
|
||||
/// </summary>
|
||||
public bool StartCapture(Actor self, Actor target, CaptureManager targetManager, out Captures captures)
|
||||
public bool StartCapture(CaptureManager targetManager, out Captures captures)
|
||||
{
|
||||
captures = null;
|
||||
|
||||
@@ -190,10 +185,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (self.WillDispose)
|
||||
return false;
|
||||
|
||||
var target = targetManager.self;
|
||||
if (target != currentTarget)
|
||||
{
|
||||
if (currentTarget != null)
|
||||
CancelCapture(self, currentTarget, currentTargetManager);
|
||||
if (currentTargetManager != null)
|
||||
CancelCapture(currentTargetManager);
|
||||
|
||||
targetManager.currentCaptors.Add(self);
|
||||
currentTarget = target;
|
||||
@@ -209,7 +205,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (targetManager.beingCapturedToken == Actor.InvalidConditionToken)
|
||||
targetManager.beingCapturedToken = target.GrantCondition(targetManager.info.BeingCapturedCondition);
|
||||
|
||||
captures = ValidCapturesWithLowestSabotageThreshold(self, target, targetManager);
|
||||
captures = ValidCapturesWithLowestSabotageThreshold(targetManager);
|
||||
if (captures == null)
|
||||
return false;
|
||||
|
||||
@@ -243,11 +239,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
/// This method revokes the capturing conditions on the captor and target
|
||||
/// and resets any capturing progress.
|
||||
/// </summary>
|
||||
public void CancelCapture(Actor self, Actor target, CaptureManager targetManager)
|
||||
public void CancelCapture(CaptureManager targetManager)
|
||||
{
|
||||
if (currentTarget == null)
|
||||
return;
|
||||
|
||||
var target = targetManager.self;
|
||||
foreach (var w in progressWatchers)
|
||||
w.Update(self, self, target, 0, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user