diff --git a/OpenRA.Mods.Common/Traits/Wanders.cs b/OpenRA.Mods.Common/Traits/Wanders.cs index 590aea9d09..02a963cc91 100644 --- a/OpenRA.Mods.Common/Traits/Wanders.cs +++ b/OpenRA.Mods.Common/Traits/Wanders.cs @@ -15,7 +15,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Wanders around aimlessly while idle.")] - public abstract class WandersInfo : ITraitInfo + public class WandersInfo : UpgradableTraitInfo, Requires { public readonly int WanderMoveRadius = 1; @@ -28,13 +28,14 @@ namespace OpenRA.Mods.Common.Traits [Desc("Maximum amount of ticks the actor will sit idly before starting to wander.")] public readonly int MaxMoveDelay = 0; - public abstract object Create(ActorInitializer init); + public override object Create(ActorInitializer init) { return new Wanders(init.Self, this); } } - public class Wanders : INotifyIdle, INotifyBecomingIdle + public class Wanders : UpgradableTrait, INotifyCreated, INotifyIdle, INotifyBecomingIdle { readonly Actor self; readonly WandersInfo info; + IResolveOrder move; int countdown; int ticksIdle; @@ -42,12 +43,18 @@ namespace OpenRA.Mods.Common.Traits bool firstTick = true; public Wanders(Actor self, WandersInfo info) + : base(info) { this.self = self; this.info = info; effectiveMoveRadius = info.WanderMoveRadius; } + void INotifyCreated.Created(Actor self) + { + move = self.Trait() as IResolveOrder; + } + public virtual void OnBecomingIdle(Actor self) { countdown = self.World.SharedRandom.Next(info.MinMoveDelay, info.MaxMoveDelay); @@ -55,6 +62,9 @@ namespace OpenRA.Mods.Common.Traits public virtual void TickIdle(Actor self) { + if (IsTraitDisabled) + return; + // OnBecomingIdle has not been called yet at this point, so set the initial countdown here if (firstTick) { @@ -93,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits public virtual void DoAction(Actor self, CPos targetCell) { - throw new NotImplementedException("Base class Wanders does not implement method DoAction!"); + move.ResolveOrder(self, new Order("Move", self, false) { TargetLocation = targetCell }); } } } diff --git a/OpenRA.Mods.D2k/Activities/SwallowActor.cs b/OpenRA.Mods.D2k/Activities/SwallowActor.cs index 242db18501..bc76d8fa60 100644 --- a/OpenRA.Mods.D2k/Activities/SwallowActor.cs +++ b/OpenRA.Mods.D2k/Activities/SwallowActor.cs @@ -149,7 +149,7 @@ namespace OpenRA.Mods.D2k.Activities sandworm.IsAttacking = false; // There is a chance that the worm would just go away after attacking - if (self.World.SharedRandom.Next(100) <= sandworm.Info.ChanceToDisappear) + if (self.World.SharedRandom.Next(100) <= sandworm.WormInfo.ChanceToDisappear) { self.CancelActivity(); self.World.AddFrameEndTask(w => self.Dispose()); diff --git a/OpenRA.Mods.D2k/Traits/Sandworm.cs b/OpenRA.Mods.D2k/Traits/Sandworm.cs index aed5aef875..0fd131dbb3 100644 --- a/OpenRA.Mods.D2k/Traits/Sandworm.cs +++ b/OpenRA.Mods.D2k/Traits/Sandworm.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.D2k.Traits class Sandworm : Wanders, ITick, INotifyActorDisposing { - public readonly SandwormInfo Info; + public readonly SandwormInfo WormInfo; readonly WormManager manager; readonly Mobile mobile; @@ -50,7 +50,7 @@ namespace OpenRA.Mods.D2k.Traits public Sandworm(Actor self, SandwormInfo info) : base(self, info) { - Info = info; + WormInfo = info; mobile = self.Trait(); attackTrait = self.Trait(); manager = self.World.WorldActor.Trait(); @@ -78,10 +78,10 @@ namespace OpenRA.Mods.D2k.Traits void RescanForTargets(Actor self) { - targetCountdown = Info.TargetRescanInterval; + targetCountdown = WormInfo.TargetRescanInterval; // If close enough, we don't care about other actors. - var target = self.World.FindActorsInCircle(self.CenterPosition, Info.IgnoreNoiseAttackRange) + var target = self.World.FindActorsInCircle(self.CenterPosition, WormInfo.IgnoreNoiseAttackRange) .FirstOrDefault(x => attackTrait.HasAnyValidWeapons(Target.FromActor(x))); if (target != null) { @@ -98,7 +98,7 @@ namespace OpenRA.Mods.D2k.Traits return mobile.CanEnterCell(a.Location, null, false); }; - var actorsInRange = self.World.FindActorsInCircle(self.CenterPosition, Info.MaxSearchRadius) + var actorsInRange = self.World.FindActorsInCircle(self.CenterPosition, WormInfo.MaxSearchRadius) .Where(isValidTarget).SelectMany(a => a.TraitsImplementing()); var noiseDirection = actorsInRange.Aggregate(WVec.Zero, (a, b) => a + b.AttractionAtPosition(self.CenterPosition));