Added attack move
This commit is contained in:
@@ -41,6 +41,9 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
if (!Voices.ContainsKey("Attack"))
|
if (!Voices.ContainsKey("Attack"))
|
||||||
Voices.Add("Attack", Voices["Move"]);
|
Voices.Add("Attack", Voices["Move"]);
|
||||||
|
|
||||||
|
if (!Voices.ContainsKey("AttackMove"))
|
||||||
|
Voices.Add("AttackMove", Voices["Move"]);
|
||||||
|
|
||||||
Pools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new VoicePool(a.Value) ));
|
Pools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new VoicePool(a.Value) ));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,26 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Orders
|
namespace OpenRA.Orders
|
||||||
{
|
{
|
||||||
public class GenericSelectTarget : IOrderGenerator
|
public class GenericSelectTarget : IOrderGenerator
|
||||||
{
|
{
|
||||||
readonly Actor subject;
|
readonly IEnumerable<Actor> subjects;
|
||||||
readonly string order;
|
readonly string order;
|
||||||
readonly string cursor;
|
readonly string cursor;
|
||||||
|
|
||||||
|
public GenericSelectTarget(IEnumerable<Actor> subjects, string order, string cursor)
|
||||||
|
{
|
||||||
|
this.subjects = subjects;
|
||||||
|
this.order = order;
|
||||||
|
this.cursor = cursor;
|
||||||
|
}
|
||||||
|
|
||||||
public GenericSelectTarget(Actor subject, string order, string cursor)
|
public GenericSelectTarget(Actor subject, string order, string cursor)
|
||||||
{
|
{
|
||||||
this.subject = subject;
|
this.subjects = new Actor[] { subject };
|
||||||
this.order = order;
|
this.order = order;
|
||||||
this.cursor = cursor;
|
this.cursor = cursor;
|
||||||
}
|
}
|
||||||
@@ -36,16 +44,35 @@ namespace OpenRA.Orders
|
|||||||
|
|
||||||
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
||||||
{
|
{
|
||||||
if( mi.Button == MouseButton.Left && world.Map.IsInMap( xy ) )
|
if (mi.Button == MouseButton.Left && world.Map.IsInMap(xy))
|
||||||
{
|
{
|
||||||
world.CancelInputMode();
|
world.CancelInputMode();
|
||||||
yield return new Order( order, subject, xy );
|
foreach (var subject in subjects)
|
||||||
|
yield return new Order(order, subject, xy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Tick(World world) { }
|
public virtual void Tick(World world) { }
|
||||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
|
||||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||||
|
{
|
||||||
|
foreach (var a in world.Selection.Actors)
|
||||||
|
if (!a.Destroyed)
|
||||||
|
foreach (var t in a.TraitsImplementing<IPreRenderSelection>())
|
||||||
|
t.RenderBeforeWorld(wr, a);
|
||||||
|
|
||||||
|
Game.Renderer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||||
|
{
|
||||||
|
foreach (var a in world.Selection.Actors)
|
||||||
|
if (!a.Destroyed)
|
||||||
|
foreach (var t in a.TraitsImplementing<IPostRenderSelection>())
|
||||||
|
t.RenderAfterWorld(wr, a);
|
||||||
|
|
||||||
|
Game.Renderer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||||
}
|
}
|
||||||
@@ -67,5 +94,4 @@ namespace OpenRA.Orders
|
|||||||
world.CancelInputMode();
|
world.CancelInputMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,8 +179,9 @@ namespace OpenRA.Traits
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if( !order.Queued ) self.CancelActivity();
|
if( !order.Queued ) self.CancelActivity();
|
||||||
|
|
||||||
self.QueueActivity(new Activities.Move(currentLocation, 8));
|
self.QueueActivity(new Activities.Move(currentLocation, 8));
|
||||||
|
|
||||||
if (self.Owner == self.World.LocalPlayer)
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
self.World.AddFrameEndTask(w =>
|
self.World.AddFrameEndTask(w =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace OpenRA.Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
float2 dragStart, dragEnd;
|
float2 dragStart, dragEnd;
|
||||||
|
|
||||||
public override bool HandleInputInner(MouseInput mi)
|
public override bool HandleInputInner(MouseInput mi)
|
||||||
{
|
{
|
||||||
var xy = Game.viewport.ViewToWorld(mi);
|
var xy = Game.viewport.ViewToWorld(mi);
|
||||||
@@ -139,8 +140,20 @@ namespace OpenRA.Widgets
|
|||||||
GotoNextBase();
|
GotoNextBase();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.KeyChar == 'a')
|
||||||
|
{
|
||||||
|
StartAttackMoveOrder();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartAttackMoveOrder()
|
||||||
|
{
|
||||||
|
if (world.Selection.Actors.Count() > 0)
|
||||||
|
world.OrderGenerator = new GenericSelectTarget(world.Selection.Actors, "AttackMove", "attackmove");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GotoNextBase()
|
public void GotoNextBase()
|
||||||
|
|||||||
19
OpenRA.Mods.RA/Activities/AttackMove.cs
Normal file
19
OpenRA.Mods.RA/Activities/AttackMove.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Traits.Activities;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.RA.Activities
|
||||||
|
{
|
||||||
|
public class AttackMove : Move
|
||||||
|
{
|
||||||
|
public AttackMove(int2 destination) : base(destination) { }
|
||||||
|
public AttackMove(int2 destination, int nearEnough) : base(destination, nearEnough) { }
|
||||||
|
public AttackMove(int2 destination, Actor ignoreBuilding) : base(destination, ignoreBuilding) { }
|
||||||
|
public AttackMove(Actor target, int range) : base(target, range) { }
|
||||||
|
public AttackMove(Target target, int range) : base(target, range) { }
|
||||||
|
public AttackMove(Func<List<int2>> getPath) : base(getPath) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,11 +36,17 @@ namespace OpenRA.Mods.RA
|
|||||||
public readonly bool AlignIdleTurrets = false;
|
public readonly bool AlignIdleTurrets = false;
|
||||||
public readonly bool CanAttackGround = true;
|
public readonly bool CanAttackGround = true;
|
||||||
|
|
||||||
|
public readonly float ScanTimeAverage = 2f;
|
||||||
|
public readonly float ScanTimeSpread = .5f;
|
||||||
|
|
||||||
public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); }
|
public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderVoice
|
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderVoice
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
|
int nextScanTime = 0;
|
||||||
|
|
||||||
public bool IsAttacking { get; internal set; }
|
public bool IsAttacking { get; internal set; }
|
||||||
public Target target;
|
public Target target;
|
||||||
|
|
||||||
@@ -228,6 +234,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (self.HasTrait<Turreted>() && self.Info.Traits.Get<AttackBaseInfo>().AlignIdleTurrets)
|
if (self.HasTrait<Turreted>() && self.Info.Traits.Get<AttackBaseInfo>().AlignIdleTurrets)
|
||||||
self.Trait<Turreted>().desiredFacing = null;
|
self.Trait<Turreted>().desiredFacing = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string VoicePhraseForOrder(Actor self, Order order)
|
public string VoicePhraseForOrder(Actor self, Order order)
|
||||||
@@ -251,6 +258,48 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public Weapon ChooseWeaponForTarget(Target t) { return Weapons.FirstOrDefault(w => w.IsValidAgainst(self.World, t)); }
|
public Weapon ChooseWeaponForTarget(Target t) { return Weapons.FirstOrDefault(w => w.IsValidAgainst(self.World, t)); }
|
||||||
|
|
||||||
|
public void AttackTarget(Actor self, Actor target, bool allowMovement)
|
||||||
|
{
|
||||||
|
var attack = self.Trait<AttackBase>();
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
if (allowMovement)
|
||||||
|
attack.ResolveOrder(self, new Order("Attack", self, target));
|
||||||
|
else
|
||||||
|
attack.target = Target.FromActor(target); // for turreted things on rails.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScanAndAttack(Actor self, bool allowMovement)
|
||||||
|
{
|
||||||
|
if (--nextScanTime <= 0)
|
||||||
|
{
|
||||||
|
var attack = self.Trait<AttackBase>();
|
||||||
|
var range = attack.GetMaximumRange();
|
||||||
|
|
||||||
|
if (!attack.target.IsValid ||
|
||||||
|
(Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
|
||||||
|
AttackTarget(self, ChooseTarget(self, range), allowMovement);
|
||||||
|
|
||||||
|
var info = self.Info.Traits.Get<AttackBaseInfo>();
|
||||||
|
nextScanTime = (int)(25 * (info.ScanTimeAverage +
|
||||||
|
(self.World.SharedRandom.NextDouble() * 2 - 1) * info.ScanTimeSpread));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor ChooseTarget(Actor self, float range)
|
||||||
|
{
|
||||||
|
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||||
|
var attack = self.Trait<AttackBase>();
|
||||||
|
|
||||||
|
return inRange
|
||||||
|
.Where(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Enemy)
|
||||||
|
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
||||||
|
.Where(a => !a.HasTrait<Cloak>() || a.Trait<Cloak>().IsVisible(a, self.Owner))
|
||||||
|
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
class AttackOrderTargeter : IOrderTargeter
|
class AttackOrderTargeter : IOrderTargeter
|
||||||
{
|
{
|
||||||
readonly bool isHeal;
|
readonly bool isHeal;
|
||||||
@@ -292,6 +341,6 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
74
OpenRA.Mods.RA/AttackMoveTrait.cs
Normal file
74
OpenRA.Mods.RA/AttackMoveTrait.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Effects;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.RA
|
||||||
|
{
|
||||||
|
class AttackMoveInfo : TraitInfo<AttackMove>
|
||||||
|
{
|
||||||
|
//public object Create(ActorInitializer init) { return new AttackMove(init.self); }
|
||||||
|
public readonly bool JustMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AttackMove : ITick, IResolveOrder, IOrderVoice
|
||||||
|
{
|
||||||
|
public bool AttackMoving { get; set; }
|
||||||
|
|
||||||
|
public string VoicePhraseForOrder(Actor self, Order order)
|
||||||
|
{
|
||||||
|
if (order.OrderString == "AttackMove")
|
||||||
|
{
|
||||||
|
return "AttackMove";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResolveOrder(Actor self, Order order)
|
||||||
|
{
|
||||||
|
if (order.OrderString == "AttackMove")
|
||||||
|
{
|
||||||
|
self.CancelActivity();
|
||||||
|
//if we are just moving, we don't turn on attackmove and this becomes a regular move order
|
||||||
|
if (!self.Info.Traits.Get<AttackMoveInfo>().JustMove)
|
||||||
|
{
|
||||||
|
AttackMoving = true;
|
||||||
|
}
|
||||||
|
Order newOrder = new Order("Move", order.Subject, order.TargetLocation);
|
||||||
|
self.Trait<Mobile>().ResolveOrder(self, newOrder);
|
||||||
|
|
||||||
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
|
self.World.AddFrameEndTask(w =>
|
||||||
|
{
|
||||||
|
if (order.TargetActor != null)
|
||||||
|
w.Add(new FlashTarget(order.TargetActor));
|
||||||
|
|
||||||
|
var line = self.TraitOrDefault<DrawLineToTarget>();
|
||||||
|
if (line != null)
|
||||||
|
if (order.TargetActor != null) line.SetTarget(self, Target.FromOrder(order), Color.Red);
|
||||||
|
else line.SetTarget(self, Target.FromOrder(order), Color.Red);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.Owner == self.Owner.World.LocalPlayer)
|
||||||
|
self.World.CancelInputMode();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AttackMoving = false; //cancel attack move state for other orders
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick(Actor self)
|
||||||
|
{
|
||||||
|
if (self.Info.Traits.Get<AttackMoveInfo>().JustMove) return;
|
||||||
|
if (!self.HasTrait<AttackBase>())
|
||||||
|
{
|
||||||
|
Game.Debug("AttackMove: {0} has no AttackBase trait".F(self.ToString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!self.IsIdle && (self.HasTrait<AttackMove>() && !(self.Trait<AttackMove>().AttackMoving))) return;
|
||||||
|
|
||||||
|
self.Trait<AttackBase>().ScanAndAttack(self, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,65 +8,22 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA
|
namespace OpenRA.Mods.RA
|
||||||
{
|
{
|
||||||
class AutoTargetInfo : TraitInfo<AutoTarget>
|
class AutoTargetInfo : TraitInfo<AutoTarget>
|
||||||
{
|
{
|
||||||
public readonly float ScanTimeAverage = 2f;
|
|
||||||
public readonly float ScanTimeSpread = .5f;
|
|
||||||
public readonly bool AllowMovement = true;
|
public readonly bool AllowMovement = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutoTarget : ITick, INotifyDamage
|
class AutoTarget : ITick, INotifyDamage
|
||||||
{
|
{
|
||||||
[Sync]
|
|
||||||
int nextScanTime = 0;
|
|
||||||
|
|
||||||
void AttackTarget(Actor self, Actor target)
|
|
||||||
{
|
|
||||||
var attack = self.Trait<AttackBase>();
|
|
||||||
if (target != null)
|
|
||||||
{
|
|
||||||
if (self.Info.Traits.Get<AutoTargetInfo>().AllowMovement)
|
|
||||||
attack.ResolveOrder(self, new Order("Attack", self, target));
|
|
||||||
else
|
|
||||||
attack.target = Target.FromActor(target); // for turreted things on rails.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (!self.IsIdle && self.Info.Traits.Get<AutoTargetInfo>().AllowMovement) return;
|
if (!self.IsIdle && self.Info.Traits.Get<AutoTargetInfo>().AllowMovement) return;
|
||||||
|
|
||||||
if (--nextScanTime <= 0)
|
self.Trait<AttackBase>().ScanAndAttack(self, self.Info.Traits.Get<AutoTargetInfo>().AllowMovement);
|
||||||
{
|
|
||||||
var attack = self.Trait<AttackBase>();
|
|
||||||
var range = attack.GetMaximumRange();
|
|
||||||
|
|
||||||
if (!attack.target.IsValid ||
|
|
||||||
(Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
|
|
||||||
AttackTarget(self, ChooseTarget(self, range));
|
|
||||||
|
|
||||||
var info = self.Info.Traits.Get<AutoTargetInfo>();
|
|
||||||
nextScanTime = (int)(25 * (info.ScanTimeAverage +
|
|
||||||
(self.World.SharedRandom.NextDouble() * 2 - 1) * info.ScanTimeSpread));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Actor ChooseTarget(Actor self, float range)
|
|
||||||
{
|
|
||||||
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
|
||||||
var attack = self.Trait<AttackBase>();
|
|
||||||
|
|
||||||
return inRange
|
|
||||||
.Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy)
|
|
||||||
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
|
||||||
.Where(a => !a.HasTrait<Cloak>() || a.Trait<Cloak>().IsVisible(a,self.Owner))
|
|
||||||
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Damaged(Actor self, AttackInfo e)
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
@@ -83,7 +40,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
if (e.Damage < 0) return; // don't retaliate against healers
|
if (e.Damage < 0) return; // don't retaliate against healers
|
||||||
|
|
||||||
AttackTarget(self, e.Attacker);
|
self.Trait<AttackBase>().AttackTarget(self, e.Attacker, self.Info.Traits.Get<AutoTargetInfo>().AllowMovement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
<Compile Include="Activities\UnloadCargo.cs" />
|
<Compile Include="Activities\UnloadCargo.cs" />
|
||||||
<Compile Include="Activities\Wait.cs" />
|
<Compile Include="Activities\Wait.cs" />
|
||||||
<Compile Include="AttackBase.cs" />
|
<Compile Include="AttackBase.cs" />
|
||||||
|
<Compile Include="AttackMoveTrait.cs" />
|
||||||
<Compile Include="Buildable.cs" />
|
<Compile Include="Buildable.cs" />
|
||||||
<Compile Include="Combat.cs" />
|
<Compile Include="Combat.cs" />
|
||||||
<Compile Include="Crates\CloakCrateAction.cs" />
|
<Compile Include="Crates\CloakCrateAction.cs" />
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
DrawLineToTarget:
|
DrawLineToTarget:
|
||||||
ActorLostNotification:
|
ActorLostNotification:
|
||||||
Notification: unitlost.aud
|
Notification: unitlost.aud
|
||||||
|
AttackMove:
|
||||||
|
|
||||||
^Tank:
|
^Tank:
|
||||||
AppearsOnRadar:
|
AppearsOnRadar:
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
DrawLineToTarget:
|
DrawLineToTarget:
|
||||||
ActorLostNotification:
|
ActorLostNotification:
|
||||||
Notification: unitlost.aud
|
Notification: unitlost.aud
|
||||||
|
AttackMove:
|
||||||
|
|
||||||
^Helicopter:
|
^Helicopter:
|
||||||
AppearsOnRadar:
|
AppearsOnRadar:
|
||||||
@@ -100,6 +102,7 @@
|
|||||||
Queue: Infantry
|
Queue: Infantry
|
||||||
RenderInfantry:
|
RenderInfantry:
|
||||||
AutoTarget:
|
AutoTarget:
|
||||||
|
AttackMove:
|
||||||
Passenger:
|
Passenger:
|
||||||
CargoType: Infantry
|
CargoType: Infantry
|
||||||
HiddenUnderFog:
|
HiddenUnderFog:
|
||||||
@@ -164,6 +167,7 @@
|
|||||||
DrawLineToTarget:
|
DrawLineToTarget:
|
||||||
ActorLostNotification:
|
ActorLostNotification:
|
||||||
Notification: unitlost.aud
|
Notification: unitlost.aud
|
||||||
|
AttackMove:
|
||||||
|
|
||||||
^Building:
|
^Building:
|
||||||
AppearsOnRadar:
|
AppearsOnRadar:
|
||||||
|
|||||||
@@ -153,6 +153,8 @@ E6:
|
|||||||
EngineerRepair:
|
EngineerRepair:
|
||||||
EngineerCapture:
|
EngineerCapture:
|
||||||
-AutoTarget:
|
-AutoTarget:
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
IdleAnimation:
|
IdleAnimation:
|
||||||
Animations: idle1,idle2
|
Animations: idle1,idle2
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ MCV:
|
|||||||
NoTransformSounds: deploy1.aud
|
NoTransformSounds: deploy1.aud
|
||||||
RenderUnit:
|
RenderUnit:
|
||||||
MustBeDestroyed:
|
MustBeDestroyed:
|
||||||
|
-AttackMove:
|
||||||
|
|
||||||
HARV:
|
HARV:
|
||||||
Inherits: ^Tank
|
Inherits: ^Tank
|
||||||
@@ -58,6 +59,7 @@ HARV:
|
|||||||
RevealsShroud:
|
RevealsShroud:
|
||||||
Range: 4
|
Range: 4
|
||||||
RenderUnit:
|
RenderUnit:
|
||||||
|
-AttackMove:
|
||||||
|
|
||||||
APC:
|
APC:
|
||||||
Inherits: ^Tank
|
Inherits: ^Tank
|
||||||
@@ -650,6 +652,8 @@ LST:
|
|||||||
Cargo:
|
Cargo:
|
||||||
Types: Infantry, Vehicle
|
Types: Infantry, Vehicle
|
||||||
Passengers: 5
|
Passengers: 5
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
|
|
||||||
LTNK.Husk:
|
LTNK.Husk:
|
||||||
Inherits: ^Husk
|
Inherits: ^Husk
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
Passenger:
|
Passenger:
|
||||||
CargoType: Vehicle
|
CargoType: Vehicle
|
||||||
IronCurtainable:
|
IronCurtainable:
|
||||||
|
AttackMove:
|
||||||
HiddenUnderFog:
|
HiddenUnderFog:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
GivesExperience:
|
GivesExperience:
|
||||||
@@ -44,7 +45,8 @@
|
|||||||
Chronoshiftable:
|
Chronoshiftable:
|
||||||
Passenger:
|
Passenger:
|
||||||
CargoType: Vehicle
|
CargoType: Vehicle
|
||||||
IronCurtainable:
|
IronCurtainable:
|
||||||
|
AttackMove:
|
||||||
HiddenUnderFog:
|
HiddenUnderFog:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
GivesExperience:
|
GivesExperience:
|
||||||
@@ -73,6 +75,7 @@
|
|||||||
TargetTypes: Ground
|
TargetTypes: Ground
|
||||||
RenderInfantry:
|
RenderInfantry:
|
||||||
AutoTarget:
|
AutoTarget:
|
||||||
|
AttackMove:
|
||||||
Passenger:
|
Passenger:
|
||||||
CargoType: Infantry
|
CargoType: Infantry
|
||||||
HiddenUnderFog:
|
HiddenUnderFog:
|
||||||
@@ -96,6 +99,7 @@
|
|||||||
DetectCloaked:
|
DetectCloaked:
|
||||||
Range: 3
|
Range: 3
|
||||||
HiddenUnderFog:
|
HiddenUnderFog:
|
||||||
|
AttackMove:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
GivesExperience:
|
GivesExperience:
|
||||||
DrawLineToTarget:
|
DrawLineToTarget:
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ E6:
|
|||||||
EngineerCapture:
|
EngineerCapture:
|
||||||
TakeCover:
|
TakeCover:
|
||||||
-AutoTarget:
|
-AutoTarget:
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
IdleAnimation:
|
IdleAnimation:
|
||||||
Animations: idle1,idle2
|
Animations: idle1,idle2
|
||||||
|
|
||||||
@@ -190,6 +192,8 @@ SPY:
|
|||||||
Spy:
|
Spy:
|
||||||
-RenderInfantry:
|
-RenderInfantry:
|
||||||
-AutoTarget:
|
-AutoTarget:
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
IdleAnimation:
|
IdleAnimation:
|
||||||
Animations: idle1,idle2
|
Animations: idle1,idle2
|
||||||
|
|
||||||
@@ -253,6 +257,8 @@ MEDI:
|
|||||||
PrimaryWeapon: Heal
|
PrimaryWeapon: Heal
|
||||||
TakeCover:
|
TakeCover:
|
||||||
-AutoTarget:
|
-AutoTarget:
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
IdleAnimation:
|
IdleAnimation:
|
||||||
Animations: idle1,idle2
|
Animations: idle1,idle2
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ GAP:
|
|||||||
# Prerequisites: atek
|
# Prerequisites: atek
|
||||||
# Owner: allies
|
# Owner: allies
|
||||||
# Cost: 500
|
# Cost: 500
|
||||||
# Hotkey: g
|
|
||||||
Building:
|
Building:
|
||||||
Power: -60
|
Power: -60
|
||||||
Footprint: _ x
|
Footprint: _ x
|
||||||
@@ -268,7 +267,7 @@ AGUN:
|
|||||||
BuildPaletteOrder: 50
|
BuildPaletteOrder: 50
|
||||||
Prerequisites: dome
|
Prerequisites: dome
|
||||||
Owner: allies
|
Owner: allies
|
||||||
Hotkey: a
|
Hotkey: g
|
||||||
Valued:
|
Valued:
|
||||||
Cost: 600
|
Cost: 600
|
||||||
Tooltip:
|
Tooltip:
|
||||||
@@ -679,7 +678,7 @@ AFLD:
|
|||||||
BuildPaletteOrder: 50
|
BuildPaletteOrder: 50
|
||||||
Prerequisites: dome
|
Prerequisites: dome
|
||||||
Owner: soviet
|
Owner: soviet
|
||||||
Hotkey: a
|
Hotkey: g
|
||||||
Valued:
|
Valued:
|
||||||
Cost: 1100
|
Cost: 1100
|
||||||
Tooltip:
|
Tooltip:
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ HARV:
|
|||||||
RevealsShroud:
|
RevealsShroud:
|
||||||
Range: 4
|
Range: 4
|
||||||
RenderUnit:
|
RenderUnit:
|
||||||
|
-AttackMove:
|
||||||
|
|
||||||
MCV:
|
MCV:
|
||||||
Inherits: ^Vehicle
|
Inherits: ^Vehicle
|
||||||
@@ -303,6 +304,7 @@ MCV:
|
|||||||
RenderUnit:
|
RenderUnit:
|
||||||
MustBeDestroyed:
|
MustBeDestroyed:
|
||||||
BaseBuilding:
|
BaseBuilding:
|
||||||
|
-AttackMove:
|
||||||
|
|
||||||
JEEP:
|
JEEP:
|
||||||
Inherits: ^Vehicle
|
Inherits: ^Vehicle
|
||||||
@@ -394,6 +396,8 @@ MNLY.AP:
|
|||||||
MineImmune:
|
MineImmune:
|
||||||
LimitedAmmo:
|
LimitedAmmo:
|
||||||
Ammo: 5
|
Ammo: 5
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
|
|
||||||
MNLY.AT:
|
MNLY.AT:
|
||||||
Inherits: ^Tank
|
Inherits: ^Tank
|
||||||
@@ -423,6 +427,8 @@ MNLY.AT:
|
|||||||
MineImmune:
|
MineImmune:
|
||||||
LimitedAmmo:
|
LimitedAmmo:
|
||||||
Ammo: 5
|
Ammo: 5
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
|
|
||||||
TRUK:
|
TRUK:
|
||||||
Inherits: ^Vehicle
|
Inherits: ^Vehicle
|
||||||
@@ -625,6 +631,8 @@ LST:
|
|||||||
Passengers: 5
|
Passengers: 5
|
||||||
IronCurtainable:
|
IronCurtainable:
|
||||||
RepairableNear:
|
RepairableNear:
|
||||||
|
AttackMove:
|
||||||
|
JustMove: true
|
||||||
|
|
||||||
PT:
|
PT:
|
||||||
Inherits: ^Ship
|
Inherits: ^Ship
|
||||||
|
|||||||
Reference in New Issue
Block a user