Add plumbing for notifying traits of movement
More precisely, about start and stop of movement.
This commit is contained in:
@@ -176,6 +176,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
ConditionManager conditionManager;
|
||||
IDisposable reservation;
|
||||
IEnumerable<int> speedModifiers;
|
||||
INotifyMoving[] notifyMoving;
|
||||
|
||||
[Sync] public int Facing { get; set; }
|
||||
[Sync] public WPos CenterPosition { get; private set; }
|
||||
@@ -191,9 +192,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
int airborneToken = ConditionManager.InvalidConditionToken;
|
||||
int cruisingToken = ConditionManager.InvalidConditionToken;
|
||||
|
||||
bool isMoving;
|
||||
bool isMovingVertically;
|
||||
MovementType movementTypes;
|
||||
WPos cachedPosition;
|
||||
int cachedFacing;
|
||||
bool? landNow;
|
||||
|
||||
public Aircraft(ActorInitializer init, AircraftInfo info)
|
||||
@@ -233,6 +234,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
conditionManager = self.TraitOrDefault<ConditionManager>();
|
||||
speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray().Select(sm => sm.GetSpeedModifier());
|
||||
cachedPosition = self.CenterPosition;
|
||||
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
|
||||
}
|
||||
|
||||
void INotifyAddedToWorld.AddedToWorld(Actor self)
|
||||
@@ -317,10 +319,23 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
var oldCachedFacing = cachedFacing;
|
||||
cachedFacing = Facing;
|
||||
|
||||
var oldCachedPosition = cachedPosition;
|
||||
cachedPosition = self.CenterPosition;
|
||||
isMoving = (oldCachedPosition - cachedPosition).HorizontalLengthSquared != 0;
|
||||
isMovingVertically = (oldCachedPosition - cachedPosition).VerticalLengthSquared != 0;
|
||||
|
||||
var newMovementTypes = MovementType.None;
|
||||
if (oldCachedFacing != Facing)
|
||||
newMovementTypes |= MovementType.Turn;
|
||||
|
||||
if ((oldCachedPosition - cachedPosition).HorizontalLengthSquared != 0)
|
||||
newMovementTypes |= MovementType.Horizontal;
|
||||
|
||||
if ((oldCachedPosition - cachedPosition).VerticalLengthSquared != 0)
|
||||
newMovementTypes |= MovementType.Vertical;
|
||||
|
||||
CurrentMovementTypes = newMovementTypes;
|
||||
|
||||
Repulse();
|
||||
}
|
||||
@@ -712,9 +727,22 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public CPos NearestMoveableCell(CPos cell) { return cell; }
|
||||
|
||||
public bool IsMoving { get { return isMoving; } set { } }
|
||||
public MovementType CurrentMovementTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return movementTypes;
|
||||
}
|
||||
|
||||
public bool IsMovingVertically { get { return isMovingVertically; } set { } }
|
||||
set
|
||||
{
|
||||
var oldValue = movementTypes;
|
||||
movementTypes = value;
|
||||
if (value != oldValue)
|
||||
foreach (var n in notifyMoving)
|
||||
n.MovementTypeChanged(self, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanEnterTargetNow(Actor self, Target target)
|
||||
{
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (conditionManager == null)
|
||||
return;
|
||||
|
||||
var isMovingVertically = Info.ConsiderVerticalMovement ? movement.IsMovingVertically : false;
|
||||
var isMoving = !IsTraitDisabled && !self.IsDead && (movement.IsMoving || isMovingVertically);
|
||||
var isMovingVertically = Info.ConsiderVerticalMovement ? movement.CurrentMovementTypes.HasFlag(MovementType.Vertical);
|
||||
var isMoving = !IsTraitDisabled && !self.IsDead && (movement.CurrentMovementTypes.HasFlag(MovementType.Horizontal) || isMovingVertically);
|
||||
if (isMoving && conditionToken == ConditionManager.InvalidConditionToken)
|
||||
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
|
||||
else if (!isMoving && conditionToken != ConditionManager.InvalidConditionToken)
|
||||
|
||||
@@ -33,9 +33,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speed at which the actor turns.")]
|
||||
public readonly int TurnSpeed = 255;
|
||||
|
||||
[Desc("Should turning always be considering as moving (instead of only turning while moving forward).")]
|
||||
public readonly bool AlwaysConsiderTurnAsMove = false;
|
||||
|
||||
public readonly int Speed = 1;
|
||||
|
||||
public readonly string Cursor = "move";
|
||||
@@ -124,22 +121,39 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public class Mobile : PausableConditionalTrait<MobileInfo>, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove,
|
||||
public class Mobile : PausableConditionalTrait<MobileInfo>, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, ITick,
|
||||
IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly Lazy<IEnumerable<int>> speedModifiers;
|
||||
|
||||
#region IMove IsMoving checks
|
||||
public bool IsMoving { get; set; }
|
||||
public bool IsMovingVertically { get { return false; } set { } }
|
||||
#region IMove CurrentMovementTypes
|
||||
MovementType movementTypes;
|
||||
public MovementType CurrentMovementTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return movementTypes;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var oldValue = movementTypes;
|
||||
movementTypes = value;
|
||||
if (value != oldValue)
|
||||
foreach (var n in notifyMoving)
|
||||
n.MovementTypeChanged(self, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
int facing;
|
||||
int oldFacing, facing;
|
||||
WPos oldPos;
|
||||
CPos fromCell, toCell;
|
||||
public SubCell FromSubCell, ToSubCell;
|
||||
INotifyCustomLayerChanged[] notifyCustomLayerChanged;
|
||||
INotifyVisualPositionChanged[] notifyVisualPositionChanged;
|
||||
INotifyMoving[] notifyMoving;
|
||||
INotifyFinishedMoving[] notifyFinishedMoving;
|
||||
|
||||
#region IFacing
|
||||
@@ -201,11 +215,27 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
notifyCustomLayerChanged = self.TraitsImplementing<INotifyCustomLayerChanged>().ToArray();
|
||||
notifyVisualPositionChanged = self.TraitsImplementing<INotifyVisualPositionChanged>().ToArray();
|
||||
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
|
||||
notifyFinishedMoving = self.TraitsImplementing<INotifyFinishedMoving>().ToArray();
|
||||
|
||||
base.Created(self);
|
||||
}
|
||||
|
||||
void ITick.Tick(Actor self)
|
||||
{
|
||||
var newMovementTypes = MovementType.None;
|
||||
if (oldPos != CenterPosition)
|
||||
newMovementTypes |= MovementType.Horizontal;
|
||||
|
||||
if (oldFacing != Facing)
|
||||
newMovementTypes |= MovementType.Turn;
|
||||
|
||||
CurrentMovementTypes = newMovementTypes;
|
||||
|
||||
oldPos = CenterPosition;
|
||||
oldFacing = Facing;
|
||||
}
|
||||
|
||||
void INotifyAddedToWorld.AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.AddToMaps(self, this);
|
||||
|
||||
@@ -140,12 +140,12 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
wasModifying = rsm.IsModifyingSequence;
|
||||
}
|
||||
|
||||
if ((state != AnimationState.Moving || dirty) && move.IsMoving)
|
||||
if ((state != AnimationState.Moving || dirty) && move.CurrentMovementTypes.HasFlag(MovementType.Horizontal))
|
||||
{
|
||||
state = AnimationState.Moving;
|
||||
DefaultAnimation.PlayRepeating(NormalizeInfantrySequence(self, Info.MoveSequence));
|
||||
}
|
||||
else if (((state == AnimationState.Moving || dirty) && !move.IsMoving)
|
||||
else if (((state == AnimationState.Moving || dirty) && !move.CurrentMovementTypes.HasFlag(MovementType.Horizontal))
|
||||
|| ((state == AnimationState.Idle || state == AnimationState.IdleAnimating) && !self.IsIdle))
|
||||
PlayStandAnimation(self);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
if (IsTraitDisabled || wsb.IsTraitDisabled)
|
||||
return;
|
||||
|
||||
var isMoving = movement.IsMoving && !self.IsDead;
|
||||
var isMoving = movement.CurrentMovementTypes.HasFlag(MovementType.Horizontal) && !self.IsDead;
|
||||
|
||||
if (isMoving ^ (wsb.DefaultAnimation.CurrentSequence.Name != Info.MoveSequence))
|
||||
return;
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
static bool IsMovingInMyDirection(Actor self, Actor other)
|
||||
{
|
||||
var otherMobile = other.TraitOrDefault<Mobile>();
|
||||
if (otherMobile == null || !otherMobile.IsMoving)
|
||||
if (otherMobile == null || !otherMobile.CurrentMovementTypes.HasFlag(MovementType.Horizontal))
|
||||
return false;
|
||||
|
||||
var selfMobile = self.TraitOrDefault<Mobile>();
|
||||
|
||||
Reference in New Issue
Block a user