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; } internal SyncHash[] SyncHashes { get; private set; }
readonly IFacing facing; readonly IFacing facing;
@@ -93,6 +118,8 @@ namespace OpenRA
{ {
var init = new ActorInitializer(this, initDict); var init = new ActorInitializer(this, initDict);
readOnlyConditionCache = new ReadOnlyDictionary<string, int>(conditionCache);
World = world; World = world;
ActorID = world.NextAID(); ActorID = world.NextAID();
if (initDict.Contains<OwnerInit>()) if (initDict.Contains<OwnerInit>())
@@ -148,9 +175,36 @@ namespace OpenRA
{ {
created = true; created = true;
// Make sure traits are usable for condition notifiers
foreach (var t in TraitsImplementing<INotifyCreated>()) foreach (var t in TraitsImplementing<INotifyCreated>())
t.Created(this); 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 // 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 // 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; ICreationActivity creationActivity = null;
@@ -454,6 +508,60 @@ namespace OpenRA
return new[] { CenterPosition }; 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 #region Scripting interface
Lazy<ScriptActorInterface> luaInterface; Lazy<ScriptActorInterface> luaInterface;

View File

@@ -539,4 +539,24 @@ namespace OpenRA.Traits
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface ICreationActivity { Activity GetCreationActivity(); } 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; readonly AttackLeapInfo info;
ConditionManager conditionManager; int leapToken = Actor.InvalidConditionToken;
int leapToken = ConditionManager.InvalidConditionToken;
public AttackLeap(Actor self, AttackLeapInfo info) public AttackLeap(Actor self, AttackLeapInfo info)
: base(self, info) : base(self, info)
@@ -43,12 +42,6 @@ namespace OpenRA.Mods.Cnc.Traits
this.info = info; this.info = info;
} }
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
protected override bool CanAttack(Actor self, Target target) protected override bool CanAttack(Actor self, Target target)
{ {
if (target.Type != TargetType.Actor) if (target.Type != TargetType.Actor)
@@ -62,14 +55,14 @@ namespace OpenRA.Mods.Cnc.Traits
public void GrantLeapCondition(Actor self) public void GrantLeapCondition(Actor self)
{ {
if (conditionManager != null && !string.IsNullOrEmpty(info.LeapCondition)) if (!string.IsNullOrEmpty(info.LeapCondition))
leapToken = conditionManager.GrantCondition(self, info.LeapCondition); leapToken = self.GrantCondition(info.LeapCondition);
} }
public void RevokeLeapCondition(Actor self) public void RevokeLeapCondition(Actor self)
{ {
if (leapToken != ConditionManager.InvalidConditionToken) if (leapToken != Actor.InvalidConditionToken)
leapToken = conditionManager.RevokeCondition(self, leapToken); leapToken = self.RevokeCondition(leapToken);
} }
public override Activity GetAttackActivity(Actor self, AttackSource source, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor) 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 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 IDeathActorInitModifier, ITransformActorInitModifier
{ {
readonly ConyardChronoReturnInfo info; readonly ConyardChronoReturnInfo info;
@@ -70,8 +70,7 @@ namespace OpenRA.Mods.Cnc.Traits
readonly Actor self; readonly Actor self;
readonly string faction; readonly string faction;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
Actor chronosphere; Actor chronosphere;
int duration; int duration;
@@ -110,11 +109,6 @@ namespace OpenRA.Mods.Cnc.Traits
chronosphere = init.Get<ChronoshiftChronosphereInit, Actor>(); chronosphere = init.Get<ChronoshiftChronosphereInit, Actor>();
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
IEnumerable<VariableObserver> IObservesVariables.GetVariableObservers() IEnumerable<VariableObserver> IObservesVariables.GetVariableObservers()
{ {
if (info.ReturnOriginalActorOnCondition != null) if (info.ReturnOriginalActorOnCondition != null)
@@ -128,8 +122,8 @@ namespace OpenRA.Mods.Cnc.Traits
void TriggerVortex() void TriggerVortex()
{ {
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && conditionToken == ConditionManager.InvalidConditionToken) if (!string.IsNullOrEmpty(info.Condition) && conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition); conditionToken = self.GrantCondition(info.Condition);
triggered = true; triggered = true;
@@ -140,8 +134,8 @@ namespace OpenRA.Mods.Cnc.Traits
wsb.PlayCustomAnimation(self, info.Sequence, () => wsb.PlayCustomAnimation(self, info.Sequence, () =>
{ {
triggered = false; triggered = false;
if (conditionToken != ConditionManager.InvalidConditionToken) if (conditionToken != Actor.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken); 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); } 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 INotifyDamage, INotifyUnload, INotifyDemolition, INotifyInfiltration, ITick
{ {
public ActorInfo AsActor { get; private set; } public ActorInfo AsActor { get; private set; }
@@ -112,9 +112,8 @@ namespace OpenRA.Mods.Cnc.Traits
readonly Actor self; readonly Actor self;
readonly DisguiseInfo info; readonly DisguiseInfo info;
ConditionManager conditionManager; int disguisedToken = Actor.InvalidConditionToken;
int disguisedToken = ConditionManager.InvalidConditionToken; int disguisedAsToken = Actor.InvalidConditionToken;
int disguisedAsToken = ConditionManager.InvalidConditionToken;
CPos? lastPos; CPos? lastPos;
public Disguise(Actor self, DisguiseInfo info) public Disguise(Actor self, DisguiseInfo info)
@@ -125,11 +124,6 @@ namespace OpenRA.Mods.Cnc.Traits
AsActor = self.Info; AsActor = self.Info;
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
IEnumerable<IOrderTargeter> IIssueOrder.Orders IEnumerable<IOrderTargeter> IIssueOrder.Orders
{ {
get get
@@ -225,25 +219,22 @@ namespace OpenRA.Mods.Cnc.Traits
foreach (var t in self.TraitsImplementing<INotifyEffectiveOwnerChanged>()) foreach (var t in self.TraitsImplementing<INotifyEffectiveOwnerChanged>())
t.OnEffectiveOwnerChanged(self, oldEffectiveOwner, AsPlayer); t.OnEffectiveOwnerChanged(self, oldEffectiveOwner, AsPlayer);
if (conditionManager != null) if (Disguised != oldDisguiseSetting)
{ {
if (Disguised != oldDisguiseSetting) if (Disguised && disguisedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition))
{ disguisedToken = self.GrantCondition(info.DisguisedCondition);
if (Disguised && disguisedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition)) else if (!Disguised && disguisedToken != Actor.InvalidConditionToken)
disguisedToken = conditionManager.GrantCondition(self, info.DisguisedCondition); disguisedToken = self.RevokeCondition(disguisedToken);
else if (!Disguised && disguisedToken != ConditionManager.InvalidConditionToken) }
disguisedToken = conditionManager.RevokeCondition(self, disguisedToken);
}
if (AsActor != oldEffectiveActor) if (AsActor != oldEffectiveActor)
{ {
if (disguisedAsToken != ConditionManager.InvalidConditionToken) if (disguisedAsToken != Actor.InvalidConditionToken)
disguisedAsToken = conditionManager.RevokeCondition(self, disguisedAsToken); disguisedAsToken = self.RevokeCondition(disguisedAsToken);
string disguisedAsCondition; string disguisedAsCondition;
if (info.DisguisedAsConditions.TryGetValue(AsActor.Name, out 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; readonly MadTankInfo info;
ConditionManager conditionManager;
public MadTank(Actor self, MadTankInfo info) public MadTank(Actor self, MadTankInfo info)
{ {
this.info = info; this.info = info;
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
public IEnumerable<IOrderTargeter> Orders public IEnumerable<IOrderTargeter> Orders
{ {
get get
@@ -195,8 +188,8 @@ namespace OpenRA.Mods.Cnc.Traits
if (target.Type == TargetType.Invalid) if (target.Type == TargetType.Invalid)
return true; return true;
if (mad.conditionManager != null && !string.IsNullOrEmpty(mad.info.DeployedCondition)) if (!string.IsNullOrEmpty(mad.info.DeployedCondition))
mad.conditionManager.GrantCondition(self, mad.info.DeployedCondition); self.GrantCondition(mad.info.DeployedCondition);
self.World.AddFrameEndTask(w => EjectDriver()); self.World.AddFrameEndTask(w => EjectDriver());
if (mad.info.ThumpSequence != null) if (mad.info.ThumpSequence != null)

View File

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

View File

@@ -12,7 +12,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Lint namespace OpenRA.Mods.Common.Lint
@@ -60,9 +59,6 @@ namespace OpenRA.Mods.Common.Lint
var ungranted = consumed.Except(granted); var ungranted = consumed.Except(granted);
if (ungranted.Any()) if (ungranted.Any())
emitError("Actor type `{0}` consumes conditions that are not granted: {1}".F(actorInfo.Key, ungranted.JoinWith(", "))); 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; Repairable repairable;
Rearmable rearmable; Rearmable rearmable;
IAircraftCenterPositionOffset[] positionOffsets; IAircraftCenterPositionOffset[] positionOffsets;
ConditionManager conditionManager;
IDisposable reservation; IDisposable reservation;
IEnumerable<int> speedModifiers; IEnumerable<int> speedModifiers;
INotifyMoving[] notifyMoving; INotifyMoving[] notifyMoving;
@@ -230,8 +229,8 @@ namespace OpenRA.Mods.Common.Traits
bool airborne; bool airborne;
bool cruising; bool cruising;
int airborneToken = ConditionManager.InvalidConditionToken; int airborneToken = Actor.InvalidConditionToken;
int cruisingToken = ConditionManager.InvalidConditionToken; int cruisingToken = Actor.InvalidConditionToken;
MovementType movementTypes; MovementType movementTypes;
WPos cachedPosition; WPos cachedPosition;
@@ -293,7 +292,6 @@ namespace OpenRA.Mods.Common.Traits
{ {
repairable = self.TraitOrDefault<Repairable>(); repairable = self.TraitOrDefault<Repairable>();
rearmable = self.TraitOrDefault<Rearmable>(); rearmable = self.TraitOrDefault<Rearmable>();
conditionManager = self.TraitOrDefault<ConditionManager>();
speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray().Select(sm => sm.GetSpeedModifier()); speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray().Select(sm => sm.GetSpeedModifier());
cachedPosition = self.CenterPosition; cachedPosition = self.CenterPosition;
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray(); notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
@@ -1116,8 +1114,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
airborne = true; airborne = true;
if (conditionManager != null && !string.IsNullOrEmpty(Info.AirborneCondition) && airborneToken == ConditionManager.InvalidConditionToken) if (!string.IsNullOrEmpty(Info.AirborneCondition) && airborneToken == Actor.InvalidConditionToken)
airborneToken = conditionManager.GrantCondition(self, Info.AirborneCondition); airborneToken = self.GrantCondition(Info.AirborneCondition);
} }
void OnAirborneAltitudeLeft() void OnAirborneAltitudeLeft()
@@ -1126,8 +1124,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
airborne = false; airborne = false;
if (conditionManager != null && airborneToken != ConditionManager.InvalidConditionToken) if (airborneToken != Actor.InvalidConditionToken)
airborneToken = conditionManager.RevokeCondition(self, airborneToken); airborneToken = self.RevokeCondition(airborneToken);
} }
#endregion #endregion
@@ -1140,8 +1138,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
cruising = true; cruising = true;
if (conditionManager != null && !string.IsNullOrEmpty(Info.CruisingCondition) && cruisingToken == ConditionManager.InvalidConditionToken) if (!string.IsNullOrEmpty(Info.CruisingCondition) && cruisingToken == Actor.InvalidConditionToken)
cruisingToken = conditionManager.GrantCondition(self, Info.CruisingCondition); cruisingToken = self.GrantCondition(Info.CruisingCondition);
} }
void OnCruisingAltitudeLeft() void OnCruisingAltitudeLeft()
@@ -1150,8 +1148,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
cruising = false; cruising = false;
if (conditionManager != null && cruisingToken != ConditionManager.InvalidConditionToken) if (cruisingToken != Actor.InvalidConditionToken)
cruisingToken = conditionManager.RevokeCondition(self, cruisingToken); cruisingToken = self.RevokeCondition(cruisingToken);
} }
#endregion #endregion

View File

@@ -51,7 +51,6 @@ namespace OpenRA.Mods.Common.Traits
{ {
public readonly AmmoPoolInfo Info; public readonly AmmoPoolInfo Info;
readonly Stack<int> tokens = new Stack<int>(); readonly Stack<int> tokens = new Stack<int>();
ConditionManager conditionManager;
// HACK: Temporarily needed until Rearm activity is gone for good // HACK: Temporarily needed until Rearm activity is gone for good
[Sync] [Sync]
@@ -91,7 +90,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
conditionManager = self.TraitOrDefault<ConditionManager>();
UpdateCondition(self); UpdateCondition(self);
// HACK: Temporarily needed until Rearm activity is gone for good // HACK: Temporarily needed until Rearm activity is gone for good
@@ -108,14 +106,14 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self) void UpdateCondition(Actor self)
{ {
if (conditionManager == null || string.IsNullOrEmpty(Info.AmmoCondition)) if (string.IsNullOrEmpty(Info.AmmoCondition))
return; return;
while (CurrentAmmoCount > tokens.Count && tokens.Count < Info.Ammo) 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) 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; INotifyBurstComplete[] notifyBurstComplete;
INotifyAttack[] notifyAttacks; INotifyAttack[] notifyAttacks;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
IEnumerable<int> rangeModifiers; IEnumerable<int> rangeModifiers;
IEnumerable<int> reloadModifiers; IEnumerable<int> reloadModifiers;
@@ -169,7 +168,6 @@ namespace OpenRA.Mods.Common.Traits
coords = self.Trait<BodyOrientation>(); coords = self.Trait<BodyOrientation>();
notifyBurstComplete = self.TraitsImplementing<INotifyBurstComplete>().ToArray(); notifyBurstComplete = self.TraitsImplementing<INotifyBurstComplete>().ToArray();
notifyAttacks = self.TraitsImplementing<INotifyAttack>().ToArray(); notifyAttacks = self.TraitsImplementing<INotifyAttack>().ToArray();
conditionManager = self.TraitOrDefault<ConditionManager>();
rangeModifiers = self.TraitsImplementing<IRangeModifier>().ToArray().Select(m => m.GetRangeModifier()); rangeModifiers = self.TraitsImplementing<IRangeModifier>().ToArray().Select(m => m.GetRangeModifier());
reloadModifiers = self.TraitsImplementing<IReloadModifier>().ToArray().Select(m => m.GetReloadModifier()); reloadModifiers = self.TraitsImplementing<IReloadModifier>().ToArray().Select(m => m.GetReloadModifier());
@@ -181,15 +179,15 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self) void UpdateCondition(Actor self)
{ {
if (string.IsNullOrEmpty(Info.ReloadingCondition) || conditionManager == null) if (string.IsNullOrEmpty(Info.ReloadingCondition))
return; return;
var enabled = !IsTraitDisabled && IsReloading; var enabled = !IsTraitDisabled && IsReloading;
if (enabled && conditionToken == ConditionManager.InvalidConditionToken) if (enabled && conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.ReloadingCondition); conditionToken = self.GrantCondition(Info.ReloadingCondition);
else if (!enabled && conditionToken != ConditionManager.InvalidConditionToken) else if (!enabled && conditionToken != Actor.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken); conditionToken = self.RevokeCondition(conditionToken);
} }
protected virtual void Tick(Actor self) protected virtual void Tick(Actor self)

View File

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

View File

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

View File

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

View File

@@ -57,7 +57,6 @@ namespace OpenRA.Mods.Common.Traits
readonly IHealth health; readonly IHealth health;
readonly Predicate<Player> isNotActiveAlly; readonly Predicate<Player> isNotActiveAlly;
readonly Stack<int> repairTokens = new Stack<int>(); readonly Stack<int> repairTokens = new Stack<int>();
ConditionManager conditionManager;
int remainingTicks; int remainingTicks;
public readonly List<Player> Repairers = new List<Player>(); 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; 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] [Sync]
public int RepairersHash public int RepairersHash
{ {
@@ -90,15 +83,15 @@ namespace OpenRA.Mods.Common.Traits
void UpdateCondition(Actor self) void UpdateCondition(Actor self)
{ {
if (conditionManager == null || string.IsNullOrEmpty(Info.RepairCondition)) if (string.IsNullOrEmpty(Info.RepairCondition))
return; return;
var currentRepairers = Repairers.Count; var currentRepairers = Repairers.Count;
while (Repairers.Count > repairTokens.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) while (Repairers.Count < repairTokens.Count && repairTokens.Count > 0)
conditionManager.RevokeCondition(self, repairTokens.Pop()); self.RevokeCondition(repairTokens.Pop());
} }
public void RepairBuilding(Actor self, Player player) 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 public class CaptureManager : INotifyCreated, INotifyCapture, ITick, IDisableEnemyAutoTarget
{ {
readonly CaptureManagerInfo info; readonly CaptureManagerInfo info;
ConditionManager conditionManager;
IMove move; IMove move;
ICaptureProgressWatcher[] progressWatchers; ICaptureProgressWatcher[] progressWatchers;
@@ -75,8 +74,8 @@ namespace OpenRA.Mods.Common.Traits
CaptureManager currentTargetManager; CaptureManager currentTargetManager;
int currentTargetDelay; int currentTargetDelay;
int currentTargetTotal; int currentTargetTotal;
int capturingToken = ConditionManager.InvalidConditionToken; int capturingToken = Actor.InvalidConditionToken;
int beingCapturedToken = ConditionManager.InvalidConditionToken; int beingCapturedToken = Actor.InvalidConditionToken;
bool enteringCurrentTarget; bool enteringCurrentTarget;
HashSet<Actor> currentCaptors = new HashSet<Actor>(); HashSet<Actor> currentCaptors = new HashSet<Actor>();
@@ -90,7 +89,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
conditionManager = self.TraitOrDefault<ConditionManager>();
move = self.TraitOrDefault<IMove>(); move = self.TraitOrDefault<IMove>();
progressWatchers = self.TraitsImplementing<ICaptureProgressWatcher>().ToArray(); progressWatchers = self.TraitsImplementing<ICaptureProgressWatcher>().ToArray();
@@ -206,13 +204,13 @@ namespace OpenRA.Mods.Common.Traits
else else
currentTargetDelay += 1; currentTargetDelay += 1;
if (conditionManager != null && !string.IsNullOrEmpty(info.CapturingCondition) && if (!string.IsNullOrEmpty(info.CapturingCondition) &&
capturingToken == ConditionManager.InvalidConditionToken) capturingToken == Actor.InvalidConditionToken)
capturingToken = conditionManager.GrantCondition(self, info.CapturingCondition); capturingToken = self.GrantCondition(info.CapturingCondition);
if (targetManager.conditionManager != null && !string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) && if (!string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) &&
targetManager.beingCapturedToken == ConditionManager.InvalidConditionToken) targetManager.beingCapturedToken == Actor.InvalidConditionToken)
targetManager.beingCapturedToken = targetManager.conditionManager.GrantCondition(target, targetManager.info.BeingCapturedCondition); targetManager.beingCapturedToken = target.GrantCondition(targetManager.info.BeingCapturedCondition);
captures = enabledCaptures captures = enabledCaptures
.OrderBy(c => c.Info.CaptureDelay) .OrderBy(c => c.Info.CaptureDelay)
@@ -262,11 +260,11 @@ namespace OpenRA.Mods.Common.Traits
foreach (var w in targetManager.progressWatchers) foreach (var w in targetManager.progressWatchers)
w.Update(target, self, target, 0, 0); w.Update(target, self, target, 0, 0);
if (capturingToken != ConditionManager.InvalidConditionToken) if (capturingToken != Actor.InvalidConditionToken)
capturingToken = conditionManager.RevokeCondition(self, capturingToken); capturingToken = self.RevokeCondition(capturingToken);
if (targetManager.beingCapturedToken != ConditionManager.InvalidConditionToken) if (targetManager.beingCapturedToken != Actor.InvalidConditionToken)
targetManager.beingCapturedToken = targetManager.conditionManager.RevokeCondition(self, targetManager.beingCapturedToken); targetManager.beingCapturedToken = self.RevokeCondition(targetManager.beingCapturedToken);
currentTarget = null; currentTarget = null;
currentTargetManager = null; currentTargetManager = null;

View File

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

View File

@@ -44,10 +44,9 @@ namespace OpenRA.Mods.Common.Traits
public class Carryable : ConditionalTrait<CarryableInfo> public class Carryable : ConditionalTrait<CarryableInfo>
{ {
ConditionManager conditionManager; int reservedToken = Actor.InvalidConditionToken;
int reservedToken = ConditionManager.InvalidConditionToken; int carriedToken = Actor.InvalidConditionToken;
int carriedToken = ConditionManager.InvalidConditionToken; int lockedToken = Actor.InvalidConditionToken;
int lockedToken = ConditionManager.InvalidConditionToken;
Mobile mobile; Mobile mobile;
IDelayCarryallPickup[] delayPickups; IDelayCarryallPickup[] delayPickups;
@@ -66,7 +65,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void Created(Actor self) protected override void Created(Actor self)
{ {
conditionManager = self.Trait<ConditionManager>();
mobile = self.TraitOrDefault<Mobile>(); mobile = self.TraitOrDefault<Mobile>();
delayPickups = self.TraitsImplementing<IDelayCarryallPickup>().ToArray(); delayPickups = self.TraitsImplementing<IDelayCarryallPickup>().ToArray();
@@ -80,8 +78,8 @@ namespace OpenRA.Mods.Common.Traits
attached = true; attached = true;
if (carriedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CarriedCondition)) if (carriedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CarriedCondition))
carriedToken = conditionManager.GrantCondition(self, Info.CarriedCondition); carriedToken = self.GrantCondition(Info.CarriedCondition);
} }
// This gets called by carrier after we touched down // This gets called by carrier after we touched down
@@ -92,8 +90,8 @@ namespace OpenRA.Mods.Common.Traits
attached = false; attached = false;
if (carriedToken != ConditionManager.InvalidConditionToken) if (carriedToken != Actor.InvalidConditionToken)
carriedToken = conditionManager.RevokeCondition(self, carriedToken); carriedToken = self.RevokeCondition(carriedToken);
} }
public virtual bool Reserve(Actor self, Actor carrier) public virtual bool Reserve(Actor self, Actor carrier)
@@ -104,8 +102,8 @@ namespace OpenRA.Mods.Common.Traits
state = State.Reserved; state = State.Reserved;
Carrier = carrier; Carrier = carrier;
if (reservedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.ReservedCondition)) if (reservedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.ReservedCondition))
reservedToken = conditionManager.GrantCondition(self, Info.ReservedCondition); reservedToken = self.GrantCondition(Info.ReservedCondition);
return true; return true;
} }
@@ -115,11 +113,11 @@ namespace OpenRA.Mods.Common.Traits
state = State.Free; state = State.Free;
Carrier = null; Carrier = null;
if (reservedToken != ConditionManager.InvalidConditionToken) if (reservedToken != Actor.InvalidConditionToken)
reservedToken = conditionManager.RevokeCondition(self, reservedToken); reservedToken = self.RevokeCondition(reservedToken);
if (lockedToken != ConditionManager.InvalidConditionToken) if (lockedToken != Actor.InvalidConditionToken)
lockedToken = conditionManager.RevokeCondition(self, lockedToken); lockedToken = self.RevokeCondition(lockedToken);
} }
// Prepare for transport pickup // Prepare for transport pickup
@@ -136,8 +134,8 @@ namespace OpenRA.Mods.Common.Traits
state = State.Locked; state = State.Locked;
Carrier = carrier; Carrier = carrier;
if (lockedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.LockedCondition)) if (lockedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.LockedCondition))
lockedToken = conditionManager.GrantCondition(self, Info.LockedCondition); lockedToken = self.GrantCondition(Info.LockedCondition);
} }
// Make sure we are not moving and at our normal position with respect to the cell grid // 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; int remainingTime;
bool isDocking; bool isDocking;
ConditionManager conditionManager;
Cloak[] otherCloaks; Cloak[] otherCloaks;
CPos? lastPos; CPos? lastPos;
bool wasCloaked = false; bool wasCloaked = false;
bool firstTick = true; bool firstTick = true;
int cloakedToken = ConditionManager.InvalidConditionToken; int cloakedToken = Actor.InvalidConditionToken;
public Cloak(CloakInfo info) public Cloak(CloakInfo info)
: base(info) : base(info)
@@ -89,7 +88,6 @@ namespace OpenRA.Mods.Common.Traits
protected override void Created(Actor self) protected override void Created(Actor self)
{ {
conditionManager = self.TraitOrDefault<ConditionManager>();
otherCloaks = self.TraitsImplementing<Cloak>() otherCloaks = self.TraitsImplementing<Cloak>()
.Where(c => c != this) .Where(c => c != this)
.ToArray(); .ToArray();
@@ -97,8 +95,8 @@ namespace OpenRA.Mods.Common.Traits
if (Cloaked) if (Cloaked)
{ {
wasCloaked = true; wasCloaked = true;
if (conditionManager != null && cloakedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition)) if (cloakedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = conditionManager.GrantCondition(self, Info.CloakedCondition); cloakedToken = self.GrantCondition(Info.CloakedCondition);
} }
base.Created(self); base.Created(self);
@@ -165,8 +163,8 @@ namespace OpenRA.Mods.Common.Traits
var isCloaked = Cloaked; var isCloaked = Cloaked;
if (isCloaked && !wasCloaked) if (isCloaked && !wasCloaked)
{ {
if (conditionManager != null && cloakedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition)) if (cloakedToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CloakedCondition))
cloakedToken = conditionManager.GrantCondition(self, Info.CloakedCondition); cloakedToken = self.GrantCondition(Info.CloakedCondition);
// Sounds shouldn't play if the actor starts cloaked // Sounds shouldn't play if the actor starts cloaked
if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked)) if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked))
@@ -174,8 +172,8 @@ namespace OpenRA.Mods.Common.Traits
} }
else if (!isCloaked && wasCloaked) else if (!isCloaked && wasCloaked)
{ {
if (cloakedToken != ConditionManager.InvalidConditionToken) if (cloakedToken != Actor.InvalidConditionToken)
cloakedToken = conditionManager.RevokeCondition(self, cloakedToken); cloakedToken = self.RevokeCondition(cloakedToken);
if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked)) if (!(firstTick && Info.InitialDelay == 0) && !otherCloaks.Any(a => a.Cloaked))
Game.Sound.Play(SoundType.World, Info.UncloakSound, self.CenterPosition); 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).")] [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] [GrantedConditionReference]
[FieldLoader.Require] [FieldLoader.Require]
@@ -55,7 +55,6 @@ namespace OpenRA.Mods.Common.Traits
} }
public readonly ExternalConditionInfo Info; public readonly ExternalConditionInfo Info;
readonly ConditionManager conditionManager;
readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>(); readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>();
// Tokens are sorted on insert/remove by ascending expiry time // 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) public ExternalCondition(Actor self, ExternalConditionInfo info)
{ {
Info = info; Info = info;
conditionManager = self.Trait<ConditionManager>();
} }
public bool CanGrantCondition(Actor self, object source) public bool CanGrantCondition(Actor self, object source)
{ {
if (conditionManager == null || source == null) if (source == null)
return false; return false;
// Timed tokens do not count towards the source cap: the condition with the shortest // 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) public int GrantCondition(Actor self, object source, int duration = 0, int remaining = 0)
{ {
if (!CanGrantCondition(self, source)) 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; HashSet<int> permanent;
permanentTokens.TryGetValue(source, out permanent); permanentTokens.TryGetValue(source, out permanent);
@@ -118,8 +116,8 @@ namespace OpenRA.Mods.Common.Traits
{ {
var expireToken = timedTokens[expireIndex].Token; var expireToken = timedTokens[expireIndex].Token;
timedTokens.RemoveAt(expireIndex); timedTokens.RemoveAt(expireIndex);
if (conditionManager.TokenValid(self, expireToken)) if (self.TokenValid(expireToken))
conditionManager.RevokeCondition(self, expireToken); self.RevokeCondition(expireToken);
} }
} }
} }
@@ -133,8 +131,8 @@ namespace OpenRA.Mods.Common.Traits
if (timedTokens.Count > 0) if (timedTokens.Count > 0)
{ {
var expire = timedTokens[0].Token; var expire = timedTokens[0].Token;
if (conditionManager.TokenValid(self, expire)) if (self.TokenValid(expire))
conditionManager.RevokeCondition(self, expire); self.RevokeCondition(expire);
timedTokens.RemoveAt(0); 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> /// <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) public bool TryRevokeCondition(Actor self, object source, int token)
{ {
if (conditionManager == null || source == null) if (source == null)
return false; return false;
HashSet<int> permanentTokensForSource; HashSet<int> permanentTokensForSource;
@@ -184,8 +182,8 @@ namespace OpenRA.Mods.Common.Traits
return false; return false;
} }
if (conditionManager.TokenValid(self, token)) if (self.TokenValid(token))
conditionManager.RevokeCondition(self, token); self.RevokeCondition(token);
return true; return true;
} }
@@ -201,8 +199,8 @@ namespace OpenRA.Mods.Common.Traits
while (count < timedTokens.Count && timedTokens[count].Expires < worldTick) while (count < timedTokens.Count && timedTokens[count].Expires < worldTick)
{ {
var token = timedTokens[count].Token; var token = timedTokens[count].Token;
if (conditionManager.TokenValid(self, token)) if (self.TokenValid(token))
conditionManager.RevokeCondition(self, token); self.RevokeCondition(token);
count++; count++;
} }

View File

@@ -29,31 +29,23 @@ namespace OpenRA.Mods.Common.Traits
class GrantCondition : ConditionalTrait<GrantConditionInfo> class GrantCondition : ConditionalTrait<GrantConditionInfo>
{ {
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
public GrantCondition(GrantConditionInfo info) public GrantCondition(GrantConditionInfo info)
: base(info) { } : base(info) { }
protected override void Created(Actor self)
{
conditionManager = self.Trait<ConditionManager>();
base.Created(self);
}
protected override void TraitEnabled(Actor self) protected override void TraitEnabled(Actor self)
{ {
if (conditionToken == ConditionManager.InvalidConditionToken) if (conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition); conditionToken = self.GrantCondition(Info.Condition);
} }
protected override void TraitDisabled(Actor self) protected override void TraitDisabled(Actor self)
{ {
if (Info.GrantPermanently || conditionToken == ConditionManager.InvalidConditionToken) if (Info.GrantPermanently || conditionToken == Actor.InvalidConditionToken)
return; 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 cooldown = 0;
int shotsFired = 0; int shotsFired = 0;
ConditionManager manager;
// Only tracked when RevokeOnNewTarget is true. // Only tracked when RevokeOnNewTarget is true.
Target lastTarget = Target.Invalid; Target lastTarget = Target.Invalid;
@@ -60,33 +59,26 @@ namespace OpenRA.Mods.Common.Traits
public GrantConditionOnAttack(ActorInitializer init, GrantConditionOnAttackInfo info) public GrantConditionOnAttack(ActorInitializer init, GrantConditionOnAttackInfo info)
: base(info) { } : base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
manager = self.TraitOrDefault<ConditionManager>();
}
void GrantInstance(Actor self, string cond) void GrantInstance(Actor self, string cond)
{ {
if (manager == null || string.IsNullOrEmpty(cond)) if (string.IsNullOrEmpty(cond))
return; return;
tokens.Push(manager.GrantCondition(self, cond)); tokens.Push(self.GrantCondition(cond));
} }
void RevokeInstance(Actor self, bool revokeAll) void RevokeInstance(Actor self, bool revokeAll)
{ {
shotsFired = 0; shotsFired = 0;
if (manager == null || tokens.Count == 0) if (tokens.Count == 0)
return; return;
if (!revokeAll) if (!revokeAll)
manager.RevokeCondition(self, tokens.Pop()); self.RevokeCondition(tokens.Pop());
else else
while (tokens.Count > 0) while (tokens.Count > 0)
manager.RevokeCondition(self, tokens.Pop()); self.RevokeCondition(tokens.Pop());
} }
void ITick.Tick(Actor self) void ITick.Tick(Actor self)

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly GrantConditionOnBotOwnerInfo info; readonly GrantConditionOnBotOwnerInfo info;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
public GrantConditionOnBotOwner(ActorInitializer init, GrantConditionOnBotOwnerInfo info) public GrantConditionOnBotOwner(ActorInitializer init, GrantConditionOnBotOwnerInfo info)
{ {
@@ -49,22 +48,18 @@ namespace OpenRA.Mods.Common.Traits
// it's defined on the PlayerActor. // it's defined on the PlayerActor.
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
conditionManager = self.TraitOrDefault<ConditionManager>(); if (self.Owner.IsBot && info.Bots.Contains(self.Owner.BotType))
if (conditionManager != null && self.Owner.IsBot && info.Bots.Contains(self.Owner.BotType)) conditionToken = self.GrantCondition(info.Condition);
conditionToken = conditionManager.GrantCondition(self, info.Condition);
}); });
} }
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{ {
if (conditionManager == null) if (conditionToken != Actor.InvalidConditionToken)
return; conditionToken = self.RevokeCondition(conditionToken);
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
if (info.Bots.Contains(newOwner.BotType)) 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 GrantConditionOnDamageStateInfo info;
readonly IHealth health; readonly IHealth health;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
public GrantConditionOnDamageState(Actor self, GrantConditionOnDamageStateInfo info) public GrantConditionOnDamageState(Actor self, GrantConditionOnDamageStateInfo info)
{ {
@@ -52,16 +51,15 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
conditionManager = self.Trait<ConditionManager>();
GrantConditionOnValidDamageState(self, health.DamageState); GrantConditionOnValidDamageState(self, health.DamageState);
} }
void GrantConditionOnValidDamageState(Actor self, DamageState state) void GrantConditionOnValidDamageState(Actor self, DamageState state)
{ {
if (!info.ValidDamageStates.HasFlag(state) || conditionToken != ConditionManager.InvalidConditionToken) if (!info.ValidDamageStates.HasFlag(state) || conditionToken != Actor.InvalidConditionToken)
return; return;
conditionToken = conditionManager.GrantCondition(self, info.Condition); conditionToken = self.GrantCondition(info.Condition);
var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom); var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition); Game.Sound.Play(SoundType.World, sound, self.CenterPosition);
@@ -69,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyDamageStateChanged.DamageStateChanged(Actor self, AttackInfo e) void INotifyDamageStateChanged.DamageStateChanged(Actor self, AttackInfo e)
{ {
var granted = conditionToken != ConditionManager.InvalidConditionToken; var granted = conditionToken != Actor.InvalidConditionToken;
if (granted && info.GrantPermanently) if (granted && info.GrantPermanently)
return; return;
@@ -77,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
GrantConditionOnValidDamageState(self, health.DamageState); GrantConditionOnValidDamageState(self, health.DamageState);
else if (granted && !info.ValidDamageStates.HasFlag(e.DamageState) && info.ValidDamageStates.HasFlag(e.PreviousDamageState)) 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); var sound = info.DisabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition); Game.Sound.Play(SoundType.World, sound, self.CenterPosition);

View File

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

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
class GrantConditionOnFaction : ConditionalTrait<GrantConditionOnFactionInfo>, INotifyOwnerChanged class GrantConditionOnFaction : ConditionalTrait<GrantConditionOnFactionInfo>, INotifyOwnerChanged
{ {
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
string faction; string faction;
public GrantConditionOnFaction(ActorInitializer init, GrantConditionOnFactionInfo info) 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; 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) public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{ {
if (Info.ResetOnOwnerChange && faction != newOwner.Faction.InternalName) if (Info.ResetOnOwnerChange && faction != newOwner.Faction.InternalName)
@@ -63,16 +55,16 @@ namespace OpenRA.Mods.Common.Traits
protected override void TraitEnabled(Actor self) protected override void TraitEnabled(Actor self)
{ {
if (conditionToken == ConditionManager.InvalidConditionToken && Info.Factions.Contains(faction)) if (conditionToken == Actor.InvalidConditionToken && Info.Factions.Contains(faction))
conditionToken = conditionManager.GrantCondition(self, Info.Condition); conditionToken = self.GrantCondition(Info.Condition);
} }
protected override void TraitDisabled(Actor self) protected override void TraitDisabled(Actor self)
{ {
if (conditionToken == ConditionManager.InvalidConditionToken) if (conditionToken == Actor.InvalidConditionToken)
return; 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 IHealth health;
readonly int maxHP; readonly int maxHP;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
public GrantConditionOnHealth(Actor self, GrantConditionOnHealthInfo info) public GrantConditionOnHealth(Actor self, GrantConditionOnHealthInfo info)
{ {
@@ -65,16 +64,15 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
conditionManager = self.Trait<ConditionManager>();
GrantConditionOnValidHealth(self, health.HP); GrantConditionOnValidHealth(self, health.HP);
} }
void GrantConditionOnValidHealth(Actor self, int 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; return;
conditionToken = conditionManager.GrantCondition(self, info.Condition); conditionToken = self.GrantCondition(info.Condition);
var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom); var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition); Game.Sound.Play(SoundType.World, sound, self.CenterPosition);
@@ -82,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyDamage.Damaged(Actor self, AttackInfo e) void INotifyDamage.Damaged(Actor self, AttackInfo e)
{ {
var granted = conditionToken != ConditionManager.InvalidConditionToken; var granted = conditionToken != Actor.InvalidConditionToken;
if (granted && info.GrantPermanently) if (granted && info.GrantPermanently)
return; return;
@@ -90,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
GrantConditionOnValidHealth(self, health.HP); GrantConditionOnValidHealth(self, health.HP);
else if (granted && (info.MinHP > health.HP || maxHP < 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); var sound = info.DisabledSounds.RandomOrDefault(Game.CosmeticRandom);
Game.Sound.Play(SoundType.World, sound, self.CenterPosition); 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) 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; jumpjetInAir = true;
} }
// By the time the condition is meant to be revoked, the 'oldLayer' is already no longer the Jumpjet layer, either // 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; jumpjetInAir = false;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -34,9 +34,8 @@ namespace OpenRA.Mods.Common.Traits
readonly GrantConditionOnPrerequisiteInfo info; readonly GrantConditionOnPrerequisiteInfo info;
bool wasAvailable; bool wasAvailable;
ConditionManager conditionManager;
GrantConditionOnPrerequisiteManager globalManager; GrantConditionOnPrerequisiteManager globalManager;
int conditionToken = ConditionManager.InvalidConditionToken; int conditionToken = Actor.InvalidConditionToken;
public GrantConditionOnPrerequisite(Actor self, GrantConditionOnPrerequisiteInfo info) 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; var playerActor = self.Info.Name == "player" ? self : self.Owner.PlayerActor;
globalManager = playerActor.Trait<GrantConditionOnPrerequisiteManager>(); globalManager = playerActor.Trait<GrantConditionOnPrerequisiteManager>();
conditionManager = self.TraitOrDefault<ConditionManager>();
} }
void INotifyAddedToWorld.AddedToWorld(Actor self) void INotifyAddedToWorld.AddedToWorld(Actor self)
@@ -74,13 +72,13 @@ namespace OpenRA.Mods.Common.Traits
public void PrerequisitesUpdated(Actor self, bool available) public void PrerequisitesUpdated(Actor self, bool available)
{ {
if (available == wasAvailable || conditionManager == null) if (available == wasAvailable)
return; return;
if (available && conditionToken == ConditionManager.InvalidConditionToken) if (available && conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition); conditionToken = self.GrantCondition(info.Condition);
else if (!available && conditionToken != ConditionManager.InvalidConditionToken) else if (!available && conditionToken != Actor.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken); conditionToken = self.RevokeCondition(conditionToken);
wasAvailable = available; 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 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; readonly GrantConditionOnProductionInfo info;
ConditionManager conditionManager;
int token = ConditionManager.InvalidConditionToken; int token = Actor.InvalidConditionToken;
[Sync] [Sync]
int ticks; int ticks;
@@ -54,31 +53,26 @@ namespace OpenRA.Mods.Common.Traits
ticks = info.Duration; ticks = info.Duration;
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyProduction.UnitProduced(Actor self, Actor other, CPos exit) void INotifyProduction.UnitProduced(Actor self, Actor other, CPos exit)
{ {
if (info.Actors.Any() && !info.Actors.Select(a => a.ToLowerInvariant()).Contains(other.Info.Name)) if (info.Actors.Any() && !info.Actors.Select(a => a.ToLowerInvariant()).Contains(other.Info.Name))
return; return;
if (conditionManager != null && token == ConditionManager.InvalidConditionToken) if (token == Actor.InvalidConditionToken)
token = conditionManager.GrantCondition(self, info.Condition); token = self.GrantCondition(info.Condition);
ticks = info.Duration; ticks = info.Duration;
} }
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
if (info.Duration >= 0 && token != ConditionManager.InvalidConditionToken && --ticks < 0) if (info.Duration >= 0 && token != Actor.InvalidConditionToken && --ticks < 0)
token = conditionManager.RevokeCondition(self, token); token = self.RevokeCondition(token);
} }
float ISelectionBar.GetValue() float ISelectionBar.GetValue()
{ {
if (!info.ShowSelectionBar || info.Duration < 0 || token == ConditionManager.InvalidConditionToken) if (!info.ShowSelectionBar || info.Duration < 0 || token == Actor.InvalidConditionToken)
return 0; return 0;
return (float)ticks / info.Duration; 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, // 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. // 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) if (newLayer == ValidLayerType && depth < transitionDepth && conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, Info.Condition); conditionToken = self.GrantCondition(Info.Condition);
else if (newLayer != ValidLayerType && depth > transitionDepth && conditionToken != ConditionManager.InvalidConditionToken) else if (newLayer != ValidLayerType && depth > transitionDepth && conditionToken != Actor.InvalidConditionToken)
{ {
conditionToken = conditionManager.RevokeCondition(self, conditionToken); conditionToken = self.RevokeCondition(conditionToken);
PlayTransitionAudioVisuals(self, self.Location); 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 object Create(ActorInitializer init) { return new GrantConditionOnTerrain(init, this); }
} }
public class GrantConditionOnTerrain : INotifyCreated, ITick public class GrantConditionOnTerrain : ITick
{ {
readonly GrantConditionOnTerrainInfo info; readonly GrantConditionOnTerrainInfo info;
readonly TileSet tileSet; readonly TileSet tileSet;
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
string cachedTerrain; string cachedTerrain;
public GrantConditionOnTerrain(ActorInitializer init, GrantConditionOnTerrainInfo info) public GrantConditionOnTerrain(ActorInitializer init, GrantConditionOnTerrainInfo info)
@@ -43,20 +42,12 @@ namespace OpenRA.Mods.Common.Traits
tileSet = init.World.Map.Rules.TileSet; tileSet = init.World.Map.Rules.TileSet;
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
var cell = self.Location; var cell = self.Location;
if (!self.World.Map.Contains(cell)) if (!self.World.Map.Contains(cell))
return; return;
if (conditionManager == null)
return;
// The terrain type may change between ticks without the actor moving // The terrain type may change between ticks without the actor moving
var currentTerrain = cell.Layer == 0 ? self.World.Map.GetTerrainInfo(cell).Type : var currentTerrain = cell.Layer == 0 ? self.World.Map.GetTerrainInfo(cell).Type :
tileSet[self.World.GetCustomMovementLayers()[cell.Layer].GetTerrainIndex(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); var wantsGranted = info.TerrainTypes.Contains(currentTerrain);
if (currentTerrain != cachedTerrain) if (currentTerrain != cachedTerrain)
{ {
if (wantsGranted && conditionToken == ConditionManager.InvalidConditionToken) if (wantsGranted && conditionToken == Actor.InvalidConditionToken)
conditionToken = conditionManager.GrantCondition(self, info.Condition); conditionToken = self.GrantCondition(info.Condition);
else if (!wantsGranted && conditionToken != ConditionManager.InvalidConditionToken) else if (!wantsGranted && conditionToken != Actor.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken); conditionToken = self.RevokeCondition(conditionToken);
} }
cachedTerrain = currentTerrain; cachedTerrain = currentTerrain;

View File

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

View File

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

View File

@@ -42,8 +42,7 @@ namespace OpenRA.Mods.Common.Traits
public class ToggleConditionOnOrder : PausableConditionalTrait<ToggleConditionOnOrderInfo>, IResolveOrder public class ToggleConditionOnOrder : PausableConditionalTrait<ToggleConditionOnOrderInfo>, IResolveOrder
{ {
ConditionManager conditionManager; int conditionToken = Actor.InvalidConditionToken;
int conditionToken = ConditionManager.InvalidConditionToken;
// If the trait is paused this may be true with no condition granted // If the trait is paused this may be true with no condition granted
[Sync] [Sync]
@@ -52,21 +51,11 @@ namespace OpenRA.Mods.Common.Traits
public ToggleConditionOnOrder(Actor self, ToggleConditionOnOrderInfo info) public ToggleConditionOnOrder(Actor self, ToggleConditionOnOrderInfo info)
: base(info) { } : base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void SetCondition(Actor self, bool granted) void SetCondition(Actor self, bool granted)
{ {
if (conditionManager == null) if (granted && conditionToken == Actor.InvalidConditionToken)
return;
if (granted && conditionToken == ConditionManager.InvalidConditionToken)
{ {
conditionToken = conditionManager.GrantCondition(self, Info.Condition); conditionToken = self.GrantCondition(Info.Condition);
if (Info.EnabledSound != null) if (Info.EnabledSound != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.EnabledSound, self.Owner.Faction.InternalName); 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) if (Info.EnabledSpeech != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName); 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) if (Info.DisabledSound != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.DisabledSound, self.Owner.Faction.InternalName); 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> actions = new List<DemolishAction>();
List<DemolishAction> removeActions = new List<DemolishAction>(); List<DemolishAction> removeActions = new List<DemolishAction>();
public Demolishable(DemolishableInfo info) public Demolishable(DemolishableInfo info)
: base(info) { } : base(info) { }
protected override void Created(Actor self)
{
base.Created(self);
conditionManager = self.TraitOrDefault<ConditionManager>();
}
bool IDemolishable.IsValidTarget(Actor self, Actor saboteur) bool IDemolishable.IsValidTarget(Actor self, Actor saboteur)
{ {
return !IsTraitDisabled; return !IsTraitDisabled;
@@ -66,9 +59,9 @@ namespace OpenRA.Mods.Common.Traits
if (IsTraitDisabled) if (IsTraitDisabled)
return; return;
var token = ConditionManager.InvalidConditionToken; var token = Actor.InvalidConditionToken;
if (conditionManager != null && !string.IsNullOrEmpty(Info.Condition)) if (!string.IsNullOrEmpty(Info.Condition))
token = conditionManager.GrantCondition(self, Info.Condition); token = self.GrantCondition(Info.Condition);
actions.Add(new DemolishAction(saboteur, delay, token)); actions.Add(new DemolishAction(saboteur, delay, token));
} }
@@ -88,9 +81,9 @@ namespace OpenRA.Mods.Common.Traits
if (Util.ApplyPercentageModifiers(100, modifiers) > 0) if (Util.ApplyPercentageModifiers(100, modifiers) > 0)
self.Kill(a.Saboteur); 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); removeActions.Add(a);
} }
} }

View File

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

View File

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

View File

@@ -35,7 +35,6 @@ namespace OpenRA.Mods.Common.Traits
class KillsSelf : ConditionalTrait<KillsSelfInfo>, INotifyAddedToWorld, ITick class KillsSelf : ConditionalTrait<KillsSelfInfo>, INotifyAddedToWorld, ITick
{ {
int lifetime; int lifetime;
ConditionManager conditionManager;
public KillsSelf(Actor self, KillsSelfInfo info) public KillsSelf(Actor self, KillsSelfInfo info)
: base(info) : base(info)
@@ -51,12 +50,6 @@ namespace OpenRA.Mods.Common.Traits
self.World.AddFrameEndTask(w => Kill(self)); self.World.AddFrameEndTask(w => Kill(self));
} }
protected override void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
base.Created(self);
}
void INotifyAddedToWorld.AddedToWorld(Actor self) void INotifyAddedToWorld.AddedToWorld(Actor self)
{ {
if (!IsTraitDisabled) if (!IsTraitDisabled)
@@ -80,8 +73,8 @@ namespace OpenRA.Mods.Common.Traits
if (self.IsDead) if (self.IsDead)
return; return;
if (conditionManager != null && !string.IsNullOrEmpty(Info.GrantsCondition)) if (!string.IsNullOrEmpty(Info.GrantsCondition))
conditionManager.GrantCondition(self, Info.GrantsCondition); self.GrantCondition(Info.GrantsCondition);
if (Info.RemoveInstead || !self.Info.HasTraitInfo<IHealthInfo>()) if (Info.RemoveInstead || !self.Info.HasTraitInfo<IHealthInfo>())
self.Dispose(); 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 object Create(ActorInitializer init) { return new Parachutable(init.Self, this); }
} }
public class Parachutable : INotifyCreated, INotifyParachute public class Parachutable : INotifyParachute
{ {
readonly ParachutableInfo info; readonly ParachutableInfo info;
readonly IPositionable positionable; readonly IPositionable positionable;
public Actor IgnoreActor; public Actor IgnoreActor;
ConditionManager conditionManager; int parachutingToken = Actor.InvalidConditionToken;
int parachutingToken = ConditionManager.InvalidConditionToken;
public Parachutable(Actor self, ParachutableInfo info) public Parachutable(Actor self, ParachutableInfo info)
{ {
@@ -75,17 +74,12 @@ namespace OpenRA.Mods.Common.Traits
public bool IsInAir { get; private set; } public bool IsInAir { get; private set; }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
void INotifyParachute.OnParachute(Actor self) void INotifyParachute.OnParachute(Actor self)
{ {
IsInAir = true; IsInAir = true;
if (conditionManager != null && parachutingToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.ParachutingCondition)) if (parachutingToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(info.ParachutingCondition))
parachutingToken = conditionManager.GrantCondition(self, info.ParachutingCondition); parachutingToken = self.GrantCondition(info.ParachutingCondition);
self.NotifyBlocker(self.Location); self.NotifyBlocker(self.Location);
} }
@@ -94,8 +88,8 @@ namespace OpenRA.Mods.Common.Traits
{ {
IsInAir = false; IsInAir = false;
if (parachutingToken != ConditionManager.InvalidConditionToken) if (parachutingToken != Actor.InvalidConditionToken)
parachutingToken = conditionManager.RevokeCondition(self, parachutingToken); parachutingToken = self.RevokeCondition(parachutingToken);
if (!info.KilledOnImpassableTerrain) if (!info.KilledOnImpassableTerrain)
return; return;

View File

@@ -50,15 +50,14 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new Passenger(this); } 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 readonly PassengerInfo Info;
public Actor Transport; public Actor Transport;
bool requireForceMove; bool requireForceMove;
ConditionManager conditionManager; int anyCargoToken = Actor.InvalidConditionToken;
int anyCargoToken = ConditionManager.InvalidConditionToken; int specificCargoToken = Actor.InvalidConditionToken;
int specificCargoToken = ConditionManager.InvalidConditionToken;
public Passenger(PassengerInfo info) 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) public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
{ {
if (order.OrderID == "EnterTransport") if (order.OrderID == "EnterTransport")
@@ -126,14 +120,12 @@ namespace OpenRA.Mods.Common.Traits
void INotifyEnteredCargo.OnEnteredCargo(Actor self, Actor cargo) void INotifyEnteredCargo.OnEnteredCargo(Actor self, Actor cargo)
{ {
string specificCargoCondition; 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)) if (anyCargoToken == Actor.InvalidConditionToken && !string.IsNullOrEmpty(Info.CargoCondition))
specificCargoToken = conditionManager.GrantCondition(self, specificCargoCondition); 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 // 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 // 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) void INotifyExitedCargo.OnExitedCargo(Actor self, Actor cargo)
{ {
if (anyCargoToken != ConditionManager.InvalidConditionToken) if (anyCargoToken != Actor.InvalidConditionToken)
anyCargoToken = conditionManager.RevokeCondition(self, anyCargoToken); anyCargoToken = self.RevokeCondition(anyCargoToken);
if (specificCargoToken != ConditionManager.InvalidConditionToken) if (specificCargoToken != Actor.InvalidConditionToken)
specificCargoToken = conditionManager.RevokeCondition(self, specificCargoToken); specificCargoToken = self.RevokeCondition(specificCargoToken);
} }
void IResolveOrder.ResolveOrder(Actor self, Order order) void IResolveOrder.ResolveOrder(Actor self, Order order)

View File

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

View File

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

View File

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

View File

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

View File

@@ -175,26 +175,6 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface INotifyExitedCargo { void OnExitedCargo(Actor self, Actor cargo); } 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 public interface INotifyHarvesterAction
{ {
void MovingToResources(Actor self, CPos targetCell); 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 MoveClassicFacingFudge(),
new RenameWithNukeLaunch(), new RenameWithNukeLaunch(),
new SpawnActorPowerDefaultEffect(), new SpawnActorPowerDefaultEffect(),
new RemoveConditionManager(),
}) })
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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