Merge ConditionManager trait directly into Actor

This commit is contained in:
atlimit8
2020-04-18 23:25:05 -05:00
committed by reaperrr
parent e12c1dc9aa
commit 259c8d2c98
65 changed files with 466 additions and 707 deletions

View File

@@ -74,6 +74,31 @@ namespace OpenRA
}
}
/// <summary>Value used to represent an invalid token.</summary>
public static readonly int InvalidConditionToken = -1;
class ConditionState
{
/// <summary>Delegates that have registered to be notified when this condition changes.</summary>
public readonly List<VariableObserverNotifier> Notifiers = new List<VariableObserverNotifier>();
/// <summary>Unique integers identifying granted instances of the condition.</summary>
public readonly HashSet<int> Tokens = new HashSet<int>();
}
readonly Dictionary<string, ConditionState> conditionStates = new Dictionary<string, ConditionState>();
/// <summary>Each granted condition receives a unique token that is used when revoking.</summary>
readonly Dictionary<int, string> conditionTokens = new Dictionary<int, string>();
int nextConditionToken = 1;
/// <summary>Cache of condition -> enabled state for quick evaluation of token counter conditions.</summary>
readonly Dictionary<string, int> conditionCache = new Dictionary<string, int>();
/// <summary>Read-only version of conditionCache that is passed to IConditionConsumers.</summary>
readonly IReadOnlyDictionary<string, int> readOnlyConditionCache;
internal SyncHash[] SyncHashes { get; private set; }
readonly IFacing facing;
@@ -93,6 +118,8 @@ namespace OpenRA
{
var init = new ActorInitializer(this, initDict);
readOnlyConditionCache = new ReadOnlyDictionary<string, int>(conditionCache);
World = world;
ActorID = world.NextAID();
if (initDict.Contains<OwnerInit>())
@@ -148,9 +175,36 @@ namespace OpenRA
{
created = true;
// Make sure traits are usable for condition notifiers
foreach (var t in TraitsImplementing<INotifyCreated>())
t.Created(this);
var allObserverNotifiers = new HashSet<VariableObserverNotifier>();
foreach (var provider in TraitsImplementing<IObservesVariables>())
{
foreach (var variableUser in provider.GetVariableObservers())
{
allObserverNotifiers.Add(variableUser.Notifier);
foreach (var variable in variableUser.Variables)
{
var cs = conditionStates.GetOrAdd(variable);
cs.Notifiers.Add(variableUser.Notifier);
// Initialize conditions that have not yet been granted to 0
// NOTE: Some conditions may have already been granted by INotifyCreated calling GrantCondition,
// and we choose to assign the token count to safely cover both cases instead of adding an if branch.
conditionCache[variable] = cs.Tokens.Count;
}
}
}
// Update all traits with their initial condition state
foreach (var notify in allObserverNotifiers)
notify(this, readOnlyConditionCache);
// TODO: Some traits may need initialization after being notified of initial condition state.
// TODO: A post condition initialization notification phase may allow queueing activities instead.
// The initial activity should run before any activities queued by INotifyCreated.Created
// However, we need to know which traits are enabled (via conditions), so wait for after the calls and insert the activity as the first
ICreationActivity creationActivity = null;
@@ -454,6 +508,60 @@ namespace OpenRA
return new[] { CenterPosition };
}
#region Conditions
void UpdateConditionState(string condition, int token, bool isRevoke)
{
ConditionState conditionState = conditionStates.GetOrAdd(condition);
if (isRevoke)
conditionState.Tokens.Remove(token);
else
conditionState.Tokens.Add(token);
conditionCache[condition] = conditionState.Tokens.Count;
// Conditions may be granted or revoked before the state is initialized.
// These notifications will be processed after INotifyCreated.Created.
if (created)
foreach (var notify in conditionState.Notifiers)
notify(this, readOnlyConditionCache);
}
/// <summary>Grants a specified condition.</summary>
/// <returns>The token that is used to revoke this condition.</returns>
public int GrantCondition(string condition)
{
var token = nextConditionToken++;
conditionTokens.Add(token, condition);
UpdateConditionState(condition, token, false);
return token;
}
/// <summary>
/// Revokes a previously granted condition.
/// </summary>
/// <param name="token">The token ID returned by GrantCondition.</param>
/// <returns>The invalid token ID.</returns>
public int RevokeCondition(int token)
{
string condition;
if (!conditionTokens.TryGetValue(token, out condition))
throw new InvalidOperationException("Attempting to revoke condition with invalid token {0} for {1}.".F(token, this));
conditionTokens.Remove(token);
UpdateConditionState(condition, token, true);
return InvalidConditionToken;
}
/// <summary>Returns whether the specified token is valid for RevokeCondition</summary>
public bool TokenValid(int token)
{
return conditionTokens.ContainsKey(token);
}
#endregion
#region Scripting interface
Lazy<ScriptActorInterface> luaInterface;

View File

@@ -539,4 +539,24 @@ namespace OpenRA.Traits
[RequireExplicitImplementation]
public interface ICreationActivity { Activity GetCreationActivity(); }
[RequireExplicitImplementation]
public interface IObservesVariablesInfo : ITraitInfo { }
public delegate void VariableObserverNotifier(Actor self, IReadOnlyDictionary<string, int> variables);
public struct VariableObserver
{
public VariableObserverNotifier Notifier;
public IEnumerable<string> Variables;
public VariableObserver(VariableObserverNotifier notifier, IEnumerable<string> variables)
{
Notifier = notifier;
Variables = variables;
}
}
public interface IObservesVariables
{
IEnumerable<VariableObserver> GetVariableObservers();
}
}

View File

@@ -34,8 +34,7 @@ namespace OpenRA.Mods.Cnc.Traits
{
readonly AttackLeapInfo info;
ConditionManager conditionManager;
int leapToken = ConditionManager.InvalidConditionToken;
int leapToken = Actor.InvalidConditionToken;
public AttackLeap(Actor self, AttackLeapInfo info)
: base(self, info)
@@ -43,12 +42,6 @@ namespace OpenRA.Mods.Cnc.Traits
this.info = info;
}
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
protected override bool CanAttack(Actor self, Target target)
{
if (target.Type != TargetType.Actor)
@@ -62,14 +55,14 @@ namespace OpenRA.Mods.Cnc.Traits
public void GrantLeapCondition(Actor self)
{
if (conditionManager != null && !string.IsNullOrEmpty(info.LeapCondition))
leapToken = conditionManager.GrantCondition(self, info.LeapCondition);
if (!string.IsNullOrEmpty(info.LeapCondition))
leapToken = self.GrantCondition(info.LeapCondition);
}
public void RevokeLeapCondition(Actor self)
{
if (leapToken != ConditionManager.InvalidConditionToken)
leapToken = conditionManager.RevokeCondition(self, leapToken);
if (leapToken != Actor.InvalidConditionToken)
leapToken = self.RevokeCondition(leapToken);
}
public override Activity GetAttackActivity(Actor self, AttackSource source, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor)

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Cnc.Traits
public object Create(ActorInitializer init) { return new ConyardChronoReturn(init, this); }
}
public class ConyardChronoReturn : INotifyCreated, ITick, ISync, IObservesVariables, ISelectionBar, INotifySold,
public class ConyardChronoReturn : ITick, ISync, IObservesVariables, ISelectionBar, INotifySold,
IDeathActorInitModifier, ITransformActorInitModifier
{
readonly ConyardChronoReturnInfo info;
@@ -70,8 +70,7 @@ namespace OpenRA.Mods.Cnc.Traits
readonly Actor self;
readonly string faction;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
Actor chronosphere;
int duration;
@@ -110,11 +109,6 @@ namespace OpenRA.Mods.Cnc.Traits
chronosphere = init.Get<ChronoshiftChronosphereInit, Actor>();
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
IEnumerable<VariableObserver> IObservesVariables.GetVariableObservers()
{
if (info.ReturnOriginalActorOnCondition != null)
@@ -128,8 +122,8 @@ namespace OpenRA.Mods.Cnc.Traits
void TriggerVortex()
{
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition);
if (!string.IsNullOrEmpty(info.Condition) && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(info.Condition);
triggered = true;
@@ -140,8 +134,8 @@ namespace OpenRA.Mods.Cnc.Traits
wsb.PlayCustomAnimation(self, info.Sequence, () =>
{
triggered = false;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
});
}

View File

@@ -99,7 +99,7 @@ namespace OpenRA.Mods.Cnc.Traits
public object Create(ActorInitializer init) { return new Disguise(init.Self, this); }
}
class Disguise : INotifyCreated, IEffectiveOwner, IIssueOrder, IResolveOrder, IOrderVoice, IRadarColorModifier, INotifyAttack,
class Disguise : IEffectiveOwner, IIssueOrder, IResolveOrder, IOrderVoice, IRadarColorModifier, INotifyAttack,
INotifyDamage, INotifyUnload, INotifyDemolition, INotifyInfiltration, ITick
{
public ActorInfo AsActor { get; private set; }
@@ -112,9 +112,8 @@ namespace OpenRA.Mods.Cnc.Traits
readonly Actor self;
readonly DisguiseInfo info;
ConditionManager conditionManager;
int disguisedToken = ConditionManager.InvalidConditionToken;
int disguisedAsToken = ConditionManager.InvalidConditionToken;
int disguisedToken = Actor.InvalidConditionToken;
int disguisedAsToken = Actor.InvalidConditionToken;
CPos? lastPos;
public Disguise(Actor self, DisguiseInfo info)
@@ -125,11 +124,6 @@ namespace OpenRA.Mods.Cnc.Traits
AsActor = self.Info;
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
IEnumerable<IOrderTargeter> IIssueOrder.Orders
{
get
@@ -225,25 +219,22 @@ namespace OpenRA.Mods.Cnc.Traits
foreach (var t in self.TraitsImplementing<INotifyEffectiveOwnerChanged>())
t.OnEffectiveOwnerChanged(self, oldEffectiveOwner, AsPlayer);
if (conditionManager != null)
{
if (Disguised != oldDisguiseSetting)
{
if (Disguised && disguisedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition))
disguisedToken = conditionManager.GrantCondition(self, info.DisguisedCondition);
else if (!Disguised && disguisedToken != ConditionManager.InvalidConditionToken)
disguisedToken = conditionManager.RevokeCondition(self, disguisedToken);
if (Disguised && disguisedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition))
disguisedToken = self.GrantCondition(info.DisguisedCondition);
else if (!Disguised && disguisedToken != Actor.InvalidConditionToken)
disguisedToken = self.RevokeCondition(disguisedToken);
}
if (AsActor != oldEffectiveActor)
{
if (disguisedAsToken != ConditionManager.InvalidConditionToken)
disguisedAsToken = conditionManager.RevokeCondition(self, disguisedAsToken);
if (disguisedAsToken != Actor.InvalidConditionToken)
disguisedAsToken = self.RevokeCondition(disguisedAsToken);
string disguisedAsCondition;
if (info.DisguisedAsConditions.TryGetValue(AsActor.Name, out disguisedAsCondition))
disguisedAsToken = conditionManager.GrantCondition(self, disguisedAsCondition);
}
disguisedAsToken = self.GrantCondition(disguisedAsCondition);
}
}

View File

@@ -83,22 +83,15 @@ namespace OpenRA.Mods.Cnc.Traits
}
}
class MadTank : INotifyCreated, IIssueOrder, IResolveOrder, IOrderVoice, IIssueDeployOrder
class MadTank : IIssueOrder, IResolveOrder, IOrderVoice, IIssueDeployOrder
{
readonly MadTankInfo info;
ConditionManager conditionManager;
public MadTank(Actor self, MadTankInfo info)
{
this.info = info;
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
public IEnumerable<IOrderTargeter> Orders
{
get
@@ -195,8 +188,8 @@ namespace OpenRA.Mods.Cnc.Traits
if (target.Type == TargetType.Invalid)
return true;
if (mad.conditionManager != null && !string.IsNullOrEmpty(mad.info.DeployedCondition))
mad.conditionManager.GrantCondition(self, mad.info.DeployedCondition);
if (!string.IsNullOrEmpty(mad.info.DeployedCondition))
self.GrantCondition(mad.info.DeployedCondition);
self.World.AddFrameEndTask(w => EjectDriver());
if (mad.info.ThumpSequence != null)

View File

@@ -22,15 +22,13 @@ namespace OpenRA.Mods.Common.Activities
readonly Func<Activity> getInner;
readonly bool isAssaultMove;
AutoTarget autoTarget;
ConditionManager conditionManager;
AttackMove attackMove;
int token = ConditionManager.InvalidConditionToken;
int token = Actor.InvalidConditionToken;
public AttackMoveActivity(Actor self, Func<Activity> getInner, bool assaultMoving = false)
{
this.getInner = getInner;
autoTarget = self.TraitOrDefault<AutoTarget>();
conditionManager = self.TraitOrDefault<ConditionManager>();
attackMove = self.TraitOrDefault<AttackMove>();
isAssaultMove = assaultMoving;
ChildHasPriority = false;
@@ -41,13 +39,13 @@ namespace OpenRA.Mods.Common.Activities
// Start moving.
QueueChild(getInner());
if (conditionManager == null || attackMove == null)
if (attackMove == null)
return;
if (!isAssaultMove && !string.IsNullOrEmpty(attackMove.Info.AttackMoveCondition))
token = conditionManager.GrantCondition(self, attackMove.Info.AttackMoveCondition);
token = self.GrantCondition(attackMove.Info.AttackMoveCondition);
else if (isAssaultMove && !string.IsNullOrEmpty(attackMove.Info.AssaultMoveCondition))
token = conditionManager.GrantCondition(self, attackMove.Info.AssaultMoveCondition);
token = self.GrantCondition(attackMove.Info.AssaultMoveCondition);
}
public override bool Tick(Actor self)
@@ -77,8 +75,8 @@ namespace OpenRA.Mods.Common.Activities
protected override void OnLastRun(Actor self)
{
if (conditionManager != null && token != ConditionManager.InvalidConditionToken)
token = conditionManager.RevokeCondition(self, token);
if (token != Actor.InvalidConditionToken)
token = self.RevokeCondition(token);
}
public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -12,7 +12,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Lint
@@ -60,9 +59,6 @@ namespace OpenRA.Mods.Common.Lint
var ungranted = consumed.Except(granted);
if (ungranted.Any())
emitError("Actor type `{0}` consumes conditions that are not granted: {1}".F(actorInfo.Key, ungranted.JoinWith(", ")));
if ((consumed.Any() || granted.Any()) && actorInfo.Value.TraitInfoOrDefault<ConditionManagerInfo>() == null)
emitError("Actor type `{0}` defines conditions but does not include a ConditionManager".F(actorInfo.Key));
}
}
}

View File

@@ -196,7 +196,6 @@ namespace OpenRA.Mods.Common.Traits
Repairable repairable;
Rearmable rearmable;
IAircraftCenterPositionOffset[] positionOffsets;
ConditionManager conditionManager;
IDisposable reservation;
IEnumerable<int> speedModifiers;
INotifyMoving[] notifyMoving;
@@ -230,8 +229,8 @@ namespace OpenRA.Mods.Common.Traits
bool airborne;
bool cruising;
int airborneToken = ConditionManager.InvalidConditionToken;
int cruisingToken = ConditionManager.InvalidConditionToken;
int airborneToken = Actor.InvalidConditionToken;
int cruisingToken = Actor.InvalidConditionToken;
MovementType movementTypes;
WPos cachedPosition;
@@ -293,7 +292,6 @@ namespace OpenRA.Mods.Common.Traits
{
repairable = self.TraitOrDefault<Repairable>();
rearmable = self.TraitOrDefault<Rearmable>();
conditionManager = self.TraitOrDefault<ConditionManager>();
speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray().Select(sm => sm.GetSpeedModifier());
cachedPosition = self.CenterPosition;
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
@@ -1116,8 +1114,8 @@ namespace OpenRA.Mods.Common.Traits
return;
airborne = true;
if (conditionManager != null && !string.IsNullOrEmpty(Info.AirborneCondition) && airborneToken == ConditionManager.InvalidConditionToken)
airborneToken = conditionManager.GrantCondition(self, Info.AirborneCondition);
if (!string.IsNullOrEmpty(Info.AirborneCondition) && airborneToken == Actor.InvalidConditionToken)
airborneToken = self.GrantCondition(Info.AirborneCondition);
}
void OnAirborneAltitudeLeft()
@@ -1126,8 +1124,8 @@ namespace OpenRA.Mods.Common.Traits
return;
airborne = false;
if (conditionManager != null && airborneToken != ConditionManager.InvalidConditionToken)
airborneToken = conditionManager.RevokeCondition(self, airborneToken);
if (airborneToken != Actor.InvalidConditionToken)
airborneToken = self.RevokeCondition(airborneToken);
}
#endregion
@@ -1140,8 +1138,8 @@ namespace OpenRA.Mods.Common.Traits
return;
cruising = true;
if (conditionManager != null && !string.IsNullOrEmpty(Info.CruisingCondition) && cruisingToken == ConditionManager.InvalidConditionToken)
cruisingToken = conditionManager.GrantCondition(self, Info.CruisingCondition);
if (!string.IsNullOrEmpty(Info.CruisingCondition) && cruisingToken == Actor.InvalidConditionToken)
cruisingToken = self.GrantCondition(Info.CruisingCondition);
}
void OnCruisingAltitudeLeft()
@@ -1150,8 +1148,8 @@ namespace OpenRA.Mods.Common.Traits
return;
cruising = false;
if (conditionManager != null && cruisingToken != ConditionManager.InvalidConditionToken)
cruisingToken = conditionManager.RevokeCondition(self, cruisingToken);
if (cruisingToken != Actor.InvalidConditionToken)
cruisingToken = self.RevokeCondition(cruisingToken);
}
#endregion

View File

@@ -51,7 +51,6 @@ namespace OpenRA.Mods.Common.Traits
{
public readonly AmmoPoolInfo Info;
readonly Stack<int> tokens = new Stack<int>();
ConditionManager conditionManager;
// HACK: Temporarily needed until Rearm activity is gone for good
[Sync]
@@ -91,7 +90,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
UpdateCondition(self);
// HACK: Temporarily needed until Rearm activity is gone for good
@@ -108,14 +106,14 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self)
{
if (conditionManager == null || string.IsNullOrEmpty(Info.AmmoCondition))
if (string.IsNullOrEmpty(Info.AmmoCondition))
return;
while (CurrentAmmoCount > tokens.Count && tokens.Count < Info.Ammo)
tokens.Push(conditionManager.GrantCondition(self, Info.AmmoCondition));
tokens.Push(self.GrantCondition(Info.AmmoCondition));
while (CurrentAmmoCount < tokens.Count && tokens.Count > 0)
conditionManager.RevokeCondition(self, tokens.Pop());
self.RevokeCondition(tokens.Pop());
}
}
}

View File

@@ -114,8 +114,7 @@ namespace OpenRA.Mods.Common.Traits
INotifyBurstComplete[] notifyBurstComplete;
INotifyAttack[] notifyAttacks;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
IEnumerable<int> rangeModifiers;
IEnumerable<int> reloadModifiers;
@@ -169,7 +168,6 @@ namespace OpenRA.Mods.Common.Traits
coords = self.Trait<BodyOrientation>();
notifyBurstComplete = self.TraitsImplementing<INotifyBurstComplete>().ToArray();
notifyAttacks = self.TraitsImplementing<INotifyAttack>().ToArray();
conditionManager = self.TraitOrDefault<ConditionManager>();
rangeModifiers = self.TraitsImplementing<IRangeModifier>().ToArray().Select(m => m.GetRangeModifier());
reloadModifiers = self.TraitsImplementing<IReloadModifier>().ToArray().Select(m => m.GetReloadModifier());
@@ -181,15 +179,15 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self)
{
if (string.IsNullOrEmpty(Info.ReloadingCondition) || conditionManager == null)
if (string.IsNullOrEmpty(Info.ReloadingCondition))
return;
var enabled = !IsTraitDisabled && IsReloading;
if (enabled && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.ReloadingCondition);
else if (!enabled && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (enabled && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.ReloadingCondition);
else if (!enabled && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
protected virtual void Tick(Actor self)

View File

@@ -35,8 +35,7 @@ namespace OpenRA.Mods.Common.Traits
public class AttackCharges : AttackOmni, INotifyAttack, INotifySold
{
readonly AttackChargesInfo info;
ConditionManager conditionManager;
int chargingToken = ConditionManager.InvalidConditionToken;
int chargingToken = Actor.InvalidConditionToken;
bool charging;
public int ChargeLevel { get; private set; }
@@ -47,13 +46,6 @@ namespace OpenRA.Mods.Common.Traits
this.info = info;
}
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
protected override void Tick(Actor self)
{
// Stop charging when we lose our target
@@ -62,12 +54,12 @@ namespace OpenRA.Mods.Common.Traits
var delta = charging ? info.ChargeRate : -info.DischargeRate;
ChargeLevel = (ChargeLevel + delta).Clamp(0, info.ChargeLevel);
if (ChargeLevel > 0 && conditionManager != null && !string.IsNullOrEmpty(info.ChargingCondition)
&& chargingToken == ConditionManager.InvalidConditionToken)
chargingToken = conditionManager.GrantCondition(self, info.ChargingCondition);
if (ChargeLevel > 0 && !string.IsNullOrEmpty(info.ChargingCondition)
&& chargingToken == Actor.InvalidConditionToken)
chargingToken = self.GrantCondition(info.ChargingCondition);
if (ChargeLevel == 0 && conditionManager != null && chargingToken != ConditionManager.InvalidConditionToken)
chargingToken = conditionManager.RevokeCondition(self, chargingToken);
if (ChargeLevel == 0 && chargingToken != Actor.InvalidConditionToken)
chargingToken = self.RevokeCondition(chargingToken);
base.Tick(self);
}

View File

@@ -145,11 +145,10 @@ namespace OpenRA.Mods.Common.Traits
public UnitStance PredictedStance;
UnitStance stance;
ConditionManager conditionManager;
IDisableAutoTarget[] disableAutoTarget;
INotifyStanceChanged[] notifyStanceChanged;
IEnumerable<AutoTargetPriorityInfo> activeTargetPriorities;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public void SetStance(Actor self, UnitStance value)
{
@@ -170,15 +169,12 @@ namespace OpenRA.Mods.Common.Traits
void ApplyStanceCondition(Actor self)
{
if (conditionManager == null)
return;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
string condition;
if (Info.ConditionByStance.TryGetValue(stance, out condition))
conditionToken = conditionManager.GrantCondition(self, condition);
conditionToken = self.GrantCondition(condition);
}
public AutoTarget(ActorInitializer init, AutoTargetInfo info)
@@ -206,7 +202,6 @@ namespace OpenRA.Mods.Common.Traits
.OrderByDescending(ati => ati.Info.Priority).ToArray()
.Where(Exts.IsTraitEnabled).Select(atp => atp.Info);
conditionManager = self.TraitOrDefault<ConditionManager>();
disableAutoTarget = self.TraitsImplementing<IDisableAutoTarget>().ToArray();
notifyStanceChanged = self.TraitsImplementing<INotifyStanceChanged>().ToArray();
ApplyStanceCondition(self);

View File

@@ -47,20 +47,13 @@ namespace OpenRA.Mods.Common.Traits
{
const string OrderID = "PrimaryProducer";
ConditionManager conditionManager;
int primaryToken = ConditionManager.InvalidConditionToken;
int primaryToken = Actor.InvalidConditionToken;
public bool IsPrimary { get; private set; }
public PrimaryBuilding(Actor self, PrimaryBuildingInfo info)
: base(info) { }
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
IEnumerable<IOrderTargeter> IIssueOrder.Orders
{
get
@@ -109,13 +102,13 @@ namespace OpenRA.Mods.Common.Traits
b.Trait.SetPrimaryProducer(b.Actor, false);
}
if (conditionManager != null && primaryToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.PrimaryCondition))
primaryToken = conditionManager.GrantCondition(self, Info.PrimaryCondition);
if (primaryToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.PrimaryCondition))
primaryToken = self.GrantCondition(Info.PrimaryCondition);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.SelectionNotification, self.Owner.Faction.InternalName);
}
else if (primaryToken != ConditionManager.InvalidConditionToken)
primaryToken = conditionManager.RevokeCondition(self, primaryToken);
else if (primaryToken != Actor.InvalidConditionToken)
primaryToken = self.RevokeCondition(primaryToken);
}
protected override void TraitEnabled(Actor self) { }

View File

@@ -57,7 +57,6 @@ namespace OpenRA.Mods.Common.Traits
readonly IHealth health;
readonly Predicate<Player> isNotActiveAlly;
readonly Stack<int> repairTokens = new Stack<int>();
ConditionManager conditionManager;
int remainingTicks;
public readonly List<Player> Repairers = new List<Player>();
@@ -70,12 +69,6 @@ namespace OpenRA.Mods.Common.Traits
isNotActiveAlly = player => player.WinState != WinState.Undefined || player.Stances[self.Owner] != Stance.Ally;
}
protected override void Created(Actor self)
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
}
[Sync]
public int RepairersHash
{
@@ -90,15 +83,15 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self)
{
if (conditionManager == null || string.IsNullOrEmpty(Info.RepairCondition))
if (string.IsNullOrEmpty(Info.RepairCondition))
return;
var currentRepairers = Repairers.Count;
while (Repairers.Count > repairTokens.Count)
repairTokens.Push(conditionManager.GrantCondition(self, Info.RepairCondition));
repairTokens.Push(self.GrantCondition(Info.RepairCondition));
while (Repairers.Count < repairTokens.Count && repairTokens.Count > 0)
conditionManager.RevokeCondition(self, repairTokens.Pop());
self.RevokeCondition(repairTokens.Pop());
}
public void RepairBuilding(Actor self, Player player)

View File

@@ -58,7 +58,6 @@ namespace OpenRA.Mods.Common.Traits
public class CaptureManager : INotifyCreated, INotifyCapture, ITick, IDisableEnemyAutoTarget
{
readonly CaptureManagerInfo info;
ConditionManager conditionManager;
IMove move;
ICaptureProgressWatcher[] progressWatchers;
@@ -75,8 +74,8 @@ namespace OpenRA.Mods.Common.Traits
CaptureManager currentTargetManager;
int currentTargetDelay;
int currentTargetTotal;
int capturingToken = ConditionManager.InvalidConditionToken;
int beingCapturedToken = ConditionManager.InvalidConditionToken;
int capturingToken = Actor.InvalidConditionToken;
int beingCapturedToken = Actor.InvalidConditionToken;
bool enteringCurrentTarget;
HashSet<Actor> currentCaptors = new HashSet<Actor>();
@@ -90,7 +89,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
move = self.TraitOrDefault<IMove>();
progressWatchers = self.TraitsImplementing<ICaptureProgressWatcher>().ToArray();
@@ -206,13 +204,13 @@ namespace OpenRA.Mods.Common.Traits
else
currentTargetDelay += 1;
if (conditionManager != null && !string.IsNullOrEmpty(info.CapturingCondition) &&
capturingToken == ConditionManager.InvalidConditionToken)
capturingToken = conditionManager.GrantCondition(self, info.CapturingCondition);
if (!string.IsNullOrEmpty(info.CapturingCondition) &&
capturingToken == Actor.InvalidConditionToken)
capturingToken = self.GrantCondition(info.CapturingCondition);
if (targetManager.conditionManager != null && !string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) &&
targetManager.beingCapturedToken == ConditionManager.InvalidConditionToken)
targetManager.beingCapturedToken = targetManager.conditionManager.GrantCondition(target, targetManager.info.BeingCapturedCondition);
if (!string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) &&
targetManager.beingCapturedToken == Actor.InvalidConditionToken)
targetManager.beingCapturedToken = target.GrantCondition(targetManager.info.BeingCapturedCondition);
captures = enabledCaptures
.OrderBy(c => c.Info.CaptureDelay)
@@ -262,11 +260,11 @@ namespace OpenRA.Mods.Common.Traits
foreach (var w in targetManager.progressWatchers)
w.Update(target, self, target, 0, 0);
if (capturingToken != ConditionManager.InvalidConditionToken)
capturingToken = conditionManager.RevokeCondition(self, capturingToken);
if (capturingToken != Actor.InvalidConditionToken)
capturingToken = self.RevokeCondition(capturingToken);
if (targetManager.beingCapturedToken != ConditionManager.InvalidConditionToken)
targetManager.beingCapturedToken = targetManager.conditionManager.RevokeCondition(self, targetManager.beingCapturedToken);
if (targetManager.beingCapturedToken != Actor.InvalidConditionToken)
targetManager.beingCapturedToken = self.RevokeCondition(targetManager.beingCapturedToken);
currentTarget = null;
currentTargetManager = null;

View File

@@ -100,8 +100,7 @@ namespace OpenRA.Mods.Common.Traits
int totalWeight = 0;
int reservedWeight = 0;
Aircraft aircraft;
ConditionManager conditionManager;
int loadingToken = ConditionManager.InvalidConditionToken;
int loadingToken = Actor.InvalidConditionToken;
Stack<int> loadedTokens = new Stack<int>();
bool takeOffAfterLoad;
bool initialised;
@@ -166,19 +165,18 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
aircraft = self.TraitOrDefault<Aircraft>();
conditionManager = self.TraitOrDefault<ConditionManager>();
if (conditionManager != null && cargo.Any())
if (cargo.Any())
{
foreach (var c in cargo)
{
string passengerCondition;
if (Info.PassengerConditions.TryGetValue(c.Info.Name, out passengerCondition))
passengerTokens.GetOrAdd(c.Info.Name).Push(conditionManager.GrantCondition(self, passengerCondition));
passengerTokens.GetOrAdd(c.Info.Name).Push(self.GrantCondition(passengerCondition));
}
if (!string.IsNullOrEmpty(Info.LoadedCondition))
loadedTokens.Push(conditionManager.GrantCondition(self, Info.LoadedCondition));
loadedTokens.Push(self.GrantCondition(Info.LoadedCondition));
}
// Defer notifications until we are certain all traits on the transport are initialised
@@ -264,8 +262,8 @@ namespace OpenRA.Mods.Common.Traits
if (!HasSpace(w))
return false;
if (conditionManager != null && loadingToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.LoadingCondition))
loadingToken = conditionManager.GrantCondition(self, Info.LoadingCondition);
if (loadingToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.LoadingCondition))
loadingToken = self.GrantCondition(Info.LoadingCondition);
reserves.Add(a);
reservedWeight += w;
@@ -283,8 +281,8 @@ namespace OpenRA.Mods.Common.Traits
reserves.Remove(a);
ReleaseLock(self);
if (loadingToken != ConditionManager.InvalidConditionToken)
loadingToken = conditionManager.RevokeCondition(self, loadingToken);
if (loadingToken != Actor.InvalidConditionToken)
loadingToken = self.RevokeCondition(loadingToken);
}
// Prepare for transport pickup
@@ -355,10 +353,10 @@ namespace OpenRA.Mods.Common.Traits
Stack<int> passengerToken;
if (passengerTokens.TryGetValue(passenger.Info.Name, out passengerToken) && passengerToken.Any())
conditionManager.RevokeCondition(self, passengerToken.Pop());
self.RevokeCondition(passengerToken.Pop());
if (loadedTokens.Any())
conditionManager.RevokeCondition(self, loadedTokens.Pop());
self.RevokeCondition(loadedTokens.Pop());
return passenger;
}
@@ -387,8 +385,8 @@ namespace OpenRA.Mods.Common.Traits
reserves.Remove(a);
ReleaseLock(self);
if (loadingToken != ConditionManager.InvalidConditionToken)
loadingToken = conditionManager.RevokeCondition(self, loadingToken);
if (loadingToken != Actor.InvalidConditionToken)
loadingToken = self.RevokeCondition(loadingToken);
}
// Don't initialise (effectively twice) if this runs before the FrameEndTask from Created
@@ -404,11 +402,11 @@ namespace OpenRA.Mods.Common.Traits
}
string passengerCondition;
if (conditionManager != null && Info.PassengerConditions.TryGetValue(a.Info.Name, out passengerCondition))
passengerTokens.GetOrAdd(a.Info.Name).Push(conditionManager.GrantCondition(self, passengerCondition));
if (Info.PassengerConditions.TryGetValue(a.Info.Name, out passengerCondition))
passengerTokens.GetOrAdd(a.Info.Name).Push(self.GrantCondition(passengerCondition));
if (conditionManager != null && !string.IsNullOrEmpty(Info.LoadedCondition))
loadedTokens.Push(conditionManager.GrantCondition(self, Info.LoadedCondition));
if (!string.IsNullOrEmpty(Info.LoadedCondition))
loadedTokens.Push(self.GrantCondition(Info.LoadedCondition));
}
void INotifyKilled.Killed(Actor self, AttackInfo e)

View File

@@ -44,10 +44,9 @@ namespace OpenRA.Mods.Common.Traits
public class Carryable : ConditionalTrait<CarryableInfo>
{
ConditionManager conditionManager;
int reservedToken = ConditionManager.InvalidConditionToken;
int carriedToken = ConditionManager.InvalidConditionToken;
int lockedToken = ConditionManager.InvalidConditionToken;
int reservedToken = Actor.InvalidConditionToken;
int carriedToken = Actor.InvalidConditionToken;
int lockedToken = Actor.InvalidConditionToken;
Mobile mobile;
IDelayCarryallPickup[] delayPickups;
@@ -66,7 +65,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
mobile = self.TraitOrDefault<Mobile>();
delayPickups = self.TraitsImplementing<IDelayCarryallPickup>().ToArray();
@@ -80,8 +78,8 @@ namespace OpenRA.Mods.Common.Traits
attached = true;
if (carriedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CarriedCondition))
carriedToken = conditionManager.GrantCondition(self, Info.CarriedCondition);
if (carriedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CarriedCondition))
carriedToken = self.GrantCondition(Info.CarriedCondition);
}
// This gets called by carrier after we touched down
@@ -92,8 +90,8 @@ namespace OpenRA.Mods.Common.Traits
attached = false;
if (carriedToken != ConditionManager.InvalidConditionToken)
carriedToken = conditionManager.RevokeCondition(self, carriedToken);
if (carriedToken != Actor.InvalidConditionToken)
carriedToken = self.RevokeCondition(carriedToken);
}
public virtual bool Reserve(Actor self, Actor carrier)
@@ -104,8 +102,8 @@ namespace OpenRA.Mods.Common.Traits
state = State.Reserved;
Carrier = carrier;
if (reservedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.ReservedCondition))
reservedToken = conditionManager.GrantCondition(self, Info.ReservedCondition);
if (reservedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.ReservedCondition))
reservedToken = self.GrantCondition(Info.ReservedCondition);
return true;
}
@@ -115,11 +113,11 @@ namespace OpenRA.Mods.Common.Traits
state = State.Free;
Carrier = null;
if (reservedToken != ConditionManager.InvalidConditionToken)
reservedToken = conditionManager.RevokeCondition(self, reservedToken);
if (reservedToken != Actor.InvalidConditionToken)
reservedToken = self.RevokeCondition(reservedToken);
if (lockedToken != ConditionManager.InvalidConditionToken)
lockedToken = conditionManager.RevokeCondition(self, lockedToken);
if (lockedToken != Actor.InvalidConditionToken)
lockedToken = self.RevokeCondition(lockedToken);
}
// Prepare for transport pickup
@@ -136,8 +134,8 @@ namespace OpenRA.Mods.Common.Traits
state = State.Locked;
Carrier = carrier;
if (lockedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.LockedCondition))
lockedToken = conditionManager.GrantCondition(self, Info.LockedCondition);
if (lockedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.LockedCondition))
lockedToken = self.GrantCondition(Info.LockedCondition);
}
// Make sure we are not moving and at our normal position with respect to the cell grid

View File

@@ -73,13 +73,12 @@ namespace OpenRA.Mods.Common.Traits
int remainingTime;
bool isDocking;
ConditionManager conditionManager;
Cloak[] otherCloaks;
CPos? lastPos;
bool wasCloaked = false;
bool firstTick = true;
int cloakedToken = ConditionManager.InvalidConditionToken;
int cloakedToken = Actor.InvalidConditionToken;
public Cloak(CloakInfo info)
: base(info)
@@ -89,7 +88,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
otherCloaks = self.TraitsImplementing<Cloak>()
.Where(c => c != this)
.ToArray();
@@ -97,8 +95,8 @@ namespace OpenRA.Mods.Common.Traits
if (Cloaked)
{
wasCloaked = true;
if (conditionManager != null && cloakedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = conditionManager.GrantCondition(self, Info.CloakedCondition);
if (cloakedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = self.GrantCondition(Info.CloakedCondition);
}
base.Created(self);
@@ -165,8 +163,8 @@ namespace OpenRA.Mods.Common.Traits
var isCloaked = Cloaked;
if (isCloaked && !wasCloaked)
{
if (conditionManager != null && cloakedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = conditionManager.GrantCondition(self, Info.CloakedCondition);
if (cloakedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = self.GrantCondition(Info.CloakedCondition);
// Sounds shouldn't play if the actor starts cloaked
if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked))
@@ -174,8 +172,8 @@ namespace OpenRA.Mods.Common.Traits
}
else if (!isCloaked && wasCloaked)
{
if (cloakedToken != ConditionManager.InvalidConditionToken)
cloakedToken = conditionManager.RevokeCondition(self, cloakedToken);
if (cloakedToken != Actor.InvalidConditionToken)
cloakedToken = self.RevokeCondition(cloakedToken);
if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked))
Game.Sound.Play(SoundType.World, Info.UncloakSound, self.CenterPosition);

View File

@@ -1,144 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Attach this to a unit to enable dynamic conditions by warheads, experience, crates, support powers, etc.")]
public class ConditionManagerInfo : TraitInfo<ConditionManager>, Requires<IObservesVariablesInfo> { }
public class ConditionManager : INotifyCreated
{
/// <summary>Value used to represent an invalid token.</summary>
public static readonly int InvalidConditionToken = -1;
class ConditionState
{
/// <summary>Delegates that have registered to be notified when this condition changes.</summary>
public readonly List<VariableObserverNotifier> Notifiers = new List<VariableObserverNotifier>();
/// <summary>Unique integers identifying granted instances of the condition.</summary>
public readonly HashSet<int> Tokens = new HashSet<int>();
}
Dictionary<string, ConditionState> state;
/// <summary>Each granted condition receives a unique token that is used when revoking.</summary>
Dictionary<int, string> tokens = new Dictionary<int, string>();
int nextToken = 1;
/// <summary>Cache of condition -> enabled state for quick evaluation of token counter conditions.</summary>
readonly Dictionary<string, int> conditionCache = new Dictionary<string, int>();
/// <summary>Read-only version of conditionCache that is passed to IConditionConsumers.</summary>
IReadOnlyDictionary<string, int> readOnlyConditionCache;
void INotifyCreated.Created(Actor self)
{
state = new Dictionary<string, ConditionState>();
readOnlyConditionCache = new ReadOnlyDictionary<string, int>(conditionCache);
var allObservers = new HashSet<VariableObserverNotifier>();
foreach (var provider in self.TraitsImplementing<IObservesVariables>())
{
foreach (var variableUser in provider.GetVariableObservers())
{
allObservers.Add(variableUser.Notifier);
foreach (var variable in variableUser.Variables)
{
var cs = state.GetOrAdd(variable);
cs.Notifiers.Add(variableUser.Notifier);
conditionCache[variable] = 0;
}
}
}
// Enable any conditions granted during trait setup
foreach (var kv in tokens)
{
ConditionState conditionState;
if (!state.TryGetValue(kv.Value, out conditionState))
continue;
conditionState.Tokens.Add(kv.Key);
conditionCache[kv.Value] = conditionState.Tokens.Count;
}
// Update all traits with their initial condition state
foreach (var consumer in allObservers)
consumer(self, readOnlyConditionCache);
}
void UpdateConditionState(Actor self, string condition, int token, bool isRevoke)
{
ConditionState conditionState;
if (!state.TryGetValue(condition, out conditionState))
return;
if (isRevoke)
conditionState.Tokens.Remove(token);
else
conditionState.Tokens.Add(token);
conditionCache[condition] = conditionState.Tokens.Count;
foreach (var notify in conditionState.Notifiers)
notify(self, readOnlyConditionCache);
}
/// <summary>Grants a specified condition.</summary>
/// <returns>The token that is used to revoke this condition.</returns>
public int GrantCondition(Actor self, string condition)
{
var token = nextToken++;
tokens.Add(token, condition);
// Conditions may be granted before the state is initialized.
// These conditions will be processed in INotifyCreated.Created.
if (state != null)
UpdateConditionState(self, condition, token, false);
return token;
}
/// <summary>
/// Revokes a previously granted condition.
/// </summary>
/// <param name="self">The actor to which this trait is attached.</param>
/// <param name="token">The token ID returned by GrantCondition.</param>
/// <returns>The invalid token ID.</returns>
public int RevokeCondition(Actor self, int token)
{
string condition;
if (!tokens.TryGetValue(token, out condition))
throw new InvalidOperationException("Attempting to revoke condition with invalid token {0} for {1}.".F(token, self));
tokens.Remove(token);
// Conditions may be granted and revoked before the state is initialized.
if (state != null)
UpdateConditionState(self, condition, token, true);
return InvalidConditionToken;
}
/// <summary>Returns whether the specified token is valid for RevokeCondition</summary>
public bool TokenValid(Actor self, int token)
{
return tokens.ContainsKey(token);
}
}
}

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits
}
[Desc("Allows a condition to be granted from an external source (Lua, warheads, etc).")]
public class ExternalConditionInfo : ITraitInfo, Requires<ConditionManagerInfo>
public class ExternalConditionInfo : ITraitInfo
{
[GrantedConditionReference]
[FieldLoader.Require]
@@ -55,7 +55,6 @@ namespace OpenRA.Mods.Common.Traits
}
public readonly ExternalConditionInfo Info;
readonly ConditionManager conditionManager;
readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>();
// Tokens are sorted on insert/remove by ascending expiry time
@@ -67,12 +66,11 @@ namespace OpenRA.Mods.Common.Traits
public ExternalCondition(Actor self, ExternalConditionInfo info)
{
Info = info;
conditionManager = self.Trait<ConditionManager>();
}
public bool CanGrantCondition(Actor self, object source)
{
if (conditionManager == null || source == null)
if (source == null)
return false;
// Timed tokens do not count towards the source cap: the condition with the shortest
@@ -93,9 +91,9 @@ namespace OpenRA.Mods.Common.Traits
public int GrantCondition(Actor self, object source, int duration = 0, int remaining = 0)
{
if (!CanGrantCondition(self, source))
return ConditionManager.InvalidConditionToken;
return Actor.InvalidConditionToken;
var token = conditionManager.GrantCondition(self, Info.Condition);
var token = self.GrantCondition(Info.Condition);
HashSet<int> permanent;
permanentTokens.TryGetValue(source, out permanent);
@@ -118,8 +116,8 @@ namespace OpenRA.Mods.Common.Traits
{
var expireToken = timedTokens[expireIndex].Token;
timedTokens.RemoveAt(expireIndex);
if (conditionManager.TokenValid(self, expireToken))
conditionManager.RevokeCondition(self, expireToken);
if (self.TokenValid(expireToken))
self.RevokeCondition(expireToken);
}
}
}
@@ -133,8 +131,8 @@ namespace OpenRA.Mods.Common.Traits
if (timedTokens.Count > 0)
{
var expire = timedTokens[0].Token;
if (conditionManager.TokenValid(self, expire))
conditionManager.RevokeCondition(self, expire);
if (self.TokenValid(expire))
self.RevokeCondition(expire);
timedTokens.RemoveAt(0);
}
@@ -166,7 +164,7 @@ namespace OpenRA.Mods.Common.Traits
/// <returns><c>true</c> if the now-revoked condition was originally granted by this trait.</returns>
public bool TryRevokeCondition(Actor self, object source, int token)
{
if (conditionManager == null || source == null)
if (source == null)
return false;
HashSet<int> permanentTokensForSource;
@@ -184,8 +182,8 @@ namespace OpenRA.Mods.Common.Traits
return false;
}
if (conditionManager.TokenValid(self, token))
conditionManager.RevokeCondition(self, token);
if (self.TokenValid(token))
self.RevokeCondition(token);
return true;
}
@@ -201,8 +199,8 @@ namespace OpenRA.Mods.Common.Traits
while (count < timedTokens.Count && timedTokens[count].Expires < worldTick)
{
var token = timedTokens[count].Token;
if (conditionManager.TokenValid(self, token))
conditionManager.RevokeCondition(self, token);
if (self.TokenValid(token))
self.RevokeCondition(token);
count++;
}

View File

@@ -29,31 +29,23 @@ namespace OpenRA.Mods.Common.Traits
class GrantCondition : ConditionalTrait<GrantConditionInfo>
{
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantCondition(GrantConditionInfo info)
: base(info) { }
protected override void Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
base.Created(self);
}
protected override void TraitEnabled(Actor self)
{
if (conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
if (conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
}
protected override void TraitDisabled(Actor self)
{
if (Info.GrantPermanently || conditionToken == ConditionManager.InvalidConditionToken)
if (Info.GrantPermanently || conditionToken == Actor.InvalidConditionToken)
return;
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
}
}
}

View File

@@ -52,7 +52,6 @@ namespace OpenRA.Mods.Common.Traits
int cooldown = 0;
int shotsFired = 0;
ConditionManager manager;
// Only tracked when RevokeOnNewTarget is true.
Target lastTarget = Target.Invalid;
@@ -60,33 +59,26 @@ namespace OpenRA.Mods.Common.Traits
public GrantConditionOnAttack(ActorInitializer init, GrantConditionOnAttackInfo info)
: base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
manager = self.TraitOrDefault<ConditionManager>();
}
void GrantInstance(Actor self, string cond)
{
if (manager == null || string.IsNullOrEmpty(cond))
if (string.IsNullOrEmpty(cond))
return;
tokens.Push(manager.GrantCondition(self, cond));
tokens.Push(self.GrantCondition(cond));
}
void RevokeInstance(Actor self, bool revokeAll)
{
shotsFired = 0;
if (manager == null || tokens.Count == 0)
if (tokens.Count == 0)
return;
if (!revokeAll)
manager.RevokeCondition(self, tokens.Pop());
self.RevokeCondition(tokens.Pop());
else
while (tokens.Count > 0)
manager.RevokeCondition(self, tokens.Pop());
self.RevokeCondition(tokens.Pop());
}
void ITick.Tick(Actor self)

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{
readonly GrantConditionOnBotOwnerInfo info;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnBotOwner(ActorInitializer init, GrantConditionOnBotOwnerInfo info)
{
@@ -49,22 +48,18 @@ namespace OpenRA.Mods.Common.Traits
// it's defined on the PlayerActor.
self.World.AddFrameEndTask(w =>
{
conditionManager = self.TraitOrDefault<ConditionManager>();
if (conditionManager != null && self.Owner.IsBot && info.Bots.Contains(self.Owner.BotType))
conditionToken = conditionManager.GrantCondition(self, info.Condition);
if (self.Owner.IsBot && info.Bots.Contains(self.Owner.BotType))
conditionToken = self.GrantCondition(info.Condition);
});
}
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
if (conditionManager == null)
return;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
if (info.Bots.Contains(newOwner.BotType))
conditionToken = conditionManager.GrantCondition(self, info.Condition);
conditionToken = self.GrantCondition(info.Condition);
}
}
}

View File

@@ -41,8 +41,7 @@ namespace OpenRA.Mods.Common.Traits
readonly GrantConditionOnDamageStateInfo info;
readonly IHealth health;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnDamageState(Actor self, GrantConditionOnDamageStateInfo info)
{
@@ -52,16 +51,15 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
GrantConditionOnValidDamageState(self, health.DamageState);
}
void GrantConditionOnValidDamageState(Actor self, DamageState state)
{
if (!info.ValidDamageStates.HasFlag(state) || conditionToken != ConditionManager.InvalidConditionToken)
if (!info.ValidDamageStates.HasFlag(state) || conditionToken != Actor.InvalidConditionToken)
return;
conditionToken = conditionManager.GrantCondition(self, info.Condition);
conditionToken = self.GrantCondition(info.Condition);
var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition);
@@ -69,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyDamageStateChanged.DamageStateChanged(Actor self, AttackInfo e)
{
var granted = conditionToken != ConditionManager.InvalidConditionToken;
var granted = conditionToken != Actor.InvalidConditionToken;
if (granted && info.GrantPermanently)
return;
@@ -77,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
GrantConditionOnValidDamageState(self, health.DamageState);
else if (granted && !info.ValidDamageStates.HasFlag(e.DamageState) && info.ValidDamageStates.HasFlag(e.PreviousDamageState))
{
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
var sound = info.DisabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition);

View File

@@ -98,10 +98,9 @@ namespace OpenRA.Mods.Common.Traits
readonly IMove move;
DeployState deployState;
ConditionManager conditionManager;
INotifyDeployTriggered[] notify;
int deployedToken = ConditionManager.InvalidConditionToken;
int undeployedToken = ConditionManager.InvalidConditionToken;
int deployedToken = Actor.InvalidConditionToken;
int undeployedToken = Actor.InvalidConditionToken;
public DeployState DeployState { get { return deployState; } }
@@ -118,7 +117,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
notify = self.TraitsImplementing<INotifyDeployTriggered>().ToArray();
base.Created(self);
@@ -317,32 +315,32 @@ namespace OpenRA.Mods.Common.Traits
void OnDeployStarted()
{
if (undeployedToken != ConditionManager.InvalidConditionToken)
undeployedToken = conditionManager.RevokeCondition(self, undeployedToken);
if (undeployedToken != Actor.InvalidConditionToken)
undeployedToken = self.RevokeCondition(undeployedToken);
deployState = DeployState.Deploying;
}
void OnDeployCompleted()
{
if (conditionManager != null && !string.IsNullOrEmpty(Info.DeployedCondition) && deployedToken == ConditionManager.InvalidConditionToken)
deployedToken = conditionManager.GrantCondition(self, Info.DeployedCondition);
if (!string.IsNullOrEmpty(Info.DeployedCondition) && deployedToken == Actor.InvalidConditionToken)
deployedToken = self.GrantCondition(Info.DeployedCondition);
deployState = DeployState.Deployed;
}
void OnUndeployStarted()
{
if (deployedToken != ConditionManager.InvalidConditionToken)
deployedToken = conditionManager.RevokeCondition(self, deployedToken);
if (deployedToken != Actor.InvalidConditionToken)
deployedToken = self.RevokeCondition(deployedToken);
deployState = DeployState.Deploying;
}
void OnUndeployCompleted()
{
if (conditionManager != null && !string.IsNullOrEmpty(Info.UndeployedCondition) && undeployedToken == ConditionManager.InvalidConditionToken)
undeployedToken = conditionManager.GrantCondition(self, Info.UndeployedCondition);
if (!string.IsNullOrEmpty(Info.UndeployedCondition) && undeployedToken == Actor.InvalidConditionToken)
undeployedToken = self.GrantCondition(Info.UndeployedCondition);
deployState = DeployState.Undeployed;
}

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
class GrantConditionOnFaction : ConditionalTrait<GrantConditionOnFactionInfo>, INotifyOwnerChanged
{
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
string faction;
public GrantConditionOnFaction(ActorInitializer init, GrantConditionOnFactionInfo info)
@@ -43,13 +42,6 @@ namespace OpenRA.Mods.Common.Traits
faction = init.Contains<FactionInit>() ? init.Get<FactionInit, string>() : init.Self.Owner.Faction.InternalName;
}
protected override void Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
base.Created(self);
}
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
if (Info.ResetOnOwnerChange && faction != newOwner.Faction.InternalName)
@@ -63,16 +55,16 @@ namespace OpenRA.Mods.Common.Traits
protected override void TraitEnabled(Actor self)
{
if (conditionToken == ConditionManager.InvalidConditionToken && Info.Factions.Contains(faction))
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
if (conditionToken == Actor.InvalidConditionToken && Info.Factions.Contains(faction))
conditionToken = self.GrantCondition(Info.Condition);
}
protected override void TraitDisabled(Actor self)
{
if (conditionToken == ConditionManager.InvalidConditionToken)
if (conditionToken == Actor.InvalidConditionToken)
return;
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
}
}
}

View File

@@ -53,8 +53,7 @@ namespace OpenRA.Mods.Common.Traits
readonly IHealth health;
readonly int maxHP;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnHealth(Actor self, GrantConditionOnHealthInfo info)
{
@@ -65,16 +64,15 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
GrantConditionOnValidHealth(self, health.HP);
}
void GrantConditionOnValidHealth(Actor self, int hp)
{
if (info.MinHP > hp || maxHP < hp || conditionToken != ConditionManager.InvalidConditionToken)
if (info.MinHP > hp || maxHP < hp || conditionToken != Actor.InvalidConditionToken)
return;
conditionToken = conditionManager.GrantCondition(self, info.Condition);
conditionToken = self.GrantCondition(info.Condition);
var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition);
@@ -82,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyDamage.Damaged(Actor self, AttackInfo e)
{
var granted = conditionToken != ConditionManager.InvalidConditionToken;
var granted = conditionToken != Actor.InvalidConditionToken;
if (granted && info.GrantPermanently)
return;
@@ -90,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
GrantConditionOnValidHealth(self, health.HP);
else if (granted && (info.MinHP > health.HP || maxHP < health.HP))
{
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
var sound = info.DisabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition);

View File

@@ -40,16 +40,16 @@ namespace OpenRA.Mods.Common.Traits
protected override void UpdateConditions(Actor self, byte oldLayer, byte newLayer)
{
if (!jumpjetInAir && newLayer == ValidLayerType && oldLayer != ValidLayerType && conditionToken == ConditionManager.InvalidConditionToken)
if (!jumpjetInAir && newLayer == ValidLayerType && oldLayer != ValidLayerType && conditionToken == Actor.InvalidConditionToken)
{
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
conditionToken = self.GrantCondition(Info.Condition);
jumpjetInAir = true;
}
// By the time the condition is meant to be revoked, the 'oldLayer' is already no longer the Jumpjet layer, either
if (jumpjetInAir && newLayer != ValidLayerType && oldLayer != ValidLayerType && conditionToken != ConditionManager.InvalidConditionToken)
if (jumpjetInAir && newLayer != ValidLayerType && oldLayer != ValidLayerType && conditionToken != Actor.InvalidConditionToken)
{
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
jumpjetInAir = false;
}
}

View File

@@ -24,8 +24,7 @@ namespace OpenRA.Mods.Common.Traits
public abstract class GrantConditionOnLayer<InfoType> : ConditionalTrait<InfoType>, INotifyCustomLayerChanged where InfoType : GrantConditionOnLayerInfo
{
protected readonly byte ValidLayerType;
protected ConditionManager conditionManager;
protected int conditionToken = ConditionManager.InvalidConditionToken;
protected int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnLayer(Actor self, InfoType info, byte validLayer)
: base(info)
@@ -33,40 +32,31 @@ namespace OpenRA.Mods.Common.Traits
ValidLayerType = validLayer;
}
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
void INotifyCustomLayerChanged.CustomLayerChanged(Actor self, byte oldLayer, byte newLayer)
{
if (conditionManager == null)
return;
UpdateConditions(self, oldLayer, newLayer);
}
protected virtual void UpdateConditions(Actor self, byte oldLayer, byte newLayer)
{
if (newLayer == ValidLayerType && oldLayer != ValidLayerType && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
else if (newLayer != ValidLayerType && oldLayer == ValidLayerType && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (newLayer == ValidLayerType && oldLayer != ValidLayerType && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
else if (newLayer != ValidLayerType && oldLayer == ValidLayerType && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
protected override void TraitEnabled(Actor self)
{
if (self.Location.Layer == ValidLayerType && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
if (self.Location.Layer == ValidLayerType && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
}
protected override void TraitDisabled(Actor self)
{
if (conditionToken == ConditionManager.InvalidConditionToken)
if (conditionToken == Actor.InvalidConditionToken)
return;
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
}
}
}

View File

@@ -43,9 +43,8 @@ namespace OpenRA.Mods.Common.Traits
if (direction != info.Direction)
return;
var conditionManager = self.TraitOrDefault<ConditionManager>();
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition))
conditionManager.GrantCondition(self, info.Condition);
if (!string.IsNullOrEmpty(info.Condition))
self.GrantCondition(info.Condition);
}
}
}

View File

@@ -29,8 +29,7 @@ namespace OpenRA.Mods.Common.Traits
public class GrantConditionOnMovement : ConditionalTrait<GrantConditionOnMovementInfo>, INotifyMoving
{
readonly IMove movement;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnMovement(Actor self, GrantConditionOnMovementInfo info)
: base(info)
@@ -38,23 +37,14 @@ namespace OpenRA.Mods.Common.Traits
movement = self.Trait<IMove>();
}
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
void UpdateCondition(Actor self, MovementType types)
{
if (conditionManager == null)
return;
var validMovement = !IsTraitDisabled && (types & Info.ValidMovementTypes) != 0;
if (!validMovement && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
else if (validMovement && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
if (!validMovement && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
else if (validMovement && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
}
void INotifyMoving.MovementTypeChanged(Actor self, MovementType types)

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
readonly GrantConditionOnPlayerResourcesInfo info;
PlayerResources playerResources;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnPlayerResources(GrantConditionOnPlayerResourcesInfo info)
{
@@ -49,7 +48,6 @@ namespace OpenRA.Mods.Common.Traits
// it refers to the same actor as self.Owner.PlayerActor
var playerActor = self.Info.Name == "player" ? self : self.Owner.PlayerActor;
playerResources = playerActor.Trait<PlayerResources>();
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
@@ -59,14 +57,14 @@ namespace OpenRA.Mods.Common.Traits
void ITick.Tick(Actor self)
{
if (string.IsNullOrEmpty(info.Condition) || conditionManager == null)
if (string.IsNullOrEmpty(info.Condition))
return;
var enabled = playerResources.Resources > info.Threshold;
if (enabled && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition);
else if (!enabled && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (enabled && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(info.Condition);
else if (!enabled && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
}
}

View File

@@ -31,8 +31,7 @@ namespace OpenRA.Mods.Common.Traits
public class GrantConditionOnPowerState : ConditionalTrait<GrantConditionOnPowerStateInfo>, INotifyOwnerChanged, INotifyPowerLevelChanged
{
PowerManager playerPower;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
bool validPowerState;
@@ -46,8 +45,6 @@ namespace OpenRA.Mods.Common.Traits
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
Update(self);
}
@@ -63,15 +60,12 @@ namespace OpenRA.Mods.Common.Traits
void Update(Actor self)
{
if (conditionManager == null)
return;
validPowerState = !IsTraitDisabled && Info.ValidPowerStates.HasFlag(playerPower.PowerState);
if (validPowerState && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
else if (!validPowerState && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (validPowerState && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
else if (!validPowerState && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
void INotifyPowerLevelChanged.PowerLevelChanged(Actor self)

View File

@@ -34,9 +34,8 @@ namespace OpenRA.Mods.Common.Traits
readonly GrantConditionOnPrerequisiteInfo info;
bool wasAvailable;
ConditionManager conditionManager;
GrantConditionOnPrerequisiteManager globalManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnPrerequisite(Actor self, GrantConditionOnPrerequisiteInfo info)
{
@@ -52,7 +51,6 @@ namespace OpenRA.Mods.Common.Traits
var playerActor = self.Info.Name == "player" ? self : self.Owner.PlayerActor;
globalManager = playerActor.Trait<GrantConditionOnPrerequisiteManager>();
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyAddedToWorld.AddedToWorld(Actor self)
@@ -74,13 +72,13 @@ namespace OpenRA.Mods.Common.Traits
public void PrerequisitesUpdated(Actor self, bool available)
{
if (available == wasAvailable || conditionManager == null)
if (available == wasAvailable)
return;
if (available && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition);
else if (!available && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (available && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(info.Condition);
else if (!available && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
wasAvailable = available;
}

View File

@@ -38,12 +38,11 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new GrantConditionOnProduction(init.Self, this); }
}
public class GrantConditionOnProduction : INotifyCreated, INotifyProduction, ITick, ISync, ISelectionBar
public class GrantConditionOnProduction : INotifyProduction, ITick, ISync, ISelectionBar
{
readonly GrantConditionOnProductionInfo info;
ConditionManager conditionManager;
int token = ConditionManager.InvalidConditionToken;
int token = Actor.InvalidConditionToken;
[Sync]
int ticks;
@@ -54,31 +53,26 @@ namespace OpenRA.Mods.Common.Traits
ticks = info.Duration;
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyProduction.UnitProduced(Actor self, Actor other, CPos exit)
{
if (info.Actors.Any() && !info.Actors.Select(a => a.ToLowerInvariant()).Contains(other.Info.Name))
return;
if (conditionManager != null && token == ConditionManager.InvalidConditionToken)
token = conditionManager.GrantCondition(self, info.Condition);
if (token == Actor.InvalidConditionToken)
token = self.GrantCondition(info.Condition);
ticks = info.Duration;
}
void ITick.Tick(Actor self)
{
if (info.Duration >= 0 && token != ConditionManager.InvalidConditionToken && --ticks < 0)
token = conditionManager.RevokeCondition(self, token);
if (info.Duration >= 0 && token != Actor.InvalidConditionToken && --ticks < 0)
token = self.RevokeCondition(token);
}
float ISelectionBar.GetValue()
{
if (!info.ShowSelectionBar || info.Duration < 0 || token == ConditionManager.InvalidConditionToken)
if (!info.ShowSelectionBar || info.Duration < 0 || token == Actor.InvalidConditionToken)
return 0;
return (float)ticks / info.Duration;

View File

@@ -74,11 +74,11 @@ namespace OpenRA.Mods.Common.Traits
// Grant condition when new layer is Subterranean and depth is lower than transition depth,
// revoke condition when new layer is not Subterranean and depth is at or higher than transition depth.
if (newLayer == ValidLayerType && depth < transitionDepth && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
else if (newLayer != ValidLayerType && depth > transitionDepth && conditionToken != ConditionManager.InvalidConditionToken)
if (newLayer == ValidLayerType && depth < transitionDepth && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.Condition);
else if (newLayer != ValidLayerType && depth > transitionDepth && conditionToken != Actor.InvalidConditionToken)
{
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
PlayTransitionAudioVisuals(self, self.Location);
}
}

View File

@@ -28,13 +28,12 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new GrantConditionOnTerrain(init, this); }
}
public class GrantConditionOnTerrain : INotifyCreated, ITick
public class GrantConditionOnTerrain : ITick
{
readonly GrantConditionOnTerrainInfo info;
readonly TileSet tileSet;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
string cachedTerrain;
public GrantConditionOnTerrain(ActorInitializer init, GrantConditionOnTerrainInfo info)
@@ -43,20 +42,12 @@ namespace OpenRA.Mods.Common.Traits
tileSet = init.World.Map.Rules.TileSet;
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void ITick.Tick(Actor self)
{
var cell = self.Location;
if (!self.World.Map.Contains(cell))
return;
if (conditionManager == null)
return;
// The terrain type may change between ticks without the actor moving
var currentTerrain = cell.Layer == 0 ? self.World.Map.GetTerrainInfo(cell).Type :
tileSet[self.World.GetCustomMovementLayers()[cell.Layer].GetTerrainIndex(cell)].Type;
@@ -64,10 +55,10 @@ namespace OpenRA.Mods.Common.Traits
var wantsGranted = info.TerrainTypes.Contains(currentTerrain);
if (currentTerrain != cachedTerrain)
{
if (wantsGranted && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition);
else if (!wantsGranted && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (wantsGranted && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(info.Condition);
else if (!wantsGranted && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
cachedTerrain = currentTerrain;

View File

@@ -23,33 +23,27 @@ namespace OpenRA.Mods.Common.Traits
object ITraitInfo.Create(ActorInitializer init) { return new GrantConditionWhileAiming(this); }
}
public class GrantConditionWhileAiming : INotifyCreated, INotifyAiming
public class GrantConditionWhileAiming : INotifyAiming
{
readonly GrantConditionWhileAimingInfo info;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
public GrantConditionWhileAiming(GrantConditionWhileAimingInfo info)
{
this.info = info;
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyAiming.StartedAiming(Actor self, AttackBase attack)
{
if (conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition);
if (conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(info.Condition);
}
void INotifyAiming.StoppedAiming(Actor self, AttackBase attack)
{
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
}
}

View File

@@ -40,8 +40,7 @@ namespace OpenRA.Mods.Common.Traits.Conditions
return;
var condition = info.Conditions.Random(self.World.SharedRandom);
var conditionManager = self.Trait<ConditionManager>();
conditionManager.GrantCondition(self, condition);
self.GrantCondition(condition);
}
}
}

View File

@@ -42,8 +42,7 @@ namespace OpenRA.Mods.Common.Traits
public class ToggleConditionOnOrder : PausableConditionalTrait<ToggleConditionOnOrderInfo>, IResolveOrder
{
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
// If the trait is paused this may be true with no condition granted
[Sync]
@@ -52,21 +51,11 @@ namespace OpenRA.Mods.Common.Traits
public ToggleConditionOnOrder(Actor self, ToggleConditionOnOrderInfo info)
: base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void SetCondition(Actor self, bool granted)
{
if (conditionManager == null)
return;
if (granted && conditionToken == ConditionManager.InvalidConditionToken)
if (granted && conditionToken == Actor.InvalidConditionToken)
{
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
conditionToken = self.GrantCondition(Info.Condition);
if (Info.EnabledSound != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.EnabledSound, self.Owner.Faction.InternalName);
@@ -74,9 +63,9 @@ namespace OpenRA.Mods.Common.Traits
if (Info.EnabledSpeech != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName);
}
else if (!granted && conditionToken != ConditionManager.InvalidConditionToken)
else if (!granted && conditionToken != Actor.InvalidConditionToken)
{
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
conditionToken = self.RevokeCondition(conditionToken);
if (Info.DisabledSound != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.DisabledSound, self.Owner.Faction.InternalName);

View File

@@ -43,19 +43,12 @@ namespace OpenRA.Mods.Common.Traits
}
}
ConditionManager conditionManager;
List<DemolishAction> actions = new List<DemolishAction>();
List<DemolishAction> removeActions = new List<DemolishAction>();
public Demolishable(DemolishableInfo info)
: base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
}
bool IDemolishable.IsValidTarget(Actor self, Actor saboteur)
{
return !IsTraitDisabled;
@@ -66,9 +59,9 @@ namespace OpenRA.Mods.Common.Traits
if (IsTraitDisabled)
return;
var token = ConditionManager.InvalidConditionToken;
if (conditionManager != null && !string.IsNullOrEmpty(Info.Condition))
token = conditionManager.GrantCondition(self, Info.Condition);
var token = Actor.InvalidConditionToken;
if (!string.IsNullOrEmpty(Info.Condition))
token = self.GrantCondition(Info.Condition);
actions.Add(new DemolishAction(saboteur, delay, token));
}
@@ -88,9 +81,9 @@ namespace OpenRA.Mods.Common.Traits
if (Util.ApplyPercentageModifiers(100, modifiers) > 0)
self.Kill(a.Saboteur);
else if (a.Token != ConditionManager.InvalidConditionToken)
else if (a.Token != Actor.InvalidConditionToken)
{
conditionManager.RevokeCondition(self, a.Token);
self.RevokeCondition(a.Token);
removeActions.Add(a);
}
}

View File

@@ -59,7 +59,6 @@ namespace OpenRA.Mods.Common.Traits
readonly int initialExperience;
readonly List<Pair<int, string>> nextLevel = new List<Pair<int, string>>();
ConditionManager conditionManager;
// Stored as a percentage of our value
[Sync]
@@ -87,7 +86,6 @@ namespace OpenRA.Mods.Common.Traits
foreach (var kv in info.Conditions)
nextLevel.Add(Pair.New(kv.Key * requiredExperience, kv.Value));
conditionManager = self.TraitOrDefault<ConditionManager>();
if (initialExperience > 0)
GiveExperience(initialExperience, info.SuppressLevelupAnimation);
}
@@ -115,8 +113,7 @@ namespace OpenRA.Mods.Common.Traits
while (Level < MaxLevel && experience >= nextLevel[Level].First)
{
if (conditionManager != null)
conditionManager.GrantCondition(self, nextLevel[Level].Second);
self.GrantCondition(nextLevel[Level].Second);
Level++;

View File

@@ -97,8 +97,7 @@ namespace OpenRA.Mods.Common.Traits
readonly ResourceLayer resLayer;
readonly ResourceClaimLayer claimLayer;
readonly Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
HarvesterResourceMultiplier[] resourceMultipliers;
[Sync]
@@ -135,7 +134,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
resourceMultipliers = self.TraitsImplementing<HarvesterResourceMultiplier>().ToArray();
conditionManager = self.TraitOrDefault<ConditionManager>();
UpdateCondition(self);
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
@@ -212,15 +210,15 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self)
{
if (string.IsNullOrEmpty(Info.EmptyCondition) || conditionManager == null)
if (string.IsNullOrEmpty(Info.EmptyCondition))
return;
var enabled = IsEmpty;
if (enabled && conditionToken == ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.EmptyCondition);
else if (!enabled && conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (enabled && conditionToken == Actor.InvalidConditionToken)
conditionToken = self.GrantCondition(Info.EmptyCondition);
else if (!enabled && conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
}
public void AcceptResource(Actor self, ResourceType type)

View File

@@ -35,7 +35,6 @@ namespace OpenRA.Mods.Common.Traits
class KillsSelf : ConditionalTrait<KillsSelfInfo>, INotifyAddedToWorld, ITick
{
int lifetime;
ConditionManager conditionManager;
public KillsSelf(Actor self, KillsSelfInfo info)
: base(info)
@@ -51,12 +50,6 @@ namespace OpenRA.Mods.Common.Traits
self.World.AddFrameEndTask(w => Kill(self));
}
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
void INotifyAddedToWorld.AddedToWorld(Actor self)
{
if (!IsTraitDisabled)
@@ -80,8 +73,8 @@ namespace OpenRA.Mods.Common.Traits
if (self.IsDead)
return;
if (conditionManager != null && !string.IsNullOrEmpty(Info.GrantsCondition))
conditionManager.GrantCondition(self, Info.GrantsCondition);
if (!string.IsNullOrEmpty(Info.GrantsCondition))
self.GrantCondition(Info.GrantsCondition);
if (Info.RemoveInstead || !self.Info.HasTraitInfo<IHealthInfo>())
self.Dispose();

View File

@@ -57,15 +57,14 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new Parachutable(init.Self, this); }
}
public class Parachutable : INotifyCreated, INotifyParachute
public class Parachutable : INotifyParachute
{
readonly ParachutableInfo info;
readonly IPositionable positionable;
public Actor IgnoreActor;
ConditionManager conditionManager;
int parachutingToken = ConditionManager.InvalidConditionToken;
int parachutingToken = Actor.InvalidConditionToken;
public Parachutable(Actor self, ParachutableInfo info)
{
@@ -75,17 +74,12 @@ namespace OpenRA.Mods.Common.Traits
public bool IsInAir { get; private set; }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyParachute.OnParachute(Actor self)
{
IsInAir = true;
if (conditionManager != null && parachutingToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.ParachutingCondition))
parachutingToken = conditionManager.GrantCondition(self, info.ParachutingCondition);
if (parachutingToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(info.ParachutingCondition))
parachutingToken = self.GrantCondition(info.ParachutingCondition);
self.NotifyBlocker(self.Location);
}
@@ -94,8 +88,8 @@ namespace OpenRA.Mods.Common.Traits
{
IsInAir = false;
if (parachutingToken != ConditionManager.InvalidConditionToken)
parachutingToken = conditionManager.RevokeCondition(self, parachutingToken);
if (parachutingToken != Actor.InvalidConditionToken)
parachutingToken = self.RevokeCondition(parachutingToken);
if (!info.KilledOnImpassableTerrain)
return;

View File

@@ -50,15 +50,14 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new Passenger(this); }
}
public class Passenger : INotifyCreated, IIssueOrder, IResolveOrder, IOrderVoice, INotifyRemovedFromWorld, INotifyEnteredCargo, INotifyExitedCargo, INotifyKilled, IObservesVariables
public class Passenger : IIssueOrder, IResolveOrder, IOrderVoice, INotifyRemovedFromWorld, INotifyEnteredCargo, INotifyExitedCargo, INotifyKilled, IObservesVariables
{
public readonly PassengerInfo Info;
public Actor Transport;
bool requireForceMove;
ConditionManager conditionManager;
int anyCargoToken = ConditionManager.InvalidConditionToken;
int specificCargoToken = ConditionManager.InvalidConditionToken;
int anyCargoToken = Actor.InvalidConditionToken;
int specificCargoToken = Actor.InvalidConditionToken;
public Passenger(PassengerInfo info)
{
@@ -75,11 +74,6 @@ namespace OpenRA.Mods.Common.Traits
}
}
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
{
if (order.OrderID == "EnterTransport")
@@ -126,14 +120,12 @@ namespace OpenRA.Mods.Common.Traits
void INotifyEnteredCargo.OnEnteredCargo(Actor self, Actor cargo)
{
string specificCargoCondition;
if (conditionManager != null)
{
if (anyCargoToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CargoCondition))
anyCargoToken = conditionManager.GrantCondition(self, Info.CargoCondition);
if (specificCargoToken == ConditionManager.InvalidConditionToken && Info.CargoConditions.TryGetValue(cargo.Info.Name, out specificCargoCondition))
specificCargoToken = conditionManager.GrantCondition(self, specificCargoCondition);
}
if (anyCargoToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CargoCondition))
anyCargoToken = self.GrantCondition(Info.CargoCondition);
if (specificCargoToken == Actor.InvalidConditionToken && Info.CargoConditions.TryGetValue(cargo.Info.Name, out specificCargoCondition))
specificCargoToken = self.GrantCondition(specificCargoCondition);
// Allow scripted / initial actors to move from the unload point back into the cell grid on unload
// This is handled by the RideTransport activity for player-loaded cargo
@@ -148,11 +140,11 @@ namespace OpenRA.Mods.Common.Traits
void INotifyExitedCargo.OnExitedCargo(Actor self, Actor cargo)
{
if (anyCargoToken != ConditionManager.InvalidConditionToken)
anyCargoToken = conditionManager.RevokeCondition(self, anyCargoToken);
if (anyCargoToken != Actor.InvalidConditionToken)
anyCargoToken = self.RevokeCondition(anyCargoToken);
if (specificCargoToken != ConditionManager.InvalidConditionToken)
specificCargoToken = conditionManager.RevokeCondition(self, specificCargoToken);
if (specificCargoToken != Actor.InvalidConditionToken)
specificCargoToken = self.RevokeCondition(specificCargoToken);
}
void IResolveOrder.ResolveOrder(Actor self, Order order)

View File

@@ -49,8 +49,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly PluggableInfo Info;
readonly string initialPlug;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
int conditionToken = Actor.InvalidConditionToken;
Dictionary<string, bool> plugTypesAvailability = null;
string active;
@@ -73,8 +72,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
if (!string.IsNullOrEmpty(initialPlug))
EnablePlug(self, initialPlug);
}
@@ -96,10 +93,10 @@ namespace OpenRA.Mods.Common.Traits
if (!Info.Conditions.TryGetValue(type, out condition))
return;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
self.RevokeCondition(conditionToken);
conditionToken = conditionManager.GrantCondition(self, condition);
conditionToken = self.GrantCondition(condition);
active = type;
}
@@ -108,8 +105,8 @@ namespace OpenRA.Mods.Common.Traits
if (type != active)
return;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
active = null;
}

View File

@@ -27,8 +27,7 @@ namespace OpenRA.Mods.Common.Traits
public class AffectedByPowerOutage : ConditionalTrait<AffectedByPowerOutageInfo>, INotifyOwnerChanged, ISelectionBar, INotifyCreated, INotifyAddedToWorld
{
PowerManager playerPower;
ConditionManager conditionManager;
int token = ConditionManager.InvalidConditionToken;
int token = Actor.InvalidConditionToken;
public AffectedByPowerOutage(Actor self, AffectedByPowerOutageInfo info)
: base(info)
@@ -40,13 +39,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void TraitEnabled(Actor self) { UpdateStatus(self); }
protected override void TraitDisabled(Actor self) { Revoke(self); }
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
float ISelectionBar.GetValue()
{
if (IsTraitDisabled || playerPower.PowerOutageRemainingTicks <= 0)
@@ -72,14 +64,14 @@ namespace OpenRA.Mods.Common.Traits
void Grant(Actor self)
{
if (token == ConditionManager.InvalidConditionToken)
token = conditionManager.GrantCondition(self, Info.Condition);
if (token == Actor.InvalidConditionToken)
token = self.GrantCondition(Info.Condition);
}
void Revoke(Actor self)
{
if (token != ConditionManager.InvalidConditionToken)
token = conditionManager.RevokeCondition(self, token);
if (token != Actor.InvalidConditionToken)
token = self.RevokeCondition(token);
}
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Visualizes the remaining time for a condition.")]
class TimedConditionBarInfo : ITraitInfo, Requires<ConditionManagerInfo>
class TimedConditionBarInfo : ITraitInfo
{
[FieldLoader.Require]
[Desc("Condition that this bar corresponds to")]

View File

@@ -39,8 +39,7 @@ namespace OpenRA.Mods.Common.Traits.Render
readonly WithSpriteBody[] wsbs;
readonly bool skipMakeAnimation;
ConditionManager conditionManager;
int token = ConditionManager.InvalidConditionToken;
int token = Actor.InvalidConditionToken;
public WithMakeAnimation(ActorInitializer init, WithMakeAnimationInfo info)
{
@@ -52,15 +51,14 @@ namespace OpenRA.Mods.Common.Traits.Render
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
if (!skipMakeAnimation)
Forward(self, () => { });
}
public void Forward(Actor self, Action onComplete)
{
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken)
token = conditionManager.GrantCondition(self, info.Condition);
if (!string.IsNullOrEmpty(info.Condition) && token == Actor.InvalidConditionToken)
token = self.GrantCondition(info.Condition);
var wsb = wsbs.FirstEnabledTraitOrDefault();
@@ -71,8 +69,8 @@ namespace OpenRA.Mods.Common.Traits.Render
{
self.World.AddFrameEndTask(w =>
{
if (token != ConditionManager.InvalidConditionToken)
token = conditionManager.RevokeCondition(self, token);
if (token != Actor.InvalidConditionToken)
token = self.RevokeCondition(token);
// TODO: Rewrite this to use a trait notification for save game support
onComplete();
@@ -82,8 +80,8 @@ namespace OpenRA.Mods.Common.Traits.Render
public void Reverse(Actor self, Action onComplete)
{
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken)
token = conditionManager.GrantCondition(self, info.Condition);
if (!string.IsNullOrEmpty(info.Condition) && token == Actor.InvalidConditionToken)
token = self.GrantCondition(info.Condition);
var wsb = wsbs.FirstEnabledTraitOrDefault();
@@ -94,8 +92,8 @@ namespace OpenRA.Mods.Common.Traits.Render
{
self.World.AddFrameEndTask(w =>
{
if (token != ConditionManager.InvalidConditionToken)
token = conditionManager.RevokeCondition(self, token);
if (token != Actor.InvalidConditionToken)
token = self.RevokeCondition(token);
// TODO: Rewrite this to use a trait notification for save game support
onComplete();
@@ -116,8 +114,8 @@ namespace OpenRA.Mods.Common.Traits.Render
if (wsb != null)
wsb.DefaultAnimation.PlayFetchIndex(info.Sequence, () => 0);
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition))
token = conditionManager.GrantCondition(self, info.Condition);
if (!string.IsNullOrEmpty(info.Condition))
token = self.GrantCondition(info.Condition);
self.QueueActivity(queued, activity);
});

View File

@@ -175,26 +175,6 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation]
public interface INotifyExitedCargo { void OnExitedCargo(Actor self, Actor cargo); }
[RequireExplicitImplementation]
public interface IObservesVariablesInfo : ITraitInfo { }
public delegate void VariableObserverNotifier(Actor self, IReadOnlyDictionary<string, int> variables);
public struct VariableObserver
{
public VariableObserverNotifier Notifier;
public IEnumerable<string> Variables;
public VariableObserver(VariableObserverNotifier notifier, IEnumerable<string> variables)
{
Notifier = notifier;
Variables = variables;
}
}
public interface IObservesVariables
{
IEnumerable<VariableObserver> GetVariableObservers();
}
public interface INotifyHarvesterAction
{
void MovingToResources(Actor self, CPos targetCell);

View File

@@ -0,0 +1,34 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class RemoveConditionManager : UpdateRule
{
public override string Name { get { return "ConditionManager trait has been removed."; } }
public override string Description
{
get
{
return "ConditionManager trait has been removed. Its functionality has been integrated into the actor itself.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
actorNode.RemoveNodes("ConditionManager");
yield break;
}
}
}

View File

@@ -62,6 +62,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new MoveClassicFacingFudge(),
new RenameWithNukeLaunch(),
new SpawnActorPowerDefaultEffect(),
new RemoveConditionManager(),
})
};

View File

@@ -29,7 +29,6 @@ namespace OpenRA.Mods.D2k.Activities
readonly Target target;
readonly Sandworm sandworm;
readonly ConditionManager conditionManager;
readonly WeaponInfo weapon;
readonly Armament armament;
readonly AttackSwallow swallow;
@@ -39,7 +38,7 @@ namespace OpenRA.Mods.D2k.Activities
int countdown;
CPos burrowLocation;
AttackState stance;
int attackingToken = ConditionManager.InvalidConditionToken;
int attackingToken = Actor.InvalidConditionToken;
public SwallowActor(Actor self, Target target, Armament a, IFacing facing)
{
@@ -50,7 +49,6 @@ namespace OpenRA.Mods.D2k.Activities
sandworm = self.Trait<Sandworm>();
positionable = self.Trait<Mobile>();
swallow = self.Trait<AttackSwallow>();
conditionManager = self.TraitOrDefault<ConditionManager>();
}
bool AttackTargets(Actor self, IEnumerable<Actor> targets)
@@ -103,9 +101,8 @@ namespace OpenRA.Mods.D2k.Activities
stance = AttackState.Burrowed;
countdown = swallow.Info.AttackDelay;
burrowLocation = self.Location;
if (conditionManager != null && attackingToken == ConditionManager.InvalidConditionToken &&
!string.IsNullOrEmpty(swallow.Info.AttackingCondition))
attackingToken = conditionManager.GrantCondition(self, swallow.Info.AttackingCondition);
if (attackingToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(swallow.Info.AttackingCondition))
attackingToken = self.GrantCondition(swallow.Info.AttackingCondition);
break;
case AttackState.Burrowed:
if (--countdown > 0)
@@ -164,8 +161,8 @@ namespace OpenRA.Mods.D2k.Activities
void RevokeCondition(Actor self)
{
if (attackingToken != ConditionManager.InvalidConditionToken)
attackingToken = conditionManager.RevokeCondition(self, attackingToken);
if (attackingToken != Actor.InvalidConditionToken)
attackingToken = self.RevokeCondition(attackingToken);
}
}
}

View File

@@ -5,7 +5,6 @@
GivesExperience:
PlayerExperienceModifier: 1
ScriptTriggers:
ConditionManager:
RenderDebugState:
^SpriteActor:
@@ -779,7 +778,6 @@
^CivBuilding:
Inherits: ^Building
-ConditionManager:
Tooltip:
GenericName: Civilian Building
GenericStancePrefix: false

View File

@@ -58,6 +58,5 @@ Player:
GrantConditionOnPrerequisiteManager:
ResourceStorageWarning:
PlayerExperience:
ConditionManager:
GameSaveViewportManager:
PlayerRadarTerrain:

View File

@@ -10,7 +10,6 @@ spicebloom.spawnpoint:
Sequence: grow3
BodyOrientation:
QuantizedFacings: 1
ConditionManager:
GrantConditionOnTerrain:
Condition: clearsand
TerrainTypes: SpiceSand
@@ -125,7 +124,6 @@ sandworm:
TerrainTypes: Sand, Dune, SpiceSand, Spice
MovingInterval: 3
RequiresCondition: !attacking
ConditionManager:
RevealOnFire:
Duration: 50
Radius: 2c512

View File

@@ -5,7 +5,6 @@
GivesExperience:
PlayerExperienceModifier: 1
ScriptTriggers:
ConditionManager:
RenderDebugState:
^SpriteActor:

View File

@@ -150,6 +150,5 @@ Player:
ResourceStorageWarning:
AdviceInterval: 26
PlayerExperience:
ConditionManager:
GameSaveViewportManager:
PlayerRadarTerrain:

View File

@@ -4,7 +4,6 @@
GivesExperience:
PlayerExperienceModifier: 1
ScriptTriggers:
ConditionManager:
RenderDebugState:
^SpriteActor:
@@ -1130,7 +1129,6 @@
ShadowImage: parach-shadow
ShadowSequence: idle
RequiresCondition: parachute
ConditionManager:
MapEditorData:
Categories: System

View File

@@ -149,6 +149,5 @@ Player:
Sequence: veteran
ResourceStorageWarning:
PlayerExperience:
ConditionManager:
GameSaveViewportManager:
PlayerRadarTerrain:

View File

@@ -5,7 +5,6 @@
GivesExperience:
PlayerExperienceModifier: 1
ScriptTriggers:
ConditionManager:
RenderDebugState:
^SpriteActor:
@@ -502,7 +501,6 @@
RequiresCondition: !being-demolished
SellSounds: cashturn.aud
ScriptTriggers:
ConditionManager:
Health:
HitShape:
Type: Rectangle

View File

@@ -182,7 +182,6 @@ JUMPJET.Husk:
Sequence: die-falling
Health:
HitShape:
ConditionManager:
GrantConditionOnTerrain:
TerrainTypes: Water
Condition: water-death

View File

@@ -122,6 +122,5 @@ Player:
Id: unrestricted
ResourceStorageWarning:
PlayerExperience:
ConditionManager:
GameSaveViewportManager:
PlayerRadarTerrain: