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
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (captureManager == null)
|
||||
return false;
|
||||
|
||||
return capturers.Any(tp => captureManager.CanBeTargetedBy(target, tp.Actor, tp.Trait));
|
||||
return capturers.Any(tp => tp.Trait.CanTarget(captureManager));
|
||||
})
|
||||
.OrderByDescending(target => target.GetSellValue())
|
||||
.Take(maximumCaptureTargetOptions);
|
||||
|
||||
@@ -22,9 +22,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("CaptureTypes (from the Captures trait) that are able to capture this.")]
|
||||
public readonly BitSet<CaptureType> Types = default;
|
||||
|
||||
[Desc("What player relationships the target's owner needs to be captured by this actor.")]
|
||||
public readonly PlayerRelationship ValidRelationships = PlayerRelationship.Neutral | PlayerRelationship.Enemy;
|
||||
|
||||
[Desc("Cancel the actor's current activity when getting captured.")]
|
||||
public readonly bool CancelActivity = false;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Experience granted to the capturing player.")]
|
||||
public readonly int PlayerExperience = 0;
|
||||
|
||||
[Desc("What player relationships the target's owner needs to be captured by this actor.")]
|
||||
public readonly PlayerRelationship ValidRelationships = PlayerRelationship.Neutral | PlayerRelationship.Enemy;
|
||||
|
||||
[Desc("Relationships that the structure's previous owner needs to have for the capturing player to receive Experience.")]
|
||||
public readonly PlayerRelationship PlayerExperienceRelationships = PlayerRelationship.Enemy;
|
||||
|
||||
@@ -69,12 +72,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public class Captures : ConditionalTrait<CapturesInfo>, IIssueOrder, IResolveOrder, IOrderVoice
|
||||
{
|
||||
readonly CaptureManager captureManager;
|
||||
public readonly CaptureManager CaptureManager;
|
||||
|
||||
public Captures(Actor self, CapturesInfo info)
|
||||
: base(info)
|
||||
{
|
||||
captureManager = self.Trait<CaptureManager>();
|
||||
CaptureManager = self.Trait<CaptureManager>();
|
||||
}
|
||||
|
||||
public IEnumerable<IOrderTargeter> Orders
|
||||
@@ -110,8 +113,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
self.ShowTargetLines();
|
||||
}
|
||||
|
||||
protected override void TraitEnabled(Actor self) { captureManager.RefreshCaptures(); }
|
||||
protected override void TraitDisabled(Actor self) { captureManager.RefreshCaptures(); }
|
||||
protected override void TraitEnabled(Actor self) { CaptureManager.RefreshCaptures(); }
|
||||
protected override void TraitDisabled(Actor self) { CaptureManager.RefreshCaptures(); }
|
||||
|
||||
sealed class CaptureOrderTargeter : UnitOrderTargeter
|
||||
{
|
||||
@@ -125,8 +128,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
var captureManager = target.TraitOrDefault<CaptureManager>();
|
||||
if (captureManager == null || !captureManager.CanBeTargetedBy(target, self, captures))
|
||||
var targetManager = target.TraitOrDefault<CaptureManager>();
|
||||
if (targetManager == null || !captures.CaptureManager.CanTarget(targetManager))
|
||||
{
|
||||
cursor = captures.Info.EnterBlockedCursor;
|
||||
return false;
|
||||
@@ -147,8 +150,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
var captureManagerInfo = target.Info.TraitInfoOrDefault<CaptureManagerInfo>();
|
||||
if (captureManagerInfo == null || !captureManagerInfo.CanBeTargetedBy(target, self, captures))
|
||||
if (!captures.CaptureManager.CanTarget(target))
|
||||
{
|
||||
cursor = captures.Info.EnterBlockedCursor;
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user