Make aircraft occupy cells when landed.
This commit is contained in:
@@ -72,7 +72,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
});
|
});
|
||||||
|
|
||||||
actor.QueueActivity(new Fly(actor, Target.FromPos(self.CenterPosition + new WVec(landDistance, 0, 0))));
|
actor.QueueActivity(new Fly(actor, Target.FromPos(self.CenterPosition + new WVec(landDistance, 0, 0))));
|
||||||
actor.QueueActivity(new Land(actor, Target.FromActor(self)));
|
actor.QueueActivity(new Land(actor, Target.FromActor(self), false));
|
||||||
actor.QueueActivity(new CallFunc(() =>
|
actor.QueueActivity(new CallFunc(() =>
|
||||||
{
|
{
|
||||||
if (!self.IsInWorld || self.IsDead)
|
if (!self.IsInWorld || self.IsDead)
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
soundPlayed = true;
|
soundPlayed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.IsAtGroundLevel())
|
||||||
|
aircraft.RemoveInfluence();
|
||||||
|
|
||||||
// Inside the target annulus, so we're done
|
// Inside the target annulus, so we're done
|
||||||
var insideMaxRange = maxRange.Length > 0 && checkTarget.IsInRange(aircraft.CenterPosition, maxRange);
|
var insideMaxRange = maxRange.Length > 0 && checkTarget.IsInRange(aircraft.CenterPosition, maxRange);
|
||||||
var insideMinRange = minRange.Length > 0 && checkTarget.IsInRange(aircraft.CenterPosition, minRange);
|
var insideMinRange = minRange.Length > 0 && checkTarget.IsInRange(aircraft.CenterPosition, minRange);
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
soundPlayed = true;
|
soundPlayed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.IsAtGroundLevel())
|
||||||
|
aircraft.RemoveInfluence();
|
||||||
|
|
||||||
if (AdjustAltitude(self, aircraft, aircraft.Info.CruiseAltitude))
|
if (AdjustAltitude(self, aircraft, aircraft.Info.CruiseAltitude))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
|
|||||||
@@ -19,26 +19,42 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
readonly Aircraft aircraft;
|
readonly Aircraft aircraft;
|
||||||
readonly WDist landAltitude;
|
readonly WDist landAltitude;
|
||||||
readonly bool requireSpace;
|
readonly bool requireSpace;
|
||||||
|
readonly Actor ignoreActor;
|
||||||
|
|
||||||
bool soundPlayed;
|
bool soundPlayed;
|
||||||
|
bool landingInitiated;
|
||||||
|
|
||||||
public HeliLand(Actor self, bool requireSpace)
|
public HeliLand(Actor self, bool requireSpace, Actor ignoreActor = null)
|
||||||
: this(self, requireSpace, self.Info.TraitInfo<AircraftInfo>().LandAltitude) { }
|
: this(self, requireSpace, self.Info.TraitInfo<AircraftInfo>().LandAltitude, ignoreActor) { }
|
||||||
|
|
||||||
public HeliLand(Actor self, bool requireSpace, WDist landAltitude)
|
public HeliLand(Actor self, bool requireSpace, WDist landAltitude, Actor ignoreActor = null)
|
||||||
{
|
{
|
||||||
this.requireSpace = requireSpace;
|
this.requireSpace = requireSpace;
|
||||||
this.landAltitude = landAltitude;
|
this.landAltitude = landAltitude;
|
||||||
|
this.ignoreActor = ignoreActor;
|
||||||
aircraft = self.Trait<Aircraft>();
|
aircraft = self.Trait<Aircraft>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceling)
|
if (IsCanceling)
|
||||||
|
{
|
||||||
|
aircraft.RemoveInfluence();
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
}
|
||||||
|
|
||||||
if (requireSpace && !aircraft.CanLand(self.Location))
|
if (requireSpace && !landingInitiated)
|
||||||
return this;
|
{
|
||||||
|
var landingCell = self.Location;
|
||||||
|
if (!aircraft.CanLand(landingCell, ignoreActor))
|
||||||
|
{
|
||||||
|
self.NotifyBlocker(landingCell);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
aircraft.AddInfluence(landingCell);
|
||||||
|
landingInitiated = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel())
|
if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,22 +19,52 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
readonly Target target;
|
readonly Target target;
|
||||||
readonly Aircraft aircraft;
|
readonly Aircraft aircraft;
|
||||||
|
readonly bool requireSpace;
|
||||||
|
readonly Actor ignoreActor;
|
||||||
|
|
||||||
|
bool landingInitiated;
|
||||||
bool soundPlayed;
|
bool soundPlayed;
|
||||||
|
|
||||||
public Land(Actor self, Target t)
|
public Land(Actor self, Target t, bool requireSpace, Actor ignoreActor = null)
|
||||||
{
|
{
|
||||||
target = t;
|
target = t;
|
||||||
aircraft = self.Trait<Aircraft>();
|
aircraft = self.Trait<Aircraft>();
|
||||||
|
this.requireSpace = requireSpace;
|
||||||
|
this.ignoreActor = ignoreActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
|
if (ChildActivity != null)
|
||||||
|
{
|
||||||
|
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
|
||||||
|
if (ChildActivity != null)
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
if (!target.IsValidFor(self))
|
if (!target.IsValidFor(self))
|
||||||
Cancel(self);
|
return NextActivity;
|
||||||
|
|
||||||
if (IsCanceling)
|
if (IsCanceling)
|
||||||
|
{
|
||||||
|
aircraft.RemoveInfluence();
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requireSpace && !landingInitiated)
|
||||||
|
{
|
||||||
|
var landingCell = self.World.Map.CellContaining(target.CenterPosition);
|
||||||
|
if (!aircraft.CanLand(landingCell, ignoreActor))
|
||||||
|
{
|
||||||
|
// Maintain holding pattern.
|
||||||
|
QueueChild(self, new FlyCircle(self, 25), true);
|
||||||
|
self.NotifyBlocker(landingCell);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
aircraft.AddInfluence(landingCell);
|
||||||
|
landingInitiated = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel())
|
if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -230,10 +230,10 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
if (aircraft.Info.TurnToDock)
|
if (aircraft.Info.TurnToDock)
|
||||||
QueueChild(self, new Turn(self, aircraft.Info.InitialFacing), true);
|
QueueChild(self, new Turn(self, aircraft.Info.InitialFacing), true);
|
||||||
|
|
||||||
QueueChild(self, new HeliLand(self, false), true);
|
QueueChild(self, new HeliLand(self, true, dest), true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
QueueChild(self, new Land(self, Target.FromPos(dest.CenterPosition + offset)), true);
|
QueueChild(self, new Land(self, Target.FromPos(dest.CenterPosition + offset), true, dest), true);
|
||||||
|
|
||||||
QueueChild(self, new ResupplyAircraft(self), true);
|
QueueChild(self, new ResupplyAircraft(self), true);
|
||||||
resupplied = true;
|
resupplied = true;
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, destination)));
|
transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, destination), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
transport.QueueActivity(new Wait(15));
|
transport.QueueActivity(new Wait(15));
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
[Desc("Queues a landing activity on the specififed actor.")]
|
[Desc("Queues a landing activity on the specififed actor.")]
|
||||||
public void Land(Actor landOn)
|
public void Land(Actor landOn)
|
||||||
{
|
{
|
||||||
Self.QueueActivity(new Land(Self, Target.FromActor(landOn)));
|
Self.QueueActivity(new Land(Self, Target.FromActor(landOn), true, landOn));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ScriptActorPropertyActivity]
|
[ScriptActorPropertyActivity]
|
||||||
|
|||||||
@@ -166,8 +166,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle,
|
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle,
|
||||||
IActorPreviewInitModifier, IIssueDeployOrder, IObservesVariables
|
IActorPreviewInitModifier, IIssueDeployOrder, IObservesVariables
|
||||||
{
|
{
|
||||||
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
|
||||||
|
|
||||||
public readonly AircraftInfo Info;
|
public readonly AircraftInfo Info;
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
|
|
||||||
@@ -185,6 +183,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public Actor ReservedActor { get; private set; }
|
public Actor ReservedActor { get; private set; }
|
||||||
public bool MayYieldReservation { get; private set; }
|
public bool MayYieldReservation { get; private set; }
|
||||||
public bool ForceLanding { get; private set; }
|
public bool ForceLanding { get; private set; }
|
||||||
|
CPos landingCell;
|
||||||
|
|
||||||
bool airborne;
|
bool airborne;
|
||||||
bool cruising;
|
bool cruising;
|
||||||
@@ -493,7 +492,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
get { return Util.ApplyPercentageModifiers(Info.Speed, speedModifiers); }
|
get { return Util.ApplyPercentageModifiers(Info.Speed, speedModifiers); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<CPos, SubCell>[] OccupiedCells() { return NoCells; }
|
public Pair<CPos, SubCell>[] OccupiedCells()
|
||||||
|
{
|
||||||
|
if (!self.IsAtGroundLevel())
|
||||||
|
return new[] { Pair.New(landingCell, SubCell.FullCell) };
|
||||||
|
|
||||||
|
return new[] { Pair.New(TopLeft, SubCell.FullCell) };
|
||||||
|
}
|
||||||
|
|
||||||
public WVec FlyStep(int facing)
|
public WVec FlyStep(int facing)
|
||||||
{
|
{
|
||||||
@@ -506,13 +511,22 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return speed * dir / 1024;
|
return speed * dir / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanLand(CPos cell)
|
public bool CanLand(CPos cell, Actor ignoreActor = null)
|
||||||
{
|
{
|
||||||
if (!self.World.Map.Contains(cell))
|
if (!self.World.Map.Contains(cell))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (self.World.ActorMap.AnyActorsAt(cell))
|
foreach (var otherActor in self.World.ActorMap.GetActorsAt(cell))
|
||||||
return false;
|
{
|
||||||
|
if (otherActor != ignoreActor)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var otherActor in self.World.ActorMap.GetActorsAt(cell))
|
||||||
|
{
|
||||||
|
if (AircraftCanEnter(otherActor))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -575,7 +589,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
else if (!Info.CanHover && !atLandAltitude)
|
else if (!Info.CanHover && !atLandAltitude)
|
||||||
self.QueueActivity(new FlyCircle(self, -1, Info.IdleTurnSpeed > -1 ? Info.IdleTurnSpeed : TurnSpeed));
|
self.QueueActivity(new FlyCircle(self, -1, Info.IdleTurnSpeed > -1 ? Info.IdleTurnSpeed : TurnSpeed));
|
||||||
else if (atLandAltitude && !CanLand(self.Location) && ReservedActor == null)
|
else if (atLandAltitude && !CanLand(self.Location, self) && ReservedActor == null)
|
||||||
self.QueueActivity(new TakeOff(self));
|
self.QueueActivity(new TakeOff(self));
|
||||||
else if (Info.CanHover && self.Info.HasTraitInfo<AutoCarryallInfo>() && Info.IdleTurnSpeed > -1)
|
else if (Info.CanHover && self.Info.HasTraitInfo<AutoCarryallInfo>() && Info.IdleTurnSpeed > -1)
|
||||||
{
|
{
|
||||||
@@ -627,6 +641,19 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
OnCruisingAltitudeLeft();
|
OnCruisingAltitudeLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddInfluence(CPos landingCell)
|
||||||
|
{
|
||||||
|
this.landingCell = landingCell;
|
||||||
|
if (self.IsInWorld)
|
||||||
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveInfluence()
|
||||||
|
{
|
||||||
|
if (self.IsInWorld)
|
||||||
|
self.World.ActorMap.RemoveInfluence(self, this);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implement IMove
|
#region Implement IMove
|
||||||
@@ -701,7 +728,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public Activity MoveIntoTarget(Actor self, Target target)
|
public Activity MoveIntoTarget(Actor self, Target target)
|
||||||
{
|
{
|
||||||
if (!Info.VTOL)
|
if (!Info.VTOL)
|
||||||
return new Land(self, target);
|
return new Land(self, target, false);
|
||||||
|
|
||||||
return new HeliLand(self, false);
|
return new HeliLand(self, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !IsEmpty(self) && (aircraft == null || aircraft.CanLand(self.Location))
|
return !IsEmpty(self) && (aircraft == null || aircraft.CanLand(self.Location, self))
|
||||||
&& CurrentAdjacentCells != null && CurrentAdjacentCells.Any(c => Passengers.Any(p => p.Trait<IPositionable>().CanEnterCell(c, null, immediate)));
|
&& CurrentAdjacentCells != null && CurrentAdjacentCells.Any(c => Passengers.Any(p => p.Trait<IPositionable>().CanEnterCell(c, null, immediate)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -409,4 +409,4 @@ HUNTER:
|
|||||||
Palette: pips
|
Palette: pips
|
||||||
HitShape:
|
HitShape:
|
||||||
MapEditorData:
|
MapEditorData:
|
||||||
Categories: System
|
Categories: System
|
||||||
|
|||||||
Reference in New Issue
Block a user