Merge pull request #4478 from pchote/aircraft-follow

Add Guard and AttackMove to RA and C&C aircraft.
This commit is contained in:
Matthias Mailänder
2014-02-01 00:38:21 -08:00
46 changed files with 243 additions and 157 deletions

View File

@@ -1,6 +1,8 @@
NEW: NEW:
All Mods: All Mods:
An error dialog is now displayed when server connections are lost. An error dialog is now displayed when server connections are lost.
Added AttackMove and Guard abilities to Aircraft and Helicopters.
Aircraft and Helicopters can now be guarded by other units.
Unified the main menu navigation between TD and other mods: Unified the main menu navigation between TD and other mods:
Moved Create Game and Direct Connect facilities to the server browser. Moved Create Game and Direct Connect facilities to the server browser.
Added skirmish mode to RA and D2k to complement TD's skirmish mode. Added skirmish mode to RA and D2k to complement TD's skirmish mode.
@@ -19,7 +21,6 @@ NEW:
Fixed transparency glitches in the sniper icon. Fixed transparency glitches in the sniper icon.
Tiberian Dawn: Tiberian Dawn:
Commando can now plant C4 on bridges. Commando can now plant C4 on bridges.
Helicopters can now AttackMove.
Engine: Engine:
Converted Aircraft CruiseAltitude to world coordinates. Converted Aircraft CruiseAltitude to world coordinates.
Converted Health Radius to world coordinates. Converted Health Radius to world coordinates.

View File

@@ -153,6 +153,7 @@ namespace OpenRA.Traits
Activity MoveTo(CPos cell, int nearEnough); Activity MoveTo(CPos cell, int nearEnough);
Activity MoveTo(CPos cell, Actor ignoredActor); Activity MoveTo(CPos cell, Actor ignoredActor);
Activity MoveWithinRange(Target target, WRange range); Activity MoveWithinRange(Target target, WRange range);
Activity MoveFollow(Actor self, Target target, WRange range);
CPos NearestMoveableCell(CPos target); CPos NearestMoveableCell(CPos target);
} }

View File

@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Cnc
new FacingInit(64) new FacingInit(64)
}); });
a.QueueActivity(Fly.ToCell(self.Location + new CVec(9, 0))); a.QueueActivity(new Fly(a, Target.FromCell(self.Location + new CVec(9, 0))));
a.QueueActivity(new Land(Target.FromActor(self))); a.QueueActivity(new Land(Target.FromActor(self)));
a.QueueActivity(new CallFunc(() => a.QueueActivity(new CallFunc(() =>
{ {
@@ -71,7 +71,8 @@ namespace OpenRA.Mods.Cnc
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit)); self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit));
Sound.PlayNotification(self.Owner, "Speech", (Info as ProductionAirdropInfo).ReadyAudio, self.Owner.Country.Race); Sound.PlayNotification(self.Owner, "Speech", (Info as ProductionAirdropInfo).ReadyAudio, self.Owner.Country.Race);
})); }));
a.QueueActivity(Fly.ToCell(endPos));
a.QueueActivity(new Fly(a, Target.FromCell(endPos)));
a.QueueActivity(new RemoveSelf()); a.QueueActivity(new RemoveSelf());
}); });

View File

@@ -0,0 +1,44 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 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. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class FlyFollow : Activity
{
Target target;
Plane plane;
WRange range;
public FlyFollow(Actor self, Target target, WRange range)
{
this.target = target;
plane = self.Trait<Plane>();
this.range = range;
}
public override Activity Tick(Actor self)
{
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;
if (target.IsInRange(self.CenterPosition, range))
{
Fly.FlyToward(self, plane, plane.Facing, plane.Info.CruiseAltitude);
return this;
}
return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), this);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Mods.RA.Activities
public class Follow : Activity public class Follow : Activity
{ {
Target target; Target target;
Mobile mobile; IMove move;
WRange range; WRange range;
int nextPathTime; int nextPathTime;
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities
public Follow(Actor self, Target target, WRange range) public Follow(Actor self, Target target, WRange range)
{ {
this.target = target; this.target = target;
mobile = self.Trait<Mobile>(); move = self.Trait<IMove>();
this.range = range; this.range = range;
} }
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.RA.Activities
nextPathTime = self.World.SharedRandom.Next(delayBetweenPathingAttempts - delaySpread, nextPathTime = self.World.SharedRandom.Next(delayBetweenPathingAttempts - delaySpread,
delayBetweenPathingAttempts + delaySpread); delayBetweenPathingAttempts + delaySpread);
return Util.SequenceActivities(mobile.MoveWithinRange(target, range), this); return Util.SequenceActivities(move.MoveWithinRange(target, range), this);
} }
} }
} }

View File

@@ -15,9 +15,23 @@ namespace OpenRA.Mods.RA.Air
{ {
public class Fly : Activity public class Fly : Activity
{ {
readonly WPos pos; readonly Plane plane;
readonly Target target;
readonly WRange maxRange;
readonly WRange minRange;
Fly(WPos pos) { this.pos = pos; } public Fly(Actor self, Target t)
{
plane = self.Trait<Plane>();
target = t;
}
public Fly(Actor self, Target t, WRange minRange, WRange maxRange)
: this(self, t)
{
this.maxRange = maxRange;
this.minRange = minRange;
}
public static void FlyToward(Actor self, Plane plane, int desiredFacing, WRange desiredAltitude) public static void FlyToward(Actor self, Plane plane, int desiredFacing, WRange desiredAltitude)
{ {
@@ -36,20 +50,22 @@ namespace OpenRA.Mods.RA.Air
plane.SetPosition(self, plane.CenterPosition + move); plane.SetPosition(self, plane.CenterPosition + move);
} }
public static Fly ToPos(WPos pos) { return new Fly(pos); }
public static Fly ToCell(CPos pos) { return new Fly(pos.CenterPosition); }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled) if (IsCanceled)
return NextActivity; return NextActivity;
// Inside the target annulus, so we're done
var insideMaxRange = maxRange.Range > 0 && target.IsInRange(plane.CenterPosition, maxRange);
var insideMinRange = minRange.Range > 0 && target.IsInRange(plane.CenterPosition, minRange);
if (insideMaxRange && !insideMinRange)
return NextActivity;
// Close enough (ported from old code which checked length against sqrt(50) px) // Close enough (ported from old code which checked length against sqrt(50) px)
var d = pos - self.CenterPosition; var d = target.CenterPosition - self.CenterPosition;
if (d.HorizontalLengthSquared < 91022) if (d.HorizontalLengthSquared < 91022)
return NextActivity; return NextActivity;
var plane = self.Trait<Plane>();
var desiredFacing = Util.GetFacing(d, plane.Facing); var desiredFacing = Util.GetFacing(d, plane.Facing);
// Don't turn until we've reached the cruise altitude // Don't turn until we've reached the cruise altitude
@@ -63,7 +79,7 @@ namespace OpenRA.Mods.RA.Air
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)
{ {
yield return Target.FromPos(pos); yield return target;
} }
} }
} }

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Air
if (IsCanceled) if (IsCanceled)
return NextActivity; return NextActivity;
inner = Util.SequenceActivities(Fly.ToPos(target.CenterPosition), new FlyTimed(50)); inner = Util.SequenceActivities(new Fly(self, target), new FlyTimed(50));
} }
inner = Util.RunActivity(self, inner); inner = Util.RunActivity(self, inner);

View File

@@ -15,10 +15,23 @@ namespace OpenRA.Mods.RA.Air
{ {
class HeliFly : Activity class HeliFly : Activity
{ {
readonly WPos pos; readonly Helicopter helicopter;
readonly Target target;
readonly WRange maxRange;
readonly WRange minRange;
public HeliFly(WPos pos) { this.pos = pos; } public HeliFly(Actor self, Target t)
public HeliFly(CPos pos) { this.pos = pos.CenterPosition; } {
helicopter = self.Trait<Helicopter>();
target = t;
}
public HeliFly(Actor self, Target t, WRange minRange, WRange maxRange)
: this(self, t)
{
this.maxRange = maxRange;
this.minRange = minRange;
}
public static bool AdjustAltitude(Actor self, Helicopter helicopter, WRange targetAltitude) public static bool AdjustAltitude(Actor self, Helicopter helicopter, WRange targetAltitude)
{ {
@@ -38,18 +51,29 @@ namespace OpenRA.Mods.RA.Air
if (IsCanceled) if (IsCanceled)
return NextActivity; return NextActivity;
var helicopter = self.Trait<Helicopter>();
if (AdjustAltitude(self, helicopter, helicopter.Info.CruiseAltitude)) if (AdjustAltitude(self, helicopter, helicopter.Info.CruiseAltitude))
return this; return this;
var pos = target.CenterPosition;
// Rotate towards the target // Rotate towards the target
var dist = pos - self.CenterPosition; var dist = pos - self.CenterPosition;
var desiredFacing = Util.GetFacing(dist, helicopter.Facing); var desiredFacing = Util.GetFacing(dist, helicopter.Facing);
helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT); helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT);
var move = helicopter.FlyStep(desiredFacing);
// Inside the minimum range, so reverse
if (minRange.Range > 0 && target.IsInRange(helicopter.CenterPosition, minRange))
{
helicopter.SetPosition(self, helicopter.CenterPosition - move);
return this;
}
// Inside the maximum range, so we're done
if (maxRange.Range > 0 && target.IsInRange(helicopter.CenterPosition, maxRange))
return NextActivity;
// The next move would overshoot, so just set the final position // The next move would overshoot, so just set the final position
var move = helicopter.FlyStep(desiredFacing);
if (dist.HorizontalLengthSquared < move.HorizontalLengthSquared) if (dist.HorizontalLengthSquared < move.HorizontalLengthSquared)
{ {
helicopter.SetPosition(self, pos + new WVec(0, 0, helicopter.Info.CruiseAltitude.Range - pos.Z)); helicopter.SetPosition(self, pos + new WVec(0, 0, helicopter.Info.CruiseAltitude.Range - pos.Z));
@@ -63,7 +87,7 @@ namespace OpenRA.Mods.RA.Air
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)
{ {
yield return Target.FromPos(pos); yield return target;
} }
} }
} }

View File

@@ -42,7 +42,7 @@ namespace OpenRA.Mods.RA.Air
if (nearestHpad == null) if (nearestHpad == null)
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true), NextActivity); return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true), NextActivity);
else else
return Util.SequenceActivities(new HeliFly(nearestHpad.CenterPosition)); return Util.SequenceActivities(new HeliFly(self, Target.FromActor(nearestHpad)));
} }
var res = dest.TraitOrDefault<Reservable>(); var res = dest.TraitOrDefault<Reservable>();
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA.Air
var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero; var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero;
return Util.SequenceActivities( return Util.SequenceActivities(
new HeliFly(dest.CenterPosition + offset), new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
new Turn(initialFacing), new Turn(initialFacing),
new HeliLand(false), new HeliLand(false),
new Rearm(self), new Rearm(self),

View File

@@ -28,11 +28,13 @@ namespace OpenRA.Mods.RA.Air
class Helicopter : Aircraft, ITick, IResolveOrder, IMove class Helicopter : Aircraft, ITick, IResolveOrder, IMove
{ {
public HelicopterInfo Info; public HelicopterInfo Info;
Actor self;
bool firstTick = true; bool firstTick = true;
public Helicopter(ActorInitializer init, HelicopterInfo info) public Helicopter(ActorInitializer init, HelicopterInfo info)
: base(init, info) : base(init, info)
{ {
self = init.self;
Info = info; Info = info;
} }
@@ -46,11 +48,12 @@ namespace OpenRA.Mods.RA.Air
if (order.OrderString == "Move") if (order.OrderString == "Move")
{ {
var target = self.World.ClampToWorld(order.TargetLocation); var cell = self.World.ClampToWorld(order.TargetLocation);
var t = Target.FromCell(cell);
self.SetTargetLine(Target.FromCell(target), Color.Green); self.SetTargetLine(t, Color.Green);
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new HeliFly(target)); self.QueueActivity(new HeliFly(self, t));
if (Info.LandWhenIdle) if (Info.LandWhenIdle)
{ {
@@ -78,7 +81,7 @@ namespace OpenRA.Mods.RA.Air
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green); self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new HeliFly(order.TargetActor.CenterPosition + offset)); self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset)));
self.QueueActivity(new Turn(Info.InitialFacing)); self.QueueActivity(new Turn(Info.InitialFacing));
self.QueueActivity(new HeliLand(false)); self.QueueActivity(new HeliLand(false));
self.QueueActivity(new ResupplyAircraft()); self.QueueActivity(new ResupplyAircraft());
@@ -149,9 +152,11 @@ namespace OpenRA.Mods.RA.Air
return (d * 1024 * 8) / (int)distSq; return (d * 1024 * 8) / (int)distSq;
} }
public Activity MoveTo(CPos cell, int nearEnough) { return new HeliFly(cell); } public Activity MoveTo(CPos cell, int nearEnough) { return new HeliFly(self, Target.FromCell(cell)); }
public Activity MoveTo(CPos cell, Actor ignoredActor) { return new HeliFly(cell); } public Activity MoveTo(CPos cell, Actor ignoredActor) { return new HeliFly(self, Target.FromCell(cell)); }
public Activity MoveWithinRange(Target target, WRange range) { return new HeliFly(target.CenterPosition); } public Activity MoveWithinRange(Target target, WRange range) { return new HeliFly(self, target, WRange.Zero, range); }
public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { return new HeliFly(self, target, minRange, maxRange); }
public Activity MoveFollow(Actor self, Target target, WRange range) { return new Follow(self, target, range); }
public CPos NearestMoveableCell(CPos cell) { return cell; } public CPos NearestMoveableCell(CPos cell) { return cell; }
} }
} }

View File

@@ -9,6 +9,7 @@
#endregion #endregion
using System.Drawing; using System.Drawing;
using OpenRA.Mods.RA.Activities;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.RA.Air namespace OpenRA.Mods.RA.Air
@@ -24,10 +25,12 @@ namespace OpenRA.Mods.RA.Air
{ {
public readonly PlaneInfo Info; public readonly PlaneInfo Info;
[Sync] public WPos RTBPathHash; [Sync] public WPos RTBPathHash;
Actor self;
public Plane(ActorInitializer init, PlaneInfo info) public Plane(ActorInitializer init, PlaneInfo info)
: base(init, info) : base(init, info)
{ {
self = init.self;
Info = info; Info = info;
} }
@@ -48,10 +51,11 @@ namespace OpenRA.Mods.RA.Air
{ {
UnReserve(); UnReserve();
var target = self.World.ClampToWorld(order.TargetLocation); var cell = self.World.ClampToWorld(order.TargetLocation);
self.SetTargetLine(Target.FromCell(target), Color.Green); var t = Target.FromCell(cell);
self.SetTargetLine(t, Color.Green);
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(Fly.ToCell(target)); self.QueueActivity(new Fly(self, t));
self.QueueActivity(new FlyCircle()); self.QueueActivity(new FlyCircle());
} }
else if (order.OrderString == "Enter") else if (order.OrderString == "Enter")
@@ -89,9 +93,11 @@ namespace OpenRA.Mods.RA.Air
} }
} }
public Activity MoveTo(CPos cell, int nearEnough) { return Fly.ToCell(cell); } public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(cell)), new FlyCircle()); }
public Activity MoveTo(CPos cell, Actor ignoredActor) { return Fly.ToCell(cell); } public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(cell)), new FlyCircle()); }
public Activity MoveWithinRange(Target target, WRange range) { return Fly.ToPos(target.CenterPosition); } public Activity MoveWithinRange(Target target, WRange range) { return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), new FlyCircle()); }
public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle()); }
public Activity MoveFollow(Actor self, Target target, WRange range) { return new FlyFollow(self, target, range); }
public CPos NearestMoveableCell(CPos cell) { return cell; } public CPos NearestMoveableCell(CPos cell) { return cell; }
} }
} }

View File

@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA.Air
return; return;
} }
self.QueueActivity(Fly.ToCell(someBuilding.Location)); self.QueueActivity(new Fly(self, Target.FromActor(someBuilding)));
self.QueueActivity(new FlyCircle()); self.QueueActivity(new FlyCircle());
} }
} }

View File

@@ -110,15 +110,15 @@ namespace OpenRA.Mods.RA.Air
self.CancelActivity(); self.CancelActivity();
if (nearestAfld != null) if (nearestAfld != null)
return Util.SequenceActivities(Fly.ToCell(nearestAfld.Location), new FlyCircle()); return Util.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld)), new FlyCircle());
else else
return new FlyCircle(); return new FlyCircle();
} }
return Util.SequenceActivities( return Util.SequenceActivities(
Fly.ToPos(w1), new Fly(self, Target.FromPos(w1)),
Fly.ToPos(w2), new Fly(self, Target.FromPos(w2)),
Fly.ToPos(w3), new Fly(self, Target.FromPos(w3)),
new Land(Target.FromActor(dest)), new Land(Target.FromActor(dest)),
NextActivity); NextActivity);
} }

View File

@@ -99,8 +99,10 @@ namespace OpenRA.Mods.RA
var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance)); var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance));
attack.Target = target; attack.Target = target;
if (allowMove && self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails) var mobile = self.TraitOrDefault<Mobile>();
return Util.SequenceActivities(new Follow(self, target, range), this);
if (allowMove && mobile != null && !mobile.Info.OnRails)
return Util.SequenceActivities(mobile.MoveFollow(self, target, range), this);
} }
return NextActivity; return NextActivity;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -8,10 +8,10 @@
*/ */
#endregion #endregion
using OpenRA.FileFormats;
using OpenRA.Traits;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
@@ -29,65 +29,79 @@ namespace OpenRA.Mods.RA
[Desc("Ticks to wait until next AutoTarget: attempt.")] [Desc("Ticks to wait until next AutoTarget: attempt.")]
public readonly int MaximumScanTimeInterval = 8; public readonly int MaximumScanTimeInterval = 8;
public readonly bool TargetWhenIdle = true;
public readonly bool TargetWhenDamaged = true;
public readonly bool EnableStances = true;
public object Create(ActorInitializer init) { return new AutoTarget(init.self, this); } public object Create(ActorInitializer init) { return new AutoTarget(init.self, this); }
} }
public enum UnitStance { HoldFire, ReturnFire, Defend, AttackAnything }; public enum UnitStance { HoldFire, ReturnFire, Defend, AttackAnything }
public class AutoTarget : INotifyIdle, INotifyDamage, ITick, IResolveOrder, ISync public class AutoTarget : INotifyIdle, INotifyDamage, ITick, IResolveOrder, ISync
{ {
readonly AutoTargetInfo Info; readonly AutoTargetInfo info;
readonly AttackBase attack; readonly AttackBase attack;
readonly AttackTurreted at; readonly AttackTurreted at;
[Sync] int nextScanTime = 0;
[Sync] public int nextScanTime = 0; public UnitStance Stance;
public UnitStance stance;
[Sync] public int stanceNumber { get { return (int)stance; } }
public UnitStance predictedStance; /* NOT SYNCED: do not refer to this anywhere other than UI code */
[Sync] public Actor Aggressor; [Sync] public Actor Aggressor;
[Sync] public Actor TargetedActor; [Sync] public Actor TargetedActor;
// NOT SYNCED: do not refer to this anywhere other than UI code
public UnitStance PredictedStance;
public AutoTarget(Actor self, AutoTargetInfo info) public AutoTarget(Actor self, AutoTargetInfo info)
{ {
Info = info; this.info = info;
attack = self.Trait<AttackBase>(); attack = self.Trait<AttackBase>();
stance = Info.InitialStance; Stance = info.InitialStance;
predictedStance = stance; PredictedStance = Stance;
at = self.TraitOrDefault<AttackTurreted>(); at = self.TraitOrDefault<AttackTurreted>();
} }
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
{ {
if (order.OrderString == "SetUnitStance") if (order.OrderString == "SetUnitStance" && info.EnableStances)
stance = (UnitStance)order.TargetLocation.X; Stance = (UnitStance)order.TargetLocation.X;
} }
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)
{ {
if (!self.IsIdle) return; if (!self.IsIdle || !info.TargetWhenDamaged)
if (e.Attacker.Destroyed) return; return;
if (stance < UnitStance.ReturnFire) return; if (e.Attacker.Destroyed)
return;
if (Stance < UnitStance.ReturnFire) return;
// not a lot we can do about things we can't hurt... although maybe we should automatically run away? // not a lot we can do about things we can't hurt... although maybe we should automatically run away?
if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return; if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker)))
return;
// don't retaliate against own units force-firing on us. it's usually not what the player wanted. // don't retaliate against own units force-firing on us. It's usually not what the player wanted.
if (e.Attacker.AppearsFriendlyTo(self)) return; if (e.Attacker.AppearsFriendlyTo(self))
return;
if (e.Damage < 0) return; // don't retaliate against healers // don't retaliate against healers
if (e.Damage < 0)
return;
Aggressor = e.Attacker; Aggressor = e.Attacker;
if (at == null || !at.IsReachableTarget(at.Target, Info.AllowMovement && stance != UnitStance.Defend)) if (at == null || !at.IsReachableTarget(at.Target, info.AllowMovement && Stance != UnitStance.Defend))
Attack(self, e.Attacker); Attack(self, e.Attacker);
} }
public void TickIdle(Actor self) public void TickIdle(Actor self)
{ {
if (stance < UnitStance.Defend) return; if (Stance < UnitStance.Defend || !info.TargetWhenIdle)
return;
if (at == null || !at.IsReachableTarget(at.Target, Info.AllowMovement && stance != UnitStance.Defend)) var allowMovement = info.AllowMovement && Stance != UnitStance.Defend;
if (at == null || !at.IsReachableTarget(at.Target, allowMovement))
ScanAndAttack(self); ScanAndAttack(self);
} }
@@ -99,7 +113,7 @@ namespace OpenRA.Mods.RA
public Actor ScanForTarget(Actor self, Actor currentTarget) public Actor ScanForTarget(Actor self, Actor currentTarget)
{ {
var range = Info.ScanRadius > 0 ? WRange.FromCells(Info.ScanRadius) : attack.GetMaximumRange(); var range = info.ScanRadius > 0 ? WRange.FromCells(info.ScanRadius) : attack.GetMaximumRange();
if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range))
if (nextScanTime <= 0) if (nextScanTime <= 0)
return ChooseTarget(self, range); return ChooseTarget(self, range);
@@ -119,12 +133,12 @@ namespace OpenRA.Mods.RA
TargetedActor = targetActor; TargetedActor = targetActor;
var target = Target.FromActor(targetActor); var target = Target.FromActor(targetActor);
self.SetTargetLine(target, Color.Red, false); self.SetTargetLine(target, Color.Red, false);
attack.AttackTarget(target, false, Info.AllowMovement && stance != UnitStance.Defend); attack.AttackTarget(target, false, info.AllowMovement && Stance != UnitStance.Defend);
} }
Actor ChooseTarget(Actor self, WRange range) Actor ChooseTarget(Actor self, WRange range)
{ {
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval); nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval);
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range); var inRange = self.World.FindActorsInCircle(self.CenterPosition, range);
if (self.Owner.HasFogVisibility()) if (self.Owner.HasFogVisibility())
@@ -150,5 +164,4 @@ namespace OpenRA.Mods.RA
[Desc("Will not get automatically targeted by enemy (like walls)")] [Desc("Will not get automatically targeted by enemy (like walls)")]
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { } class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
class AutoTargetIgnore { } class AutoTargetIgnore { }
} }

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
class GuardInfo : TraitInfo<Guard>, Requires<MobileInfo> { } class GuardInfo : TraitInfo<Guard> { }
class Guard : IResolveOrder, IOrderVoice class Guard : IResolveOrder, IOrderVoice
{ {
@@ -30,8 +30,7 @@ namespace OpenRA.Mods.RA
self.SetTargetLine(target, Color.Yellow); self.SetTargetLine(target, Color.Yellow);
var range = WRange.FromCells(target.Actor.Info.Traits.Get<GuardableInfo>().Range); var range = WRange.FromCells(target.Actor.Info.Traits.Get<GuardableInfo>().Range);
self.QueueActivity(false, new AttackMove.AttackMoveActivity(self, self.QueueActivity(false, new AttackMove.AttackMoveActivity(self, self.Trait<IMove>().MoveFollow(self, target, range)));
new Follow(self, target, range)));
} }
} }

View File

@@ -272,7 +272,7 @@ namespace OpenRA.Mods.RA.Missions
void SetAlliedUnitsToDefensiveStance() void SetAlliedUnitsToDefensiveStance()
{ {
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == allies && !a.IsDead() && a.HasTrait<AutoTarget>())) foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == allies && !a.IsDead() && a.HasTrait<AutoTarget>()))
actor.Trait<AutoTarget>().stance = UnitStance.Defend; actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
} }
public void WorldLoaded(World w, WorldRenderer wr) public void WorldLoaded(World w, WorldRenderer wr)

View File

@@ -349,7 +349,7 @@ namespace OpenRA.Mods.RA.Missions
void SetupSubStances() void SetupSubStances()
{ {
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<TargetableSubmarine>())) foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<TargetableSubmarine>()))
actor.Trait<AutoTarget>().stance = UnitStance.Defend; actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
} }
public void WorldLoaded(World w, WorldRenderer wr) public void WorldLoaded(World w, WorldRenderer wr)

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
@@ -206,7 +206,7 @@ namespace OpenRA.Mods.RA.Missions
new FacingInit(Traits.Util.GetFacing(waypoints[1] - waypoints[0], 0)) new FacingInit(Traits.Util.GetFacing(waypoints[1] - waypoints[0], 0))
}); });
foreach (var waypoint in waypoints) foreach (var waypoint in waypoints)
m.QueueActivity(Fly.ToCell(waypoint)); m.QueueActivity(new Fly(m, Target.FromCell(waypoint)));
m.QueueActivity(new RemoveSelf()); m.QueueActivity(new RemoveSelf());
} }
@@ -221,12 +221,12 @@ namespace OpenRA.Mods.RA.Missions
var exit = lz.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault(); var exit = lz.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero; var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero;
chinook.QueueActivity(new HeliFly(lz.CenterPosition + offset)); // no reservation of hpad but it's not needed chinook.QueueActivity(new HeliFly(chinook, Target.FromPos(lz.CenterPosition + offset))); // no reservation of hpad but it's not needed
chinook.QueueActivity(new Turn(0)); chinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(false)); chinook.QueueActivity(new HeliLand(false));
chinook.QueueActivity(new UnloadCargo(true)); chinook.QueueActivity(new UnloadCargo(true));
chinook.QueueActivity(new Wait(150)); chinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(entry)); chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(entry)));
chinook.QueueActivity(new RemoveSelf()); chinook.QueueActivity(new RemoveSelf());
} }
@@ -290,7 +290,7 @@ namespace OpenRA.Mods.RA.Missions
foreach (var actor in actors.Values) foreach (var actor in actors.Values)
{ {
if (actor.Owner == allies && actor.HasTrait<AutoTarget>()) if (actor.Owner == allies && actor.HasTrait<AutoTarget>())
actor.Trait<AutoTarget>().stance = UnitStance.Defend; actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
if (actor.IsInWorld && (actor.HasTrait<Bridge>() || actor.Owner == allies || (actor.Owner == soviets && actor.HasTrait<Building>()))) if (actor.IsInWorld && (actor.HasTrait<Bridge>() || actor.Owner == allies || (actor.Owner == soviets && actor.HasTrait<Building>())))
actor.AddTrait(new Invulnerable()); actor.AddTrait(new Invulnerable());

View File

@@ -45,12 +45,12 @@ namespace OpenRA.Mods.RA.Missions
public static Actor ExtractUnitWithChinook(World world, Player owner, Actor unit, CPos entry, CPos lz, CPos exit) public static Actor ExtractUnitWithChinook(World world, Player owner, Actor unit, CPos entry, CPos lz, CPos exit)
{ {
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) }); var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
chinook.QueueActivity(new HeliFly(lz)); chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(lz)));
chinook.QueueActivity(new Turn(0)); chinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(true)); chinook.QueueActivity(new HeliLand(true));
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit))); chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit)));
chinook.QueueActivity(new Wait(150)); chinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(exit)); chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(exit)));
chinook.QueueActivity(new RemoveSelf()); chinook.QueueActivity(new RemoveSelf());
return chinook; return chinook;
} }
@@ -60,13 +60,13 @@ namespace OpenRA.Mods.RA.Missions
var unit = world.CreateActor(false, unitName, new TypeDictionary { new OwnerInit(owner) }); var unit = world.CreateActor(false, unitName, new TypeDictionary { new OwnerInit(owner) });
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) }); var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
chinook.Trait<Cargo>().Load(chinook, unit); chinook.Trait<Cargo>().Load(chinook, unit);
chinook.QueueActivity(new HeliFly(lz)); chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(lz)));
chinook.QueueActivity(new Turn(0)); chinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(true)); chinook.QueueActivity(new HeliLand(true));
chinook.QueueActivity(new UnloadCargo(true)); chinook.QueueActivity(new UnloadCargo(true));
chinook.QueueActivity(new CallFunc(() => afterUnload(unit))); chinook.QueueActivity(new CallFunc(() => afterUnload(unit)));
chinook.QueueActivity(new Wait(150)); chinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(exit)); chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(exit)));
chinook.QueueActivity(new RemoveSelf()); chinook.QueueActivity(new RemoveSelf());
return Pair.New(chinook, unit); return Pair.New(chinook, unit);
} }
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.RA.Missions
}); });
badger.Trait<AttackBomber>().SetTarget(location.CenterPosition); badger.Trait<AttackBomber>().SetTarget(location.CenterPosition);
badger.QueueActivity(Fly.ToCell(location)); badger.QueueActivity(new Fly(badger, Target.FromCell(location)));
badger.QueueActivity(new FlyOffMap()); badger.QueueActivity(new FlyOffMap());
badger.QueueActivity(new RemoveSelf()); badger.QueueActivity(new RemoveSelf());
} }

View File

@@ -123,7 +123,7 @@ namespace OpenRA.Mods.RA.Missions
void SetSovietUnitsToDefensiveStance() void SetSovietUnitsToDefensiveStance()
{ {
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<AutoTarget>())) foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<AutoTarget>()))
actor.Trait<AutoTarget>().stance = UnitStance.Defend; actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
} }
Actor FirstUnshroudedOrDefault(IEnumerable<Actor> actors, World world, int shroudRange) Actor FirstUnshroudedOrDefault(IEnumerable<Actor> actors, World world, int shroudRange)

View File

@@ -540,6 +540,7 @@ namespace OpenRA.Mods.RA.Move
public Activity MoveTo(CPos cell, int nearEnough) { return new Move(cell, nearEnough); } public Activity MoveTo(CPos cell, int nearEnough) { return new Move(cell, nearEnough); }
public Activity MoveTo(CPos cell, Actor ignoredActor) { return new Move(cell, ignoredActor); } public Activity MoveTo(CPos cell, Actor ignoredActor) { return new Move(cell, ignoredActor); }
public Activity MoveWithinRange(Target target, WRange range) { return new Move(target, range); } public Activity MoveWithinRange(Target target, WRange range) { return new Move(target, range); }
public Activity MoveFollow(Actor self, Target target, WRange range) { return new Follow(self, target, range); }
public Activity MoveTo(Func<List<CPos>> pathFunc) { return new Move(pathFunc); } public Activity MoveTo(Func<List<CPos>> pathFunc) { return new Move(pathFunc); }
} }
} }

View File

@@ -488,6 +488,7 @@
<Compile Include="Render\WithCrateBody.cs" /> <Compile Include="Render\WithCrateBody.cs" />
<Compile Include="Buildings\Demolishable.cs" /> <Compile Include="Buildings\Demolishable.cs" />
<Compile Include="Widgets\Logic\DisconnectWatcherLogic.cs" /> <Compile Include="Widgets\Logic\DisconnectWatcherLogic.cs" />
<Compile Include="Activities\FlyFollow.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj"> <ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
@@ -263,7 +263,7 @@ namespace OpenRA.Mods.RA.Scripting
[LuaGlobal] [LuaGlobal]
public void FlyToPos(Actor actor, WPos pos) public void FlyToPos(Actor actor, WPos pos)
{ {
actor.QueueActivity(Fly.ToPos(pos)); actor.QueueActivity(new Fly(actor, Target.FromPos(pos)));
} }
[LuaGlobal] [LuaGlobal]
@@ -278,12 +278,18 @@ namespace OpenRA.Mods.RA.Scripting
actor.QueueActivity(new FlyAttack(Target.FromCell(location))); actor.QueueActivity(new FlyAttack(Target.FromCell(location)));
} }
[LuaGlobal]
public void HeliFlyToPos(Actor actor, WPos pos)
{
actor.QueueActivity(new HeliFly(actor, Target.FromPos(pos)));
}
[LuaGlobal] [LuaGlobal]
public void SetUnitStance(Actor actor, string stance) public void SetUnitStance(Actor actor, string stance)
{ {
var at = actor.TraitOrDefault<AutoTarget>(); var at = actor.TraitOrDefault<AutoTarget>();
if (at != null) if (at != null)
at.stance = Enum<UnitStance>.Parse(stance); at.Stance = Enum<UnitStance>.Parse(stance);
} }
[LuaGlobal] [LuaGlobal]

View File

@@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA
if (flare != null) if (flare != null)
a.QueueActivity(new CallFunc(() => flare.Destroy())); a.QueueActivity(new CallFunc(() => flare.Destroy()));
a.QueueActivity(Fly.ToPos(finishEdge + spawnOffset)); a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
a.QueueActivity(new RemoveSelf()); a.QueueActivity(new RemoveSelf());
} }
}); });

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
}); });
plane.CancelActivity(); plane.CancelActivity();
plane.QueueActivity(Fly.ToCell(order.TargetLocation)); plane.QueueActivity(new Fly(plane, Target.FromCell(order.TargetLocation)));
plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w => plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w =>
{ {
var camera = w.CreateActor("camera", new TypeDictionary var camera = w.CreateActor("camera", new TypeDictionary

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.RA.Widgets
var stances = Enum<UnitStance>.GetValues(); var stances = Enum<UnitStance>.GetValues();
var nextStance = stances.Concat(stances) var nextStance = stances.Concat(stances)
.SkipWhile(s => s != actor.Second.predictedStance) .SkipWhile(s => s != actor.Second.PredictedStance)
.Skip(1) .Skip(1)
.First(); .First();
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.RA.Widgets
{ {
var at = a.TraitOrDefault<AutoTarget>(); var at = a.TraitOrDefault<AutoTarget>();
if (at != null) if (at != null)
at.predictedStance = nextStance; at.PredictedStance = nextStance;
// FIXME: Abuse of the type system here with `CPos` // FIXME: Abuse of the type system here with `CPos`
return new Order("SetUnitStance", a, false) { TargetLocation = new CPos((int)nextStance, 0) }; return new Order("SetUnitStance", a, false) { TargetLocation = new CPos((int)nextStance, 0) };

View File

@@ -116,6 +116,8 @@
EmptyWeapon: HeliExplode EmptyWeapon: HeliExplode
CombatDebugOverlay: CombatDebugOverlay:
AttackMove: AttackMove:
Guard:
Guardable:
BodyOrientation: BodyOrientation:
UpdatesPlayerStatistics: UpdatesPlayerStatistics:
Huntable: Huntable:
@@ -209,7 +211,6 @@
NotifyAll: true NotifyAll: true
ScaredyCat: ScaredyCat:
RenderInfantryPanic: RenderInfantryPanic:
AttackMove:
CrushableInfantry: CrushableInfantry:
^DINO: ^DINO:
@@ -274,6 +275,7 @@
CombatDebugOverlay: CombatDebugOverlay:
BodyOrientation: BodyOrientation:
Huntable: Huntable:
AttackMove:
LuaScriptEvents: LuaScriptEvents:
^Ship: ^Ship:

View File

@@ -171,7 +171,6 @@ E6:
Captures: Captures:
CaptureTypes: building, husk CaptureTypes: building, husk
-AutoTarget: -AutoTarget:
AttackMove:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
StandAnimations: stand, stand2 StandAnimations: stand, stand2

View File

@@ -66,6 +66,5 @@ LST:
Types: Infantry, Vehicle Types: Infantry, Vehicle
MaxWeight: 5 MaxWeight: 5
PipCount: 5 PipCount: 5
AttackMove:
RejectsOrders: RejectsOrders:

View File

@@ -27,7 +27,6 @@ MCV:
NoTransformSounds: deploy1.aud NoTransformSounds: deploy1.aud
RenderUnit: RenderUnit:
MustBeDestroyed: MustBeDestroyed:
AttackMove:
BaseBuilding: BaseBuilding:
LeavesHusk: LeavesHusk:
HuskActor: MCV.Husk HuskActor: MCV.Husk
@@ -67,7 +66,6 @@ HARV:
Type: Heavy Type: Heavy
RevealsShroud: RevealsShroud:
Range: 4 Range: 4
AttackMove:
LeavesHusk: LeavesHusk:
HuskActor: HARV.Husk HuskActor: HARV.Husk
-GainsExperience: -GainsExperience:
@@ -556,7 +554,6 @@ MHQ:
WithIdleOverlay@SPINNER: WithIdleOverlay@SPINNER:
Sequence: spinner Sequence: spinner
Offset: -256,0,256 Offset: -256,0,256
AttackMove:
Explodes: Explodes:
Weapon: UnitExplodeSmall Weapon: UnitExplodeSmall
EmptyWeapon: UnitExplodeSmall EmptyWeapon: UnitExplodeSmall

View File

@@ -29,7 +29,7 @@ end
Actor.ScriptedMove = function(actor, location) Actor.ScriptedMove = function(actor, location)
if Actor.HasTrait(actor, "Helicopter") then if Actor.HasTrait(actor, "Helicopter") then
actor:QueueActivity(OpenRA.New("HeliFly", { location.CenterPosition })) Internal.HeliFlyToPos(actor, location.CenterPosition)
else else
actor:QueueActivity(OpenRA.New("Move", { location })) actor:QueueActivity(OpenRA.New("Move", { location }))
end end
@@ -52,7 +52,7 @@ Actor.AttackMove = function(actor, location)
end end
Actor.HeliFly = function(actor, position) Actor.HeliFly = function(actor, position)
actor:QueueActivity(OpenRA.New("HeliFly", { position })) Internal.HeliFlyToPos(actor, position)
end end
Actor.HeliLand = function(actor, requireSpace) Actor.HeliLand = function(actor, requireSpace)

View File

@@ -207,6 +207,7 @@
BodyOrientation: BodyOrientation:
UpdatesPlayerStatistics: UpdatesPlayerStatistics:
Huntable: Huntable:
AttackMove:
LuaScriptEvents: LuaScriptEvents:
^Helicopter: ^Helicopter:

View File

@@ -52,7 +52,6 @@ ENGINEER:
Captures: Captures:
CaptureTypes: husk CaptureTypes: husk
-AutoTarget: -AutoTarget:
AttackMove:
BAZOOKA: BAZOOKA:
Inherits: ^Infantry Inherits: ^Infantry
@@ -110,5 +109,3 @@ MEDIC:
Passenger: Passenger:
PipType: Blue PipType: Blue
-AutoTarget: -AutoTarget:
AttackMove:

View File

@@ -297,5 +297,3 @@ SABOTEUR:
C4Demolition: C4Demolition:
C4Delay: 45 C4Delay: 45
-AutoTarget: -AutoTarget:
AttackMove:

View File

@@ -24,7 +24,6 @@
Range: 8 Range: 8
MustBeDestroyed: MustBeDestroyed:
BaseBuilding: BaseBuilding:
-AttackMove:
Explodes: Explodes:
Weapon: UnitExplodeScale Weapon: UnitExplodeScale
EmptyWeapon: UnitExplodeScale EmptyWeapon: UnitExplodeScale
@@ -80,7 +79,6 @@ HARVESTER:
Explodes: Explodes:
Weapon: UnitExplodeScale Weapon: UnitExplodeScale
EmptyWeapon: UnitExplodeScale EmptyWeapon: UnitExplodeScale
-AttackMove:
LeavesHusk: LeavesHusk:
HuskActor: Harvester.Husk HuskActor: Harvester.Husk
WithHarvestAnimation: WithHarvestAnimation:

View File

@@ -848,7 +848,6 @@ Rules:
TakeCover: TakeCover:
Spy: Spy:
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderSpy: RenderSpy:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2

View File

@@ -832,7 +832,6 @@ Rules:
Range: 40 Range: 40
RenderUnit: RenderUnit:
Image: MNLY Image: MNLY
AttackMove:
MustBeDestroyed: MustBeDestroyed:
Transforms: Transforms:
IntoActor: ftur IntoActor: ftur

View File

@@ -102,6 +102,10 @@ MIG:
ROT: 5 ROT: 5
Speed: 186 Speed: 186
RearmBuildings: afld RearmBuildings: afld
AutoTarget:
TargetWhenIdle: false
TargetWhenDamaged: false
EnableStances: false
RenderUnit: RenderUnit:
CameraPitch: 99 CameraPitch: 99
WithShadow: WithShadow:
@@ -154,6 +158,10 @@ YAK:
InitialFacing: 192 InitialFacing: 192
ROT: 5 ROT: 5
Speed: 149 Speed: 149
AutoTarget:
TargetWhenIdle: false
TargetWhenDamaged: false
EnableStances: false
RenderUnit: RenderUnit:
CameraPitch: 99 CameraPitch: 99
WithShadow: WithShadow:
@@ -247,6 +255,10 @@ HELI:
InitialFacing: 20 InitialFacing: 20
ROT: 4 ROT: 4
Speed: 149 Speed: 149
AutoTarget:
TargetWhenIdle: false
TargetWhenDamaged: false
EnableStances: false
RenderUnit: RenderUnit:
WithRotor: WithRotor:
Offset: 0,0,85 Offset: 0,0,85
@@ -293,6 +305,10 @@ HIND:
InitialFacing: 20 InitialFacing: 20
ROT: 4 ROT: 4
Speed: 112 Speed: 112
AutoTarget:
TargetWhenIdle: false
TargetWhenDamaged: false
EnableStances: false
RenderUnit: RenderUnit:
WithRotor: WithRotor:
WithShadow: WithShadow:

View File

@@ -196,6 +196,9 @@
TargetTypes: Air TargetTypes: Air
GroundedTargetTypes: Ground GroundedTargetTypes: Ground
HiddenUnderFog: HiddenUnderFog:
AttackMove:
Guard:
Guardable:
GainsExperience: GainsExperience:
GivesExperience: GivesExperience:
DrawLineToTarget: DrawLineToTarget:

View File

@@ -177,7 +177,6 @@ E6:
CaptureTypes: husk CaptureTypes: husk
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -212,7 +211,6 @@ SPY:
Infiltrates: Infiltrates:
Types: Cash, SupportPower, Exploration Types: Cash, SupportPower, Exploration
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderSpy: RenderSpy:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -289,7 +287,6 @@ MEDI:
Cursor: heal Cursor: heal
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -325,7 +322,6 @@ MECH:
Cursor: repair Cursor: repair
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -346,7 +342,6 @@ EINSTEIN:
RevealsShroud: RevealsShroud:
Range: 2 Range: 2
-AutoTarget: -AutoTarget:
AttackMove:
ProximityCaptor: ProximityCaptor:
Types: CivilianInfantry Types: CivilianInfantry
-RenderInfantry: -RenderInfantry:
@@ -369,7 +364,6 @@ DELPHI:
RevealsShroud: RevealsShroud:
Range: 2 Range: 2
-AutoTarget: -AutoTarget:
AttackMove:
ProximityCaptor: ProximityCaptor:
Types: CivilianInfantry Types: CivilianInfantry
-RenderInfantry: -RenderInfantry:
@@ -410,7 +404,6 @@ THF:
InfiltrateTypes: Cash InfiltrateTypes: Cash
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
AttackMove:
SHOK: SHOK:
Inherits: ^Infantry Inherits: ^Infantry

View File

@@ -43,7 +43,6 @@ SS:
-DetectCloaked: -DetectCloaked:
AutoTarget: AutoTarget:
InitialStance: HoldFire InitialStance: HoldFire
AttackMove:
MSUB: MSUB:
Inherits: ^Ship Inherits: ^Ship
@@ -90,7 +89,6 @@ MSUB:
-DetectCloaked: -DetectCloaked:
AutoTarget: AutoTarget:
InitialStance: HoldFire InitialStance: HoldFire
AttackMove:
DD: DD:
Inherits: ^Ship Inherits: ^Ship
@@ -225,7 +223,6 @@ LST:
PipCount: 5 PipCount: 5
IronCurtainable: IronCurtainable:
RepairableNear: RepairableNear:
AttackMove:
PT: PT:
Inherits: ^Ship Inherits: ^Ship

View File

@@ -271,7 +271,6 @@ HARV:
Range: 4 Range: 4
RenderHarvester: RenderHarvester:
ImagesByFullness: harvempty, harvhalf, harv ImagesByFullness: harvempty, harvhalf, harv
-AttackMove:
GpsDot: GpsDot:
String: Harvester String: Harvester
LeavesHusk: LeavesHusk:
@@ -316,7 +315,6 @@ MCV:
RenderUnit: RenderUnit:
MustBeDestroyed: MustBeDestroyed:
BaseBuilding: BaseBuilding:
-AttackMove:
LeavesHusk: LeavesHusk:
HuskActor: MCV.Husk HuskActor: MCV.Husk
@@ -418,7 +416,6 @@ MNLY.AP:
MineImmune: MineImmune:
LimitedAmmo: LimitedAmmo:
Ammo: 5 Ammo: 5
AttackMove:
DetectCloaked: DetectCloaked:
Range: 5 Range: 5
RenderDetectionCircle: RenderDetectionCircle:
@@ -451,7 +448,6 @@ MNLY.AT:
MineImmune: MineImmune:
LimitedAmmo: LimitedAmmo:
Ammo: 3 Ammo: 3
AttackMove:
DetectCloaked: DetectCloaked:
Range: 5 Range: 5
RenderDetectionCircle: RenderDetectionCircle:
@@ -480,7 +476,6 @@ TRUK:
RenderUnit: RenderUnit:
SupplyTruck: SupplyTruck:
Payload: 500 Payload: 500
AttackMove:
MGG: MGG:
Inherits: ^Vehicle Inherits: ^Vehicle
@@ -505,7 +500,6 @@ MGG:
WithIdleOverlay@SPINNER: WithIdleOverlay@SPINNER:
Offset: -299,0,171 Offset: -299,0,171
Sequence: spinner Sequence: spinner
AttackMove:
RevealsShroud: RevealsShroud:
Range: 6 Range: 6
CreatesShroud: CreatesShroud:
@@ -542,7 +536,6 @@ MRJ:
WithIdleOverlay@SPINNER: WithIdleOverlay@SPINNER:
Sequence: spinner Sequence: spinner
Offset: -256,0,256 Offset: -256,0,256
AttackMove:
Explodes: Explodes:
Weapon: UnitExplodeSmall Weapon: UnitExplodeSmall
EmptyWeapon: UnitExplodeSmall EmptyWeapon: UnitExplodeSmall
@@ -646,7 +639,6 @@ DTRK:
RevealsShroud: RevealsShroud:
Range: 3 Range: 3
RenderUnit: RenderUnit:
AttackMove:
Explodes: Explodes:
Weapon: MiniNuke Weapon: MiniNuke
EmptyWeapon: MiniNuke EmptyWeapon: MiniNuke
@@ -717,11 +709,9 @@ QTNK:
Selectable: Selectable:
Bounds: 44,38,0,-4 Bounds: 44,38,0,-4
RenderUnit: RenderUnit:
AttackMove:
Explodes: Explodes:
Weapon: UnitExplodeSmall Weapon: UnitExplodeSmall
MadTank: MadTank:
-EjectOnDeath: -EjectOnDeath:
TargetableUnit: TargetableUnit:
TargetTypes: Ground, MADTank TargetTypes: Ground, MADTank

View File

@@ -195,6 +195,7 @@
Buildable: Buildable:
Queue: Aircraft Queue: Aircraft
HiddenUnderFog: HiddenUnderFog:
AttackMove:
GainsExperience: GainsExperience:
GivesExperience: GivesExperience:
DrawLineToTarget: DrawLineToTarget:

View File

@@ -165,7 +165,6 @@ ENGINEER:
Captures: Captures:
CaptureTypes: building CaptureTypes: building
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -292,7 +291,6 @@ CHAMSPY:
Infiltrates: Infiltrates:
Types: Cash, SupportPower, Exploration Types: Cash, SupportPower, Exploration
-AutoTarget: -AutoTarget:
AttackMove:
-RenderInfantry: -RenderInfantry:
RenderSpy: RenderSpy:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -468,7 +466,6 @@ MHIJACK:
RevealsShroud: RevealsShroud:
Range: 6 Range: 6
-AutoTarget: -AutoTarget:
-AttackMove:
TakeCover: TakeCover:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
@@ -495,7 +492,6 @@ TRATOS:
Range: 4 Range: 4
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
-AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -521,7 +517,6 @@ OXANNA:
Range: 4 Range: 4
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
-AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -547,7 +542,6 @@ SLAV:
Range: 4 Range: 4
TakeCover: TakeCover:
-AutoTarget: -AutoTarget:
-AttackMove:
-RenderInfantry: -RenderInfantry:
RenderInfantryProne: RenderInfantryProne:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
@@ -605,7 +599,6 @@ VISSML:
TargetableUnit: TargetableUnit:
TargetTypes: Ground TargetTypes: Ground
-AutoTarget: -AutoTarget:
-AttackMove:
-RenderInfantry: -RenderInfantry:
RenderUnit: RenderUnit:

View File

@@ -24,7 +24,6 @@ MCV:
Range: 4 Range: 4
MustBeDestroyed: MustBeDestroyed:
BaseBuilding: BaseBuilding:
-AttackMove:
Transforms: Transforms:
IntoActor: gacnst IntoActor: gacnst
Offset: -1,-1 Offset: -1,-1
@@ -57,7 +56,6 @@ APC:
Range: 5 Range: 5
Turreted: Turreted:
ROT: 10 ROT: 10
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 5 MaxWeight: 5
@@ -93,7 +91,6 @@ HARV:
Type: Heavy Type: Heavy
RevealsShroud: RevealsShroud:
Range: 4 Range: 4
AttackMove:
-GainsExperience: -GainsExperience:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
@@ -188,7 +185,6 @@ TRUCKB:
Range: 5 Range: 5
SupplyTruck: SupplyTruck:
Payload: 500 Payload: 500
AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody:
@@ -212,7 +208,6 @@ LPST:
ROT: 5 ROT: 5
RevealsShroud: RevealsShroud:
Range: 10 Range: 10
AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody:
@@ -242,7 +237,6 @@ ICBM:
ROT: 5 ROT: 5
RevealsShroud: RevealsShroud:
Range: 7 Range: 7
AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody:
@@ -275,7 +269,6 @@ REPAIR:
Weapon: Repair Weapon: Repair
AttackMedic: AttackMedic:
Cursor: repair Cursor: repair
AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody:
@@ -299,7 +292,6 @@ ART2:
ROT: 2 ROT: 2
RevealsShroud: RevealsShroud:
Range: 9 Range: 9
AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody:
@@ -330,7 +322,6 @@ WEED:
Type: Heavy Type: Heavy
RevealsShroud: RevealsShroud:
Range: 4 Range: 4
AttackMove:
-GainsExperience: -GainsExperience:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
@@ -355,7 +346,6 @@ BUS:
Type: Light Type: Light
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 20 MaxWeight: 20
@@ -384,7 +374,6 @@ PICK:
Type: Light Type: Light
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 2 MaxWeight: 2
@@ -413,7 +402,6 @@ CAR:
Type: Light Type: Light
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 4 MaxWeight: 4
@@ -443,7 +431,6 @@ GGHUNT:
RevealsShroud: RevealsShroud:
Range: 7 Range: 7
RenderUnit: RenderUnit:
AttackMove:
DemoTruck: DemoTruck:
Explodes: Explodes:
Weapon: SuicideBomb Weapon: SuicideBomb
@@ -468,7 +455,6 @@ WINI:
Type: Light Type: Light
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 5 MaxWeight: 5
@@ -648,7 +634,6 @@ SAPC:
Type: Heavy Type: Heavy
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
Cargo: Cargo:
Types: Infantry Types: Infantry
MaxWeight: 5 MaxWeight: 5
@@ -734,7 +719,6 @@ TTNK:
Type: Light Type: Light
RevealsShroud: RevealsShroud:
Range: 5 Range: 5
-AttackMove:
RenderSprites: RenderSprites:
RenderVoxels: RenderVoxels:
WithVoxelBody: WithVoxelBody: