Merge Plane and Helicopter into Aircraft
This commit is contained in:
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
if (!self.IsInWorld || self.IsDead)
|
if (!self.IsInWorld || self.IsDead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo<PlaneInfo>().CruiseAltitude;
|
var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo<AircraftInfo>().CruiseAltitude;
|
||||||
var actor = w.CreateActor(actorType, new TypeDictionary
|
var actor = w.CreateActor(actorType, new TypeDictionary
|
||||||
{
|
{
|
||||||
new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)),
|
new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)),
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class Fly : Activity
|
public class Fly : Activity
|
||||||
{
|
{
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
readonly Target target;
|
readonly Target target;
|
||||||
readonly WDist maxRange;
|
readonly WDist maxRange;
|
||||||
readonly WDist minRange;
|
readonly WDist minRange;
|
||||||
|
|
||||||
public Fly(Actor self, Target t)
|
public Fly(Actor self, Target t)
|
||||||
{
|
{
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
target = t;
|
target = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
this.minRange = minRange;
|
this.minRange = minRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FlyToward(Actor self, Plane plane, int desiredFacing, WDist desiredAltitude)
|
public static void FlyToward(Actor self, Aircraft plane, int desiredFacing, WDist desiredAltitude)
|
||||||
{
|
{
|
||||||
desiredAltitude = new WDist(plane.CenterPosition.Z) + desiredAltitude - self.World.Map.DistanceAboveTerrain(plane.CenterPosition);
|
desiredAltitude = new WDist(plane.CenterPosition.Z) + desiredAltitude - self.World.Map.DistanceAboveTerrain(plane.CenterPosition);
|
||||||
|
|
||||||
|
|||||||
@@ -10,18 +10,17 @@
|
|||||||
|
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Activities
|
namespace OpenRA.Mods.Common.Activities
|
||||||
{
|
{
|
||||||
public class FlyCircle : Activity
|
public class FlyCircle : Activity
|
||||||
{
|
{
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
readonly WDist cruiseAltitude;
|
readonly WDist cruiseAltitude;
|
||||||
|
|
||||||
public FlyCircle(Actor self)
|
public FlyCircle(Actor self)
|
||||||
{
|
{
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
cruiseAltitude = plane.Info.CruiseAltitude;
|
cruiseAltitude = plane.Info.CruiseAltitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public class FlyFollow : Activity
|
public class FlyFollow : Activity
|
||||||
{
|
{
|
||||||
Target target;
|
Target target;
|
||||||
Plane plane;
|
Aircraft plane;
|
||||||
WDist minRange;
|
WDist minRange;
|
||||||
WDist maxRange;
|
WDist maxRange;
|
||||||
|
|
||||||
public FlyFollow(Actor self, Target target, WDist minRange, WDist maxRange)
|
public FlyFollow(Actor self, Target target, WDist minRange, WDist maxRange)
|
||||||
{
|
{
|
||||||
this.target = target;
|
this.target = target;
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
this.minRange = minRange;
|
this.minRange = minRange;
|
||||||
this.maxRange = maxRange;
|
this.maxRange = maxRange;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,16 @@
|
|||||||
|
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Activities
|
namespace OpenRA.Mods.Common.Activities
|
||||||
{
|
{
|
||||||
public class FlyOffMap : Activity
|
public class FlyOffMap : Activity
|
||||||
{
|
{
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
|
|
||||||
public FlyOffMap(Actor self)
|
public FlyOffMap(Actor self)
|
||||||
{
|
{
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
|
|||||||
@@ -10,20 +10,19 @@
|
|||||||
|
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Activities
|
namespace OpenRA.Mods.Common.Activities
|
||||||
{
|
{
|
||||||
public class FlyTimed : Activity
|
public class FlyTimed : Activity
|
||||||
{
|
{
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
readonly WDist cruiseAltitude;
|
readonly WDist cruiseAltitude;
|
||||||
int remainingTicks;
|
int remainingTicks;
|
||||||
|
|
||||||
public FlyTimed(int ticks, Actor self)
|
public FlyTimed(int ticks, Actor self)
|
||||||
{
|
{
|
||||||
remainingTicks = ticks;
|
remainingTicks = ticks;
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
cruiseAltitude = plane.Info.CruiseAltitude;
|
cruiseAltitude = plane.Info.CruiseAltitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
@@ -19,7 +18,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliAttack : Activity
|
public class HeliAttack : Activity
|
||||||
{
|
{
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft helicopter;
|
||||||
readonly AttackHeli attackHeli;
|
readonly AttackHeli attackHeli;
|
||||||
readonly AmmoPool[] ammoPools;
|
readonly AmmoPool[] ammoPools;
|
||||||
readonly bool attackOnlyVisibleTargets;
|
readonly bool attackOnlyVisibleTargets;
|
||||||
@@ -44,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public HeliAttack(Actor self, Target target, bool attackOnlyVisibleTargets = true)
|
public HeliAttack(Actor self, Target target, bool attackOnlyVisibleTargets = true)
|
||||||
{
|
{
|
||||||
Target = target;
|
Target = target;
|
||||||
helicopter = self.Trait<Helicopter>();
|
helicopter = self.Trait<Aircraft>();
|
||||||
attackHeli = self.Trait<AttackHeli>();
|
attackHeli = self.Trait<AttackHeli>();
|
||||||
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
|
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
|
||||||
this.attackOnlyVisibleTargets = attackOnlyVisibleTargets;
|
this.attackOnlyVisibleTargets = attackOnlyVisibleTargets;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliFly : Activity
|
public class HeliFly : Activity
|
||||||
{
|
{
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft helicopter;
|
||||||
readonly Target target;
|
readonly Target target;
|
||||||
readonly WDist maxRange;
|
readonly WDist maxRange;
|
||||||
readonly WDist minRange;
|
readonly WDist minRange;
|
||||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
public HeliFly(Actor self, Target t)
|
public HeliFly(Actor self, Target t)
|
||||||
{
|
{
|
||||||
helicopter = self.Trait<Helicopter>();
|
helicopter = self.Trait<Aircraft>();
|
||||||
target = t;
|
target = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
this.minRange = minRange;
|
this.minRange = minRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AdjustAltitude(Actor self, Helicopter helicopter, WDist targetAltitude)
|
public static bool AdjustAltitude(Actor self, Aircraft helicopter, WDist targetAltitude)
|
||||||
{
|
{
|
||||||
targetAltitude = new WDist(helicopter.CenterPosition.Z) + targetAltitude - self.World.Map.DistanceAboveTerrain(helicopter.CenterPosition);
|
targetAltitude = new WDist(helicopter.CenterPosition.Z) + targetAltitude - self.World.Map.DistanceAboveTerrain(helicopter.CenterPosition);
|
||||||
|
|
||||||
@@ -105,9 +105,9 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
public class HeliFlyAndLandWhenIdle : HeliFly
|
public class HeliFlyAndLandWhenIdle : HeliFly
|
||||||
{
|
{
|
||||||
private readonly HelicopterInfo info;
|
private readonly AircraftInfo info;
|
||||||
|
|
||||||
public HeliFlyAndLandWhenIdle(Actor self, Target t, HelicopterInfo info)
|
public HeliFlyAndLandWhenIdle(Actor self, Target t, AircraftInfo info)
|
||||||
: base(self, t)
|
: base(self, t)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
@@ -18,11 +16,11 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliFlyCircle : Activity
|
public class HeliFlyCircle : Activity
|
||||||
{
|
{
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft helicopter;
|
||||||
|
|
||||||
public HeliFlyCircle(Actor self)
|
public HeliFlyCircle(Actor self)
|
||||||
{
|
{
|
||||||
helicopter = self.Trait<Helicopter>();
|
helicopter = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliLand : Activity
|
public class HeliLand : Activity
|
||||||
{
|
{
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft helicopter;
|
||||||
bool requireSpace;
|
bool requireSpace;
|
||||||
bool playedSound;
|
bool playedSound;
|
||||||
|
|
||||||
public HeliLand(Actor self, bool requireSpace)
|
public HeliLand(Actor self, bool requireSpace)
|
||||||
{
|
{
|
||||||
this.requireSpace = requireSpace;
|
this.requireSpace = requireSpace;
|
||||||
helicopter = self.Trait<Helicopter>();
|
helicopter = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliReturn : Activity
|
public class HeliReturn : Activity
|
||||||
{
|
{
|
||||||
readonly Helicopter heli;
|
readonly Aircraft heli;
|
||||||
|
|
||||||
public HeliReturn(Actor self)
|
public HeliReturn(Actor self)
|
||||||
{
|
{
|
||||||
heli = self.Trait<Helicopter>();
|
heli = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actor ChooseHelipad(Actor self)
|
public Actor ChooseHelipad(Actor self)
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public class Land : Activity
|
public class Land : Activity
|
||||||
{
|
{
|
||||||
readonly Target target;
|
readonly Target target;
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
|
|
||||||
public Land(Actor self, Target t)
|
public Land(Actor self, Target t)
|
||||||
{
|
{
|
||||||
target = t;
|
target = t;
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class ReturnToBase : Activity
|
public class ReturnToBase : Activity
|
||||||
{
|
{
|
||||||
readonly Plane plane;
|
readonly Aircraft plane;
|
||||||
readonly PlaneInfo planeInfo;
|
readonly AircraftInfo planeInfo;
|
||||||
bool isCalculated;
|
bool isCalculated;
|
||||||
Actor dest;
|
Actor dest;
|
||||||
WPos w1, w2, w3;
|
WPos w1, w2, w3;
|
||||||
@@ -27,13 +27,13 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public ReturnToBase(Actor self, Actor dest = null)
|
public ReturnToBase(Actor self, Actor dest = null)
|
||||||
{
|
{
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Aircraft>();
|
||||||
planeInfo = self.Info.TraitInfo<PlaneInfo>();
|
planeInfo = self.Info.TraitInfo<AircraftInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
|
public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
|
||||||
{
|
{
|
||||||
var rearmBuildings = self.Info.TraitInfo<PlaneInfo>().RearmBuildings;
|
var rearmBuildings = self.Info.TraitInfo<AircraftInfo>().RearmBuildings;
|
||||||
return self.World.ActorsWithTrait<Reservable>()
|
return self.World.ActorsWithTrait<Reservable>()
|
||||||
.Where(a => a.Actor.Owner == self.Owner)
|
.Where(a => a.Actor.Owner == self.Owner)
|
||||||
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name)
|
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name)
|
||||||
@@ -94,7 +94,6 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
w1 = posCenter + tangentOffset;
|
w1 = posCenter + tangentOffset;
|
||||||
w2 = approachCenter + tangentOffset;
|
w2 = approachCenter + tangentOffset;
|
||||||
w3 = approachStart;
|
w3 = approachStart;
|
||||||
plane.RTBPathHash = w1 + (WVec)w2 + (WVec)w3;
|
|
||||||
|
|
||||||
isCalculated = true;
|
isCalculated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,7 @@
|
|||||||
<Compile Include="Orders\UnitOrderTargeter.cs" />
|
<Compile Include="Orders\UnitOrderTargeter.cs" />
|
||||||
<Compile Include="Pathfinder\CellInfo.cs" />
|
<Compile Include="Pathfinder\CellInfo.cs" />
|
||||||
<Compile Include="PlayerExtensions.cs" />
|
<Compile Include="PlayerExtensions.cs" />
|
||||||
|
<Compile Include="Scripting\Properties\AircraftProperties.cs" />
|
||||||
<Compile Include="Scripting\ScriptUpgradesCache.cs" />
|
<Compile Include="Scripting\ScriptUpgradesCache.cs" />
|
||||||
<Compile Include="Scripting\Properties\CaptureProperties.cs" />
|
<Compile Include="Scripting\Properties\CaptureProperties.cs" />
|
||||||
<Compile Include="ServerTraits\ColorValidator.cs" />
|
<Compile Include="ServerTraits\ColorValidator.cs" />
|
||||||
@@ -235,13 +236,11 @@
|
|||||||
<Compile Include="Scripting\Properties\DiplomacyProperties.cs" />
|
<Compile Include="Scripting\Properties\DiplomacyProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
|
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\HealthProperties.cs" />
|
<Compile Include="Scripting\Properties\HealthProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\HelicopterProperties.cs" />
|
|
||||||
<Compile Include="Scripting\Properties\GeneralProperties.cs" />
|
<Compile Include="Scripting\Properties\GeneralProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\GuardProperties.cs" />
|
<Compile Include="Scripting\Properties\GuardProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\MissionObjectiveProperties.cs" />
|
<Compile Include="Scripting\Properties\MissionObjectiveProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\MobileProperties.cs" />
|
<Compile Include="Scripting\Properties\MobileProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\DemolitionProperties.cs" />
|
<Compile Include="Scripting\Properties\DemolitionProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\PlaneProperties.cs" />
|
|
||||||
<Compile Include="Scripting\Properties\PlayerProperties.cs" />
|
<Compile Include="Scripting\Properties\PlayerProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\PowerProperties.cs" />
|
<Compile Include="Scripting\Properties\PowerProperties.cs" />
|
||||||
<Compile Include="Scripting\Properties\ProductionProperties.cs" />
|
<Compile Include="Scripting\Properties\ProductionProperties.cs" />
|
||||||
@@ -258,8 +257,6 @@
|
|||||||
<Compile Include="Traits\Air\AttackPlane.cs" />
|
<Compile Include="Traits\Air\AttackPlane.cs" />
|
||||||
<Compile Include="Traits\Air\FlyAwayOnIdle.cs" />
|
<Compile Include="Traits\Air\FlyAwayOnIdle.cs" />
|
||||||
<Compile Include="Traits\Air\FallsToEarth.cs" />
|
<Compile Include="Traits\Air\FallsToEarth.cs" />
|
||||||
<Compile Include="Traits\Air\Helicopter.cs" />
|
|
||||||
<Compile Include="Traits\Air\Plane.cs" />
|
|
||||||
<Compile Include="Traits\Air\ReturnOnIdle.cs" />
|
<Compile Include="Traits\Air\ReturnOnIdle.cs" />
|
||||||
<Compile Include="Traits\AppearsOnRadar.cs" />
|
<Compile Include="Traits\AppearsOnRadar.cs" />
|
||||||
<Compile Include="Traits\Armament.cs" />
|
<Compile Include="Traits\Armament.cs" />
|
||||||
|
|||||||
@@ -137,11 +137,19 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var heli = transport.Info.TraitInfoOrDefault<HelicopterInfo>();
|
var aircraftInfo = transport.TraitOrDefault<Aircraft>();
|
||||||
if (heli != null)
|
if (aircraftInfo != null)
|
||||||
{
|
{
|
||||||
transport.QueueActivity(new Turn(transport, heli.InitialFacing));
|
if (!aircraftInfo.IsPlane)
|
||||||
transport.QueueActivity(new HeliLand(transport, true));
|
{
|
||||||
|
transport.QueueActivity(new Turn(transport, aircraftInfo.Info.InitialFacing));
|
||||||
|
transport.QueueActivity(new HeliLand(transport, true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, entryPath.Last())));
|
||||||
|
}
|
||||||
|
|
||||||
transport.QueueActivity(new Wait(15));
|
transport.QueueActivity(new Wait(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +159,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
transport.QueueActivity(new WaitFor(() => cargo.IsEmpty(transport)));
|
transport.QueueActivity(new WaitFor(() => cargo.IsEmpty(transport)));
|
||||||
}
|
}
|
||||||
|
|
||||||
transport.QueueActivity(new Wait(heli != null ? 50 : 25));
|
transport.QueueActivity(new Wait(aircraftInfo != null ? 50 : 25));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitFunc != null)
|
if (exitFunc != null)
|
||||||
|
|||||||
@@ -16,23 +16,34 @@ using OpenRA.Traits;
|
|||||||
namespace OpenRA.Mods.Common.Scripting
|
namespace OpenRA.Mods.Common.Scripting
|
||||||
{
|
{
|
||||||
[ScriptPropertyGroup("Movement")]
|
[ScriptPropertyGroup("Movement")]
|
||||||
public class PlaneProperties : ScriptActorProperties, Requires<PlaneInfo>
|
public class AircraftProperties : ScriptActorProperties, Requires<AircraftInfo>
|
||||||
{
|
{
|
||||||
public PlaneProperties(ScriptContext context, Actor self)
|
readonly bool isPlane;
|
||||||
: base(context, self) { }
|
|
||||||
|
public AircraftProperties(ScriptContext context, Actor self)
|
||||||
|
: base(context, self)
|
||||||
|
{
|
||||||
|
isPlane = self.Trait<Aircraft>().IsPlane;
|
||||||
|
}
|
||||||
|
|
||||||
[ScriptActorPropertyActivity]
|
[ScriptActorPropertyActivity]
|
||||||
[Desc("Fly within the cell grid.")]
|
[Desc("Fly within the cell grid.")]
|
||||||
public void Move(CPos cell)
|
public void Move(CPos cell)
|
||||||
{
|
{
|
||||||
Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell)));
|
if (isPlane)
|
||||||
|
Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell)));
|
||||||
|
else
|
||||||
|
Self.QueueActivity(new HeliFly(Self, Target.FromCell(Self.World, cell)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ScriptActorPropertyActivity]
|
[ScriptActorPropertyActivity]
|
||||||
[Desc("Return to the base, which is either the airfield given, or an auto-selected one otherwise.")]
|
[Desc("Return to the base, which is either the airfield given, or an auto-selected one otherwise.")]
|
||||||
public void ReturnToBase(Actor airfield = null)
|
public void ReturnToBase(Actor airfield = null)
|
||||||
{
|
{
|
||||||
Self.QueueActivity(new ReturnToBase(Self, airfield));
|
if (isPlane)
|
||||||
|
Self.QueueActivity(new ReturnToBase(Self, airfield));
|
||||||
|
else
|
||||||
|
Self.QueueActivity(new HeliReturn(Self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2015 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.Common.Activities;
|
|
||||||
using OpenRA.Mods.Common.Traits;
|
|
||||||
using OpenRA.Scripting;
|
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Scripting
|
|
||||||
{
|
|
||||||
[ScriptPropertyGroup("Movement")]
|
|
||||||
public class HelicopterProperties : ScriptActorProperties, Requires<HelicopterInfo>
|
|
||||||
{
|
|
||||||
public HelicopterProperties(ScriptContext context, Actor self)
|
|
||||||
: base(context, self) { }
|
|
||||||
|
|
||||||
[ScriptActorPropertyActivity]
|
|
||||||
[Desc("Fly within the cell grid.")]
|
|
||||||
public void Move(CPos cell)
|
|
||||||
{
|
|
||||||
Self.QueueActivity(new HeliFly(Self, Target.FromCell(Self.World, cell)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Activities;
|
using OpenRA.Mods.Common.Activities;
|
||||||
@@ -19,7 +20,8 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public class AircraftInfo : IPositionableInfo, IFacingInfo, IOccupySpaceInfo, ICruiseAltitudeInfo, UsesInit<LocationInit>, UsesInit<FacingInit>
|
public class AircraftInfo : IPositionableInfo, IFacingInfo, IOccupySpaceInfo, IMoveInfo, ICruiseAltitudeInfo,
|
||||||
|
UsesInit<LocationInit>, UsesInit<FacingInit>
|
||||||
{
|
{
|
||||||
public readonly WDist CruiseAltitude = new WDist(1280);
|
public readonly WDist CruiseAltitude = new WDist(1280);
|
||||||
public readonly WDist IdealSeparation = new WDist(1706);
|
public readonly WDist IdealSeparation = new WDist(1706);
|
||||||
@@ -53,23 +55,51 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("The upgrades to grant to self while airborne.")]
|
[Desc("The upgrades to grant to self while airborne.")]
|
||||||
public readonly string[] AirborneUpgrades = { };
|
public readonly string[] AirborneUpgrades = { };
|
||||||
|
|
||||||
|
[Desc("Can the actor hover in place mid-air? If not, then the actor will have to remain in motion (circle around).")]
|
||||||
|
public readonly bool CanHover = false;
|
||||||
|
|
||||||
|
[Desc("Will this actor try to land after it has no more commands?")]
|
||||||
|
public readonly bool LandWhenIdle = true;
|
||||||
|
|
||||||
|
[Desc("Does this actor need to turn before landing?")]
|
||||||
|
public readonly bool TurnToLand = false;
|
||||||
|
|
||||||
|
public readonly WDist LandAltitude = WDist.Zero;
|
||||||
|
|
||||||
|
[Desc("How fast this actor ascends or descends when using horizontal take off/landing.")]
|
||||||
|
public readonly WAngle MaximumPitch = WAngle.FromDegrees(10);
|
||||||
|
|
||||||
|
[Desc("How fast this actor ascends or descends when using vertical take off/landing.")]
|
||||||
|
public readonly WDist AltitudeVelocity = new WDist(43);
|
||||||
|
|
||||||
|
[Desc("Sound to play when the actor is taking off.")]
|
||||||
|
public readonly string TakeoffSound = null;
|
||||||
|
|
||||||
|
[Desc("Sound to play when the actor is landing.")]
|
||||||
|
public readonly string LandingSound = null;
|
||||||
|
|
||||||
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
|
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
|
||||||
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyCreated, INotifyActorDisposing
|
public class Aircraft : ITick, ISync, IFacing, IPositionable, IMove, IIssueOrder, IResolveOrder, IOrderVoice,
|
||||||
|
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing
|
||||||
{
|
{
|
||||||
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
||||||
|
|
||||||
readonly AircraftInfo info;
|
public readonly bool IsPlane;
|
||||||
|
public readonly AircraftInfo Info;
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
|
|
||||||
UpgradeManager um;
|
UpgradeManager um;
|
||||||
|
|
||||||
[Sync] public int Facing { get; set; }
|
[Sync] public int Facing { get; set; }
|
||||||
[Sync] public WPos CenterPosition { get; private set; }
|
[Sync] public WPos CenterPosition { get; private set; }
|
||||||
public CPos TopLeft { get { return self.World.Map.CellContaining(CenterPosition); } }
|
public CPos TopLeft { get { return self.World.Map.CellContaining(CenterPosition); } }
|
||||||
public IDisposable Reservation;
|
public IDisposable Reservation;
|
||||||
public int ROT { get { return info.ROT; } }
|
public int ROT { get { return Info.ROT; } }
|
||||||
|
|
||||||
|
bool airborne;
|
||||||
bool IsAirborne
|
bool IsAirborne
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -85,21 +115,19 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (um != null)
|
if (um != null)
|
||||||
{
|
{
|
||||||
if (airborne)
|
if (airborne)
|
||||||
foreach (var u in info.AirborneUpgrades)
|
foreach (var u in Info.AirborneUpgrades)
|
||||||
um.GrantUpgrade(self, u, this);
|
um.GrantUpgrade(self, u, this);
|
||||||
else
|
else
|
||||||
foreach (var u in info.AirborneUpgrades)
|
foreach (var u in Info.AirborneUpgrades)
|
||||||
um.RevokeUpgrade(self, u, this);
|
um.RevokeUpgrade(self, u, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool airborne = false;
|
|
||||||
|
|
||||||
public Aircraft(ActorInitializer init, AircraftInfo info)
|
public Aircraft(ActorInitializer init, AircraftInfo info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
Info = info;
|
||||||
this.self = init.Self;
|
self = init.Self;
|
||||||
|
|
||||||
if (init.Contains<LocationInit>())
|
if (init.Contains<LocationInit>())
|
||||||
SetPosition(self, init.Get<LocationInit, CPos>());
|
SetPosition(self, init.Get<LocationInit, CPos>());
|
||||||
@@ -108,10 +136,23 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
SetPosition(self, init.Get<CenterPositionInit, WPos>());
|
SetPosition(self, init.Get<CenterPositionInit, WPos>());
|
||||||
|
|
||||||
Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
|
Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
|
||||||
|
|
||||||
|
// TODO: HACK: This is a hack until we can properly distinquish between airplane and helicopter!
|
||||||
|
// Or until the activities get unified enough so that it doesn't matter.
|
||||||
|
IsPlane = !info.CanHover;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Created(Actor self) { um = self.TraitOrDefault<UpgradeManager>(); }
|
public void Created(Actor self) { um = self.TraitOrDefault<UpgradeManager>(); }
|
||||||
|
|
||||||
|
public void AddedToWorld(Actor self)
|
||||||
|
{
|
||||||
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
|
self.World.ScreenMap.Add(self);
|
||||||
|
if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= Info.MinAirborneAltitude)
|
||||||
|
IsAirborne = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool firstTick = true;
|
bool firstTick = true;
|
||||||
public virtual void Tick(Actor self)
|
public virtual void Tick(Actor self)
|
||||||
{
|
{
|
||||||
@@ -143,24 +184,39 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (repulsionFacing == -1)
|
if (repulsionFacing == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var speed = info.RepulsionSpeed != -1 ? info.RepulsionSpeed : MovementSpeed;
|
var speed = Info.RepulsionSpeed != -1 ? Info.RepulsionSpeed : MovementSpeed;
|
||||||
SetPosition(self, CenterPosition + FlyStep(speed, repulsionFacing));
|
SetPosition(self, CenterPosition + FlyStep(speed, repulsionFacing));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual WVec GetRepulsionForce()
|
public virtual WVec GetRepulsionForce()
|
||||||
{
|
{
|
||||||
if (!info.Repulsable)
|
if (!Info.Repulsable)
|
||||||
return WVec.Zero;
|
return WVec.Zero;
|
||||||
|
|
||||||
// Repulsion only applies when we're flying!
|
// Repulsion only applies when we're flying!
|
||||||
var altitude = CenterPosition.Z;
|
var altitude = CenterPosition.Z;
|
||||||
if (altitude != info.CruiseAltitude.Length)
|
if (altitude != Info.CruiseAltitude.Length)
|
||||||
return WVec.Zero;
|
return WVec.Zero;
|
||||||
|
|
||||||
return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation)
|
var repulsionForce = self.World.FindActorsInCircle(self.CenterPosition, Info.IdealSeparation)
|
||||||
.Where(a => !a.IsDead && a.Info.HasTraitInfo<AircraftInfo>() && a.Info.TraitInfo<AircraftInfo>().CruiseAltitude == info.CruiseAltitude)
|
.Where(a => !a.IsDead && a.Info.HasTraitInfo<AircraftInfo>()
|
||||||
|
&& a.Info.TraitInfo<AircraftInfo>().CruiseAltitude == Info.CruiseAltitude)
|
||||||
.Select(GetRepulsionForce)
|
.Select(GetRepulsionForce)
|
||||||
.Aggregate(WVec.Zero, (a, b) => a + b);
|
.Aggregate(WVec.Zero, (a, b) => a + b);
|
||||||
|
|
||||||
|
if (Info.CanHover)
|
||||||
|
return repulsionForce;
|
||||||
|
|
||||||
|
// Non-hovering actors mush always keep moving forward, so they need extra calculations.
|
||||||
|
var currentDir = FlyStep(Facing);
|
||||||
|
var length = currentDir.HorizontalLength * repulsionForce.HorizontalLength;
|
||||||
|
if (length == 0)
|
||||||
|
return WVec.Zero;
|
||||||
|
|
||||||
|
var dot = WVec.Dot(currentDir, repulsionForce) / length;
|
||||||
|
|
||||||
|
// avoid stalling the plane
|
||||||
|
return dot >= 0 ? repulsionForce : WVec.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WVec GetRepulsionForce(Actor other)
|
public WVec GetRepulsionForce(Actor other)
|
||||||
@@ -170,7 +226,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
var d = self.CenterPosition - other.CenterPosition;
|
var d = self.CenterPosition - other.CenterPosition;
|
||||||
var distSq = d.HorizontalLengthSquared;
|
var distSq = d.HorizontalLengthSquared;
|
||||||
if (distSq > info.IdealSeparation.LengthSquared)
|
if (distSq > Info.IdealSeparation.LengthSquared)
|
||||||
return WVec.Zero;
|
return WVec.Zero;
|
||||||
|
|
||||||
if (distSq < 1)
|
if (distSq < 1)
|
||||||
@@ -219,78 +275,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disposing(Actor self)
|
|
||||||
{
|
|
||||||
UnReserve();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPosition(Actor self, WPos pos)
|
|
||||||
{
|
|
||||||
CenterPosition = pos;
|
|
||||||
|
|
||||||
if (self.IsInWorld)
|
|
||||||
{
|
|
||||||
self.World.ScreenMap.Update(self);
|
|
||||||
self.World.ActorMap.UpdatePosition(self, this);
|
|
||||||
IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Changes position, but not altitude
|
|
||||||
public void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any)
|
|
||||||
{
|
|
||||||
SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); }
|
|
||||||
|
|
||||||
public void AddedToWorld(Actor self)
|
|
||||||
{
|
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
|
||||||
self.World.ActorMap.AddPosition(self, this);
|
|
||||||
self.World.ScreenMap.Add(self);
|
|
||||||
if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude)
|
|
||||||
IsAirborne = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemovedFromWorld(Actor self)
|
|
||||||
{
|
|
||||||
UnReserve();
|
|
||||||
self.World.ActorMap.RemoveInfluence(self, this);
|
|
||||||
self.World.ActorMap.RemovePosition(self, this);
|
|
||||||
self.World.ScreenMap.Remove(self);
|
|
||||||
IsAirborne = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AircraftCanEnter(Actor a)
|
public bool AircraftCanEnter(Actor a)
|
||||||
{
|
{
|
||||||
if (self.AppearsHostileTo(a))
|
if (self.AppearsHostileTo(a))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return info.RearmBuildings.Contains(a.Info.Name)
|
return Info.RearmBuildings.Contains(a.Info.Name)
|
||||||
|| info.RepairBuildings.Contains(a.Info.Name);
|
|| Info.RepairBuildings.Contains(a.Info.Name);
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } // TODO: Handle landing
|
|
||||||
public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; }
|
|
||||||
public SubCell GetAvailableSubCell(CPos a, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, bool checkTransientActors = true)
|
|
||||||
{
|
|
||||||
// Does not use any subcell
|
|
||||||
return SubCell.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return true; }
|
|
||||||
|
|
||||||
public bool CanEnterTargetNow(Actor self, Target target)
|
|
||||||
{
|
|
||||||
if (target.Positions.Any(p => self.World.ActorMap.GetUnitsAt(self.World.Map.CellContaining(p)).Any(a => a != self && a != target.Actor)))
|
|
||||||
return false;
|
|
||||||
var res = target.Actor.TraitOrDefault<Reservable>();
|
|
||||||
if (res == null)
|
|
||||||
return true;
|
|
||||||
UnReserve();
|
|
||||||
Reservation = res.Reserve(target.Actor, self, this);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MovementSpeed
|
public int MovementSpeed
|
||||||
@@ -299,7 +290,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var modifiers = self.TraitsImplementing<ISpeedModifier>()
|
var modifiers = self.TraitsImplementing<ISpeedModifier>()
|
||||||
.Select(m => m.GetSpeedModifier());
|
.Select(m => m.GetSpeedModifier());
|
||||||
return Util.ApplyPercentageModifiers(info.Speed, modifiers);
|
return Util.ApplyPercentageModifiers(Info.Speed, modifiers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,18 +316,151 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var type = self.World.Map.GetTerrainInfo(cell).Type;
|
var type = self.World.Map.GetTerrainInfo(cell).Type;
|
||||||
return info.LandableTerrainTypes.Contains(type);
|
return Info.LandableTerrainTypes.Contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<Activity> GetResupplyActivities(Actor a)
|
public virtual IEnumerable<Activity> GetResupplyActivities(Actor a)
|
||||||
{
|
{
|
||||||
var name = a.Info.Name;
|
var name = a.Info.Name;
|
||||||
if (info.RearmBuildings.Contains(name))
|
if (Info.RearmBuildings.Contains(name))
|
||||||
yield return new Rearm(self);
|
yield return new Rearm(self);
|
||||||
if (info.RepairBuildings.Contains(name))
|
if (Info.RepairBuildings.Contains(name))
|
||||||
yield return new Repair(a);
|
yield return new Repair(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Implement IPositionable
|
||||||
|
|
||||||
|
public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } // TODO: Handle landing
|
||||||
|
public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return true; }
|
||||||
|
public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; }
|
||||||
|
public SubCell GetAvailableSubCell(CPos a, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, bool checkTransientActors = true)
|
||||||
|
{
|
||||||
|
// Does not use any subcell
|
||||||
|
return SubCell.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); }
|
||||||
|
|
||||||
|
// Changes position, but not altitude
|
||||||
|
public void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any)
|
||||||
|
{
|
||||||
|
SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPosition(Actor self, WPos pos)
|
||||||
|
{
|
||||||
|
CenterPosition = pos;
|
||||||
|
|
||||||
|
if (!self.IsInWorld)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self.World.ScreenMap.Update(self);
|
||||||
|
self.World.ActorMap.UpdatePosition(self, this);
|
||||||
|
IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= Info.MinAirborneAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implement IMove
|
||||||
|
|
||||||
|
public Activity MoveTo(CPos cell, int nearEnough)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new FlyAndContinueWithCirclesWhenIdle(self, Target.FromCell(self.World, cell));
|
||||||
|
|
||||||
|
return new HeliFly(self, Target.FromCell(self.World, cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveTo(CPos cell, Actor ignoredActor)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new FlyAndContinueWithCirclesWhenIdle(self, Target.FromCell(self.World, cell));
|
||||||
|
|
||||||
|
return new HeliFly(self, Target.FromCell(self.World, cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveWithinRange(Target target, WDist range)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new FlyAndContinueWithCirclesWhenIdle(self, target, WDist.Zero, range);
|
||||||
|
|
||||||
|
return new HeliFly(self, target, WDist.Zero, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new FlyAndContinueWithCirclesWhenIdle(self, target, minRange, maxRange);
|
||||||
|
|
||||||
|
return new HeliFly(self, target, minRange, maxRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new FlyFollow(self, target, minRange, maxRange);
|
||||||
|
|
||||||
|
return new Follow(self, target, minRange, maxRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new Fly(self, Target.FromCell(self.World, cell));
|
||||||
|
|
||||||
|
return new HeliFly(self, Target.FromCell(self.World, cell, subCell));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveToTarget(Actor self, Target target)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5));
|
||||||
|
|
||||||
|
return Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity MoveIntoTarget(Actor self, Target target)
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
return new Land(self, target);
|
||||||
|
|
||||||
|
return new HeliLand(self, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity VisualMove(Actor self, WPos fromPos, WPos toPos)
|
||||||
|
{
|
||||||
|
// TODO: Ignore repulsion when moving
|
||||||
|
if (IsPlane)
|
||||||
|
return Util.SequenceActivities(
|
||||||
|
new CallFunc(() => SetVisualPosition(self, fromPos)),
|
||||||
|
new Fly(self, Target.FromPos(toPos)));
|
||||||
|
|
||||||
|
return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)),
|
||||||
|
new HeliFly(self, Target.FromPos(toPos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CPos NearestMoveableCell(CPos cell) { return cell; }
|
||||||
|
|
||||||
|
public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } }
|
||||||
|
|
||||||
|
public bool CanEnterTargetNow(Actor self, Target target)
|
||||||
|
{
|
||||||
|
if (target.Positions.Any(p => self.World.ActorMap.GetUnitsAt(self.World.Map.CellContaining(p)).Any(a => a != self && a != target.Actor)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var res = target.Actor.TraitOrDefault<Reservable>();
|
||||||
|
if (res == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
UnReserve();
|
||||||
|
Reservation = res.Reserve(target.Actor, self, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implement order interfaces
|
||||||
|
|
||||||
public IEnumerable<IOrderTargeter> Orders
|
public IEnumerable<IOrderTargeter> Orders
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -344,7 +468,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
yield return new EnterAlliedActorTargeter<BuildingInfo>("Enter", 5,
|
yield return new EnterAlliedActorTargeter<BuildingInfo>("Enter", 5,
|
||||||
target => AircraftCanEnter(target), target => !Reservable.IsReserved(target));
|
target => AircraftCanEnter(target), target => !Reservable.IsReserved(target));
|
||||||
|
|
||||||
yield return new AircraftMoveOrderTargeter(info);
|
yield return new AircraftMoveOrderTargeter(Info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,9 +491,119 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
case "Enter":
|
case "Enter":
|
||||||
case "ReturnToBase":
|
case "ReturnToBase":
|
||||||
case "Stop":
|
case "Stop":
|
||||||
return info.Voice;
|
return Info.Voice;
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResolveOrder(Actor self, Order order)
|
||||||
|
{
|
||||||
|
if (order.OrderString == "Move")
|
||||||
|
{
|
||||||
|
var cell = self.World.Map.Clamp(order.TargetLocation);
|
||||||
|
|
||||||
|
if (!Info.MoveIntoShroud && !self.Owner.Shroud.IsExplored(cell))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!order.Queued)
|
||||||
|
UnReserve();
|
||||||
|
|
||||||
|
var target = Target.FromCell(self.World, cell);
|
||||||
|
|
||||||
|
self.SetTargetLine(target, Color.Green);
|
||||||
|
|
||||||
|
if (IsPlane)
|
||||||
|
self.QueueActivity(order.Queued, new FlyAndContinueWithCirclesWhenIdle(self, target));
|
||||||
|
else
|
||||||
|
self.QueueActivity(order.Queued, new HeliFlyAndLandWhenIdle(self, target, Info));
|
||||||
|
}
|
||||||
|
else if (order.OrderString == "Enter")
|
||||||
|
{
|
||||||
|
if (!order.Queued)
|
||||||
|
UnReserve();
|
||||||
|
|
||||||
|
if (Reservable.IsReserved(order.TargetActor))
|
||||||
|
{
|
||||||
|
if (IsPlane)
|
||||||
|
self.QueueActivity(new ReturnToBase(self));
|
||||||
|
else
|
||||||
|
self.QueueActivity(new HeliReturn(self));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
|
||||||
|
|
||||||
|
if (IsPlane)
|
||||||
|
{
|
||||||
|
self.QueueActivity(order.Queued, Util.SequenceActivities(
|
||||||
|
new ReturnToBase(self, order.TargetActor),
|
||||||
|
new ResupplyAircraft(self)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var res = order.TargetActor.TraitOrDefault<Reservable>();
|
||||||
|
if (res != null)
|
||||||
|
Reservation = res.Reserve(order.TargetActor, self, this);
|
||||||
|
|
||||||
|
Action enter = () =>
|
||||||
|
{
|
||||||
|
var exit = order.TargetActor.Info.TraitInfos<ExitInfo>().FirstOrDefault();
|
||||||
|
var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero;
|
||||||
|
|
||||||
|
self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset)));
|
||||||
|
self.QueueActivity(new Turn(self, Info.InitialFacing));
|
||||||
|
self.QueueActivity(new HeliLand(self, false));
|
||||||
|
self.QueueActivity(new ResupplyAircraft(self));
|
||||||
|
self.QueueActivity(new TakeOff(self));
|
||||||
|
};
|
||||||
|
|
||||||
|
self.QueueActivity(order.Queued, new CallFunc(enter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (order.OrderString == "Stop")
|
||||||
|
{
|
||||||
|
UnReserve();
|
||||||
|
self.CancelActivity();
|
||||||
|
|
||||||
|
// TODO: Implement INotifyBecomingIdle instead
|
||||||
|
if (!IsPlane && Info.LandWhenIdle)
|
||||||
|
{
|
||||||
|
if (Info.TurnToLand)
|
||||||
|
self.QueueActivity(new Turn(self, Info.InitialFacing));
|
||||||
|
|
||||||
|
self.QueueActivity(new HeliLand(self, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (order.OrderString == "ReturnToBase")
|
||||||
|
{
|
||||||
|
UnReserve();
|
||||||
|
self.CancelActivity();
|
||||||
|
if (IsPlane)
|
||||||
|
self.QueueActivity(new ReturnToBase(self));
|
||||||
|
else
|
||||||
|
self.QueueActivity(new HeliReturn(self));
|
||||||
|
|
||||||
|
self.QueueActivity(new ResupplyAircraft(self));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UnReserve();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void RemovedFromWorld(Actor self)
|
||||||
|
{
|
||||||
|
UnReserve();
|
||||||
|
self.World.ActorMap.RemoveInfluence(self, this);
|
||||||
|
self.World.ActorMap.RemovePosition(self, this);
|
||||||
|
self.World.ScreenMap.Remove(self);
|
||||||
|
IsAirborne = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disposing(Actor self)
|
||||||
|
{
|
||||||
|
UnReserve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2015 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 System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
|
||||||
using OpenRA.Activities;
|
|
||||||
using OpenRA.Mods.Common.Activities;
|
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
|
||||||
{
|
|
||||||
public class HelicopterInfo : AircraftInfo, IMoveInfo
|
|
||||||
{
|
|
||||||
[Desc("Allow the helicopter land after it has no more commands.")]
|
|
||||||
public readonly bool LandWhenIdle = true;
|
|
||||||
|
|
||||||
[Desc("Allow the helicopter turn before landing.")]
|
|
||||||
public readonly bool TurnToLand = false;
|
|
||||||
public readonly WDist LandAltitude = WDist.Zero;
|
|
||||||
|
|
||||||
[Desc("How fast the helicopter ascends or descends.")]
|
|
||||||
public readonly WDist AltitudeVelocity = new WDist(43);
|
|
||||||
|
|
||||||
public readonly string TakeoffSound = null;
|
|
||||||
public readonly string LandingSound = null;
|
|
||||||
|
|
||||||
public override object Create(ActorInitializer init) { return new Helicopter(init, this); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Helicopter : Aircraft, ITick, IResolveOrder, IMove
|
|
||||||
{
|
|
||||||
public readonly HelicopterInfo Info;
|
|
||||||
Actor self;
|
|
||||||
public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } }
|
|
||||||
|
|
||||||
public Helicopter(ActorInitializer init, HelicopterInfo info)
|
|
||||||
: base(init, info)
|
|
||||||
{
|
|
||||||
self = init.Self;
|
|
||||||
Info = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResolveOrder(Actor self, Order order)
|
|
||||||
{
|
|
||||||
if (order.OrderString == "Move")
|
|
||||||
{
|
|
||||||
var cell = self.World.Map.Clamp(order.TargetLocation);
|
|
||||||
var explored = self.Owner.Shroud.IsExplored(cell);
|
|
||||||
|
|
||||||
if (!explored && !Info.MoveIntoShroud)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var target = Target.FromCell(self.World, cell);
|
|
||||||
self.SetTargetLine(target, Color.Green);
|
|
||||||
|
|
||||||
if (!order.Queued)
|
|
||||||
UnReserve();
|
|
||||||
|
|
||||||
self.QueueActivity(order.Queued, new HeliFlyAndLandWhenIdle(self, target, Info));
|
|
||||||
}
|
|
||||||
else if (order.OrderString == "Enter")
|
|
||||||
{
|
|
||||||
Action enter = () =>
|
|
||||||
{
|
|
||||||
if (Reservable.IsReserved(order.TargetActor))
|
|
||||||
self.QueueActivity(order.Queued, new HeliReturn(self));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var res = order.TargetActor.TraitOrDefault<Reservable>();
|
|
||||||
if (res != null)
|
|
||||||
Reservation = res.Reserve(order.TargetActor, self, this);
|
|
||||||
|
|
||||||
var exit = order.TargetActor.Info.TraitInfos<ExitInfo>().FirstOrDefault();
|
|
||||||
var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero;
|
|
||||||
|
|
||||||
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
|
|
||||||
|
|
||||||
self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset)));
|
|
||||||
self.QueueActivity(new Turn(self, Info.InitialFacing));
|
|
||||||
self.QueueActivity(new HeliLand(self, false));
|
|
||||||
self.QueueActivity(new ResupplyAircraft(self));
|
|
||||||
self.QueueActivity(new TakeOff(self));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.QueueActivity(order.Queued, new CallFunc(enter));
|
|
||||||
|
|
||||||
if (!order.Queued)
|
|
||||||
UnReserve();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UnReserve();
|
|
||||||
|
|
||||||
if (order.OrderString == "ReturnToBase")
|
|
||||||
{
|
|
||||||
self.CancelActivity();
|
|
||||||
self.QueueActivity(new HeliReturn(self));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (order.OrderString == "Stop")
|
|
||||||
{
|
|
||||||
self.CancelActivity();
|
|
||||||
|
|
||||||
if (Info.LandWhenIdle)
|
|
||||||
{
|
|
||||||
if (Info.TurnToLand)
|
|
||||||
self.QueueActivity(new Turn(self, Info.InitialFacing));
|
|
||||||
|
|
||||||
self.QueueActivity(new HeliLand(self, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity MoveTo(CPos cell, int nearEnough) { return new HeliFly(self, Target.FromCell(self.World, cell)); }
|
|
||||||
public Activity MoveTo(CPos cell, Actor ignoredActor) { return new HeliFly(self, Target.FromCell(self.World, cell)); }
|
|
||||||
public Activity MoveWithinRange(Target target, WDist range) { return new HeliFly(self, target, WDist.Zero, range); }
|
|
||||||
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange) { return new HeliFly(self, target, minRange, maxRange); }
|
|
||||||
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange) { return new Follow(self, target, minRange, maxRange); }
|
|
||||||
public CPos NearestMoveableCell(CPos cell) { return cell; }
|
|
||||||
|
|
||||||
public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any)
|
|
||||||
{
|
|
||||||
return new HeliFly(self, Target.FromCell(self.World, cell, subCell));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity MoveIntoTarget(Actor self, Target target) { return new HeliLand(self, false); }
|
|
||||||
public Activity MoveToTarget(Actor self, Target target)
|
|
||||||
{
|
|
||||||
return Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity VisualMove(Actor self, WPos fromPos, WPos toPos)
|
|
||||||
{
|
|
||||||
// TODO: Ignore repulsion when moving
|
|
||||||
return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new HeliFly(self, Target.FromPos(toPos)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Activity> GetResupplyActivities(Actor a)
|
|
||||||
{
|
|
||||||
foreach (var b in base.GetResupplyActivities(a))
|
|
||||||
yield return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2015 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 System;
|
|
||||||
using System.Drawing;
|
|
||||||
using OpenRA.Activities;
|
|
||||||
using OpenRA.Mods.Common.Activities;
|
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
|
||||||
{
|
|
||||||
public class PlaneInfo : AircraftInfo, IMoveInfo
|
|
||||||
{
|
|
||||||
public readonly WAngle MaximumPitch = WAngle.FromDegrees(10);
|
|
||||||
|
|
||||||
public override object Create(ActorInitializer init) { return new Plane(init, this); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Plane : Aircraft, IResolveOrder, IMove, ITick, ISync
|
|
||||||
{
|
|
||||||
public readonly PlaneInfo Info;
|
|
||||||
[Sync] public WPos RTBPathHash;
|
|
||||||
Actor self;
|
|
||||||
public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } }
|
|
||||||
|
|
||||||
public Plane(ActorInitializer init, PlaneInfo info)
|
|
||||||
: base(init, info)
|
|
||||||
{
|
|
||||||
self = init.Self;
|
|
||||||
Info = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override WVec GetRepulsionForce()
|
|
||||||
{
|
|
||||||
var repulsionForce = base.GetRepulsionForce();
|
|
||||||
if (repulsionForce == WVec.Zero)
|
|
||||||
return WVec.Zero;
|
|
||||||
|
|
||||||
var currentDir = FlyStep(Facing);
|
|
||||||
var length = currentDir.HorizontalLength * repulsionForce.HorizontalLength;
|
|
||||||
if (length == 0)
|
|
||||||
return WVec.Zero;
|
|
||||||
|
|
||||||
var dot = WVec.Dot(currentDir, repulsionForce) / length;
|
|
||||||
|
|
||||||
// avoid stalling the plane
|
|
||||||
return dot >= 0 ? repulsionForce : WVec.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResolveOrder(Actor self, Order order)
|
|
||||||
{
|
|
||||||
if (order.OrderString == "Move")
|
|
||||||
{
|
|
||||||
var cell = self.World.Map.Clamp(order.TargetLocation);
|
|
||||||
var explored = self.Owner.Shroud.IsExplored(cell);
|
|
||||||
|
|
||||||
if (!explored && !Info.MoveIntoShroud)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!order.Queued)
|
|
||||||
UnReserve();
|
|
||||||
|
|
||||||
var target = Target.FromCell(self.World, cell);
|
|
||||||
self.SetTargetLine(target, Color.Green);
|
|
||||||
self.QueueActivity(order.Queued, new FlyAndContinueWithCirclesWhenIdle(self, target));
|
|
||||||
}
|
|
||||||
else if (order.OrderString == "Enter")
|
|
||||||
{
|
|
||||||
if (Reservable.IsReserved(order.TargetActor))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!order.Queued)
|
|
||||||
UnReserve();
|
|
||||||
|
|
||||||
self.SetTargetLine(Target.FromOrder(self.World, order), Color.Green);
|
|
||||||
self.QueueActivity(order.Queued, Util.SequenceActivities(new ReturnToBase(self, order.TargetActor), new ResupplyAircraft(self)));
|
|
||||||
}
|
|
||||||
else if (order.OrderString == "Stop")
|
|
||||||
{
|
|
||||||
UnReserve();
|
|
||||||
self.CancelActivity();
|
|
||||||
}
|
|
||||||
else if (order.OrderString == "ReturnToBase")
|
|
||||||
{
|
|
||||||
var airfield = ReturnToBase.ChooseAirfield(self, true);
|
|
||||||
if (airfield == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UnReserve();
|
|
||||||
self.CancelActivity();
|
|
||||||
self.SetTargetLine(Target.FromActor(airfield), Color.Green);
|
|
||||||
self.QueueActivity(new ReturnToBase(self, airfield));
|
|
||||||
self.QueueActivity(new ResupplyAircraft(self));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Game.Debug("Unreserve due to unhandled order: {0}".F(order.OrderString));
|
|
||||||
UnReserve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); }
|
|
||||||
public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); }
|
|
||||||
public Activity MoveWithinRange(Target target, WDist range) { return Util.SequenceActivities(new Fly(self, target, WDist.Zero, range), new FlyCircle(self)); }
|
|
||||||
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange)
|
|
||||||
{
|
|
||||||
return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle(self));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange) { return new FlyFollow(self, target, minRange, maxRange); }
|
|
||||||
public CPos NearestMoveableCell(CPos cell) { return cell; }
|
|
||||||
|
|
||||||
public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any) { return new Fly(self, Target.FromCell(self.World, cell)); }
|
|
||||||
public Activity VisualMove(Actor self, WPos fromPos, WPos toPos)
|
|
||||||
{
|
|
||||||
return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new Fly(self, Target.FromPos(toPos)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Activity MoveToTarget(Actor self, Target target) { return new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5)); }
|
|
||||||
public Activity MoveIntoTarget(Actor self, Target target) { return new Land(self, target); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
int totalWeight = 0;
|
int totalWeight = 0;
|
||||||
int reservedWeight = 0;
|
int reservedWeight = 0;
|
||||||
Helicopter helicopter;
|
Aircraft aircraft;
|
||||||
|
|
||||||
CPos currentCell;
|
CPos currentCell;
|
||||||
public IEnumerable<CPos> CurrentAdjacentCells { get; private set; }
|
public IEnumerable<CPos> CurrentAdjacentCells { get; private set; }
|
||||||
@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void Created(Actor self)
|
public void Created(Actor self)
|
||||||
{
|
{
|
||||||
helicopter = self.TraitOrDefault<Helicopter>();
|
aircraft = self.TraitOrDefault<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetWeight(Actor a) { return a.Info.TraitInfo<PassengerInfo>().Weight; }
|
static int GetWeight(Actor a) { return a.Info.TraitInfo<PassengerInfo>().Weight; }
|
||||||
@@ -144,7 +144,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
Unloading = true;
|
Unloading = true;
|
||||||
self.CancelActivity();
|
self.CancelActivity();
|
||||||
if (helicopter != null)
|
if (aircraft != null)
|
||||||
self.QueueActivity(new HeliLand(self, true));
|
self.QueueActivity(new HeliLand(self, true));
|
||||||
self.QueueActivity(new UnloadCargo(self, true));
|
self.QueueActivity(new UnloadCargo(self, true));
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !IsEmpty(self) && (helicopter == null || helicopter.CanLand(self.Location))
|
return !IsEmpty(self) && (aircraft == null || aircraft.CanLand(self.Location))
|
||||||
&& CurrentAdjacentCells != null && CurrentAdjacentCells.Any(c => Passengers.Any(p => p.Trait<IPositionable>().CanEnterCell(c)));
|
&& CurrentAdjacentCells != null && CurrentAdjacentCells.Any(c => Passengers.Any(p => p.Trait<IPositionable>().CanEnterCell(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (randomize)
|
if (randomize)
|
||||||
attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
||||||
|
|
||||||
var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo<PlaneInfo>().CruiseAltitude.Length;
|
var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
|
||||||
var attackRotation = WRot.FromFacing(attackFacing);
|
var attackRotation = WRot.FromFacing(attackFacing);
|
||||||
var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
|
var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
|
||||||
target = target + new WVec(0, 0, altitude);
|
target = target + new WVec(0, 0, altitude);
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (self.Info.HasTraitInfo<IFacingInfo>())
|
if (self.Info.HasTraitInfo<IFacingInfo>())
|
||||||
self.QueueActivity(new Turn(self, info.Facing));
|
self.QueueActivity(new Turn(self, info.Facing));
|
||||||
|
|
||||||
if (self.Info.HasTraitInfo<HelicopterInfo>())
|
if (self.Info.HasTraitInfo<AircraftInfo>())
|
||||||
self.QueueActivity(new HeliLand(self, true));
|
self.QueueActivity(new HeliLand(self, true));
|
||||||
|
|
||||||
foreach (var nt in self.TraitsImplementing<INotifyTransform>())
|
foreach (var nt in self.TraitsImplementing<INotifyTransform>())
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
var dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
||||||
var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(dropFacing));
|
var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(dropFacing));
|
||||||
|
|
||||||
var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo<PlaneInfo>().CruiseAltitude.Length;
|
var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
|
||||||
var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude);
|
var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude);
|
||||||
var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024;
|
var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024;
|
||||||
var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024;
|
var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
readonly IMove movement;
|
readonly IMove movement;
|
||||||
readonly Carryable carryable;
|
readonly Carryable carryable;
|
||||||
readonly Carryall carryall;
|
readonly Carryall carryall;
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft aircraft;
|
||||||
readonly IPositionable positionable;
|
readonly IPositionable positionable;
|
||||||
readonly IFacing cargoFacing;
|
readonly IFacing cargoFacing;
|
||||||
readonly IFacing selfFacing;
|
readonly IFacing selfFacing;
|
||||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
cargo = carryall.Carrying;
|
cargo = carryall.Carrying;
|
||||||
movement = self.Trait<IMove>();
|
movement = self.Trait<IMove>();
|
||||||
carryable = cargo.Trait<Carryable>();
|
carryable = cargo.Trait<Carryable>();
|
||||||
helicopter = self.Trait<Helicopter>();
|
aircraft = self.Trait<Aircraft>();
|
||||||
positionable = cargo.Trait<IPositionable>();
|
positionable = cargo.Trait<IPositionable>();
|
||||||
cargoFacing = cargo.Trait<IFacing>();
|
cargoFacing = cargo.Trait<IFacing>();
|
||||||
selfFacing = self.Trait<IFacing>();
|
selfFacing = self.Trait<IFacing>();
|
||||||
@@ -95,7 +95,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude))
|
if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.LandAltitude))
|
||||||
return this;
|
return this;
|
||||||
state = State.Release;
|
state = State.Release;
|
||||||
return Util.SequenceActivities(new Wait(15), this);
|
return Util.SequenceActivities(new Wait(15), this);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
readonly IMove movement;
|
readonly IMove movement;
|
||||||
readonly Carryable carryable;
|
readonly Carryable carryable;
|
||||||
readonly Carryall carryall;
|
readonly Carryall carryall;
|
||||||
readonly Helicopter helicopter;
|
readonly Aircraft aircraft;
|
||||||
readonly IFacing cargoFacing;
|
readonly IFacing cargoFacing;
|
||||||
readonly IFacing selfFacing;
|
readonly IFacing selfFacing;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
cargoFacing = cargo.Trait<IFacing>();
|
cargoFacing = cargo.Trait<IFacing>();
|
||||||
movement = self.Trait<IMove>();
|
movement = self.Trait<IMove>();
|
||||||
carryall = self.Trait<Carryall>();
|
carryall = self.Trait<Carryall>();
|
||||||
helicopter = self.Trait<Helicopter>();
|
aircraft = self.Trait<Aircraft>();
|
||||||
selfFacing = self.Trait<IFacing>();
|
selfFacing = self.Trait<IFacing>();
|
||||||
state = State.Intercept;
|
state = State.Intercept;
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.D2k.Activities
|
|||||||
state = State.TakeOff;
|
state = State.TakeOff;
|
||||||
return this;
|
return this;
|
||||||
case State.TakeOff:
|
case State.TakeOff:
|
||||||
if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.CruiseAltitude))
|
if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.CruiseAltitude))
|
||||||
return this;
|
return this;
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
|
|
||||||
IsBusy = false;
|
IsBusy = false;
|
||||||
IsCarrying = false;
|
IsCarrying = false;
|
||||||
var helicopter = self.Info.TraitInfoOrDefault<HelicopterInfo>();
|
|
||||||
|
var helicopter = self.Info.TraitInfoOrDefault<AircraftInfo>();
|
||||||
carryHeight = helicopter != null ? helicopter.LandAltitude : WDist.Zero;
|
carryHeight = helicopter != null ? helicopter.LandAltitude : WDist.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace OpenRA.Mods.RA.Traits
|
|||||||
if (randomize)
|
if (randomize)
|
||||||
dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
||||||
|
|
||||||
var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo<PlaneInfo>().CruiseAltitude.Length;
|
var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
|
||||||
var dropRotation = WRot.FromFacing(dropFacing);
|
var dropRotation = WRot.FromFacing(dropFacing);
|
||||||
var delta = new WVec(0, -1024, 0).Rotate(dropRotation);
|
var delta = new WVec(0, -1024, 0).Rotate(dropRotation);
|
||||||
target = target + new WVec(0, 0, altitude);
|
target = target + new WVec(0, 0, altitude);
|
||||||
|
|||||||
Reference in New Issue
Block a user