make attacks queuable
This commit is contained in:
@@ -133,6 +133,13 @@ namespace OpenRA
|
|||||||
|
|
||||||
public bool IsInWorld { get; internal set; }
|
public bool IsInWorld { get; internal set; }
|
||||||
|
|
||||||
|
public void QueueActivity( bool queued, IActivity nextActivity )
|
||||||
|
{
|
||||||
|
if( !queued )
|
||||||
|
CancelActivity();
|
||||||
|
QueueActivity( nextActivity );
|
||||||
|
}
|
||||||
|
|
||||||
public void QueueActivity( IActivity nextActivity )
|
public void QueueActivity( IActivity nextActivity )
|
||||||
{
|
{
|
||||||
if( currentActivity == null )
|
if( currentActivity == null )
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
{
|
{
|
||||||
public AttackHeli(Actor self, AttackHeliInfo info) : base(self, info) { }
|
public AttackHeli(Actor self, AttackHeliInfo info) : base(self, info) { }
|
||||||
|
|
||||||
protected override void QueueAttack(Actor self, Target newTarget)
|
protected override void QueueAttack(Actor self, bool queued, Target newTarget)
|
||||||
{
|
{
|
||||||
target = newTarget;
|
target = newTarget;
|
||||||
self.QueueActivity(new HeliAttack(newTarget));
|
self.QueueActivity(queued, new HeliAttack(newTarget));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
{
|
{
|
||||||
public AttackPlane(Actor self, AttackPlaneInfo info) : base(self, info) { }
|
public AttackPlane(Actor self, AttackPlaneInfo info) : base(self, info) { }
|
||||||
|
|
||||||
protected override void QueueAttack(Actor self, Target newTarget)
|
protected override void QueueAttack(Actor self, bool queued, Target newTarget)
|
||||||
{
|
{
|
||||||
target = newTarget;
|
target = newTarget;
|
||||||
self.QueueActivity(new FlyAttack(newTarget));
|
self.QueueActivity(queued, new FlyAttack(newTarget));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CanAttack(Actor self)
|
protected override bool CanAttack(Actor self)
|
||||||
|
|||||||
@@ -149,8 +149,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
if (order.OrderString == "Attack")
|
if (order.OrderString == "Attack")
|
||||||
{
|
{
|
||||||
self.CancelActivity();
|
QueueAttack(self, order.Queued, Target.FromOrder(order));
|
||||||
QueueAttack(self, Target.FromOrder(order));
|
|
||||||
|
|
||||||
if (self.Owner == self.World.LocalPlayer)
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
self.World.AddFrameEndTask(w =>
|
self.World.AddFrameEndTask(w =>
|
||||||
@@ -181,7 +180,7 @@ namespace OpenRA.Mods.RA
|
|||||||
return (order.OrderString == "Attack") ? "Attack" : null;
|
return (order.OrderString == "Attack") ? "Attack" : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void QueueAttack(Actor self, Target newTarget);
|
protected abstract void QueueAttack(Actor self, bool queued, Target newTarget);
|
||||||
|
|
||||||
public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(self.World, t)); }
|
public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(self.World, t)); }
|
||||||
public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); }
|
public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); }
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ namespace OpenRA.Mods.RA
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void QueueAttack(Actor self, Target newTarget)
|
protected override void QueueAttack(Actor self, bool queued, Target newTarget)
|
||||||
{
|
{
|
||||||
var weapon = ChooseWeaponForTarget(newTarget);
|
var weapon = ChooseWeaponForTarget(newTarget);
|
||||||
|
|
||||||
if (weapon != null)
|
if (weapon != null)
|
||||||
self.QueueActivity(
|
self.QueueActivity( queued,
|
||||||
new Activities.Attack(
|
new Activities.Attack(
|
||||||
newTarget,
|
newTarget,
|
||||||
Math.Max(0, (int)weapon.Info.Range)));
|
Math.Max(0, (int)weapon.Info.Range)));
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ namespace OpenRA.Mods.RA
|
|||||||
self.QueueActivity(new Leap(self, target));
|
self.QueueActivity(new Leap(self, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void QueueAttack(Actor self, Target newTarget)
|
protected override void QueueAttack(Actor self, bool queued, Target newTarget)
|
||||||
{
|
{
|
||||||
var weapon = ChooseWeaponForTarget(newTarget);
|
var weapon = ChooseWeaponForTarget(newTarget);
|
||||||
|
|
||||||
if (weapon != null)
|
if (weapon != null)
|
||||||
self.QueueActivity(
|
self.QueueActivity( queued,
|
||||||
new Activities.Attack(
|
new Activities.Attack(
|
||||||
newTarget,
|
newTarget,
|
||||||
Math.Max(0, (int)weapon.Info.Range)));
|
Math.Max(0, (int)weapon.Info.Range)));
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
using OpenRA.Mods.RA.Buildings;
|
using OpenRA.Mods.RA.Buildings;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Mods.RA.Activities;
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA
|
namespace OpenRA.Mods.RA
|
||||||
{
|
{
|
||||||
@@ -37,9 +38,22 @@ namespace OpenRA.Mods.RA
|
|||||||
DoAttack(self, target);
|
DoAttack(self, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void QueueAttack(Actor self, Target newTarget)
|
protected override void QueueAttack(Actor self, bool queued, Target newTarget)
|
||||||
{
|
{
|
||||||
target = newTarget;
|
self.QueueActivity( queued, new SetTarget( newTarget ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetTarget : CancelableActivity
|
||||||
|
{
|
||||||
|
readonly Target target;
|
||||||
|
public SetTarget( Target target ) { this.target = target; }
|
||||||
|
|
||||||
|
public override IActivity Tick( Actor self )
|
||||||
|
{
|
||||||
|
if( !IsCanceled )
|
||||||
|
self.Trait<AttackBase>().target = target;
|
||||||
|
return NextActivity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,24 +46,39 @@ namespace OpenRA.Mods.RA
|
|||||||
DoAttack( self, target );
|
DoAttack( self, target );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void QueueAttack( Actor self, Target newTarget )
|
protected override void QueueAttack( Actor self, bool queued, Target newTarget )
|
||||||
{
|
{
|
||||||
if (self.TraitsImplementing<IDisable>().Any(d => d.Disabled))
|
if (self.TraitsImplementing<IDisable>().Any(d => d.Disabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
self.QueueActivity( queued, new AttackActivity( newTarget ) );
|
||||||
var weapon = ChooseWeaponForTarget(newTarget);
|
|
||||||
if (weapon == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target = newTarget;
|
|
||||||
|
|
||||||
if (self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails)
|
|
||||||
self.QueueActivity( new Follow( newTarget,
|
|
||||||
Math.Max( 0, (int)weapon.Info.Range - RangeTolerance ) ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buildComplete = false;
|
bool buildComplete = false;
|
||||||
public void BuildingComplete(Actor self) { buildComplete = true; }
|
public void BuildingComplete(Actor self) { buildComplete = true; }
|
||||||
|
|
||||||
|
class AttackActivity : CancelableActivity
|
||||||
|
{
|
||||||
|
readonly Target newTarget;
|
||||||
|
public AttackActivity( Target newTarget ) { this.newTarget = newTarget; }
|
||||||
|
|
||||||
|
public override IActivity Tick( Actor self )
|
||||||
|
{
|
||||||
|
if( IsCanceled ) return NextActivity;
|
||||||
|
|
||||||
|
var attack = self.Trait<AttackTurreted>();
|
||||||
|
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
||||||
|
var weapon = attack.ChooseWeaponForTarget(newTarget);
|
||||||
|
if (weapon != null)
|
||||||
|
{
|
||||||
|
attack.target = newTarget;
|
||||||
|
|
||||||
|
if (self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails)
|
||||||
|
self.QueueActivity( new Follow( newTarget,
|
||||||
|
Math.Max( 0, (int)weapon.Info.Range - RangeTolerance ) ) );
|
||||||
|
}
|
||||||
|
return NextActivity;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -321,7 +321,4 @@
|
|||||||
copy "$(TargetPath)" "$(SolutionDir)mods/ra/"
|
copy "$(TargetPath)" "$(SolutionDir)mods/ra/"
|
||||||
cd "$(SolutionDir)"</PostBuildEvent>
|
cd "$(SolutionDir)"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="ServerTraits\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user