Fix Wanders to be usable on its own

Allows unarmed actors like civilians or harmless critters to wander around when idle.

Additionally made it upgradable.
This commit is contained in:
reaperrr
2016-06-25 12:45:58 +02:00
parent c643a0abd6
commit 09e365bc4a
3 changed files with 20 additions and 10 deletions

View File

@@ -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<IMoveInfo>
{
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<WandersInfo>, 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<IMove>() 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 });
}
}
}

View File

@@ -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());

View File

@@ -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<Mobile>();
attackTrait = self.Trait<AttackBase>();
manager = self.World.WorldActor.Trait<WormManager>();
@@ -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<AttractsWorms>());
var noiseDirection = actorsInRange.Aggregate(WVec.Zero, (a, b) => a + b.AttractionAtPosition(self.CenterPosition));