Spawn aircraft landed and occupying land or at cruise altitude

This commit is contained in:
Gustas
2024-06-03 19:14:25 +03:00
committed by Matthias Mailänder
parent 734afd8bcf
commit 7b01204eed
3 changed files with 81 additions and 21 deletions

View File

@@ -286,6 +286,7 @@ namespace OpenRA.Mods.Common.Traits
public bool RequireForceMove; public bool RequireForceMove;
readonly int creationActivityDelay; readonly int creationActivityDelay;
readonly bool creationByMap;
readonly CPos[] creationRallyPoint; readonly CPos[] creationRallyPoint;
bool notify = true; bool notify = true;
@@ -312,12 +313,13 @@ namespace OpenRA.Mods.Common.Traits
self = init.Self; self = init.Self;
var locationInit = init.GetOrDefault<LocationInit>(); var locationInit = init.GetOrDefault<LocationInit>();
if (locationInit != null)
SetPosition(self, locationInit.Value);
var centerPositionInit = init.GetOrDefault<CenterPositionInit>(); var centerPositionInit = init.GetOrDefault<CenterPositionInit>();
if (centerPositionInit != null) if (locationInit != null || centerPositionInit != null)
SetPosition(self, centerPositionInit.Value); {
var pos = centerPositionInit?.Value ?? self.World.Map.CenterOfCell(locationInit.Value);
creationByMap = init.Contains<SpawnedByMapInit>();
SetPosition(self, pos);
}
Facing = init.GetValue<FacingInit, WAngle>(Info.InitialFacing); Facing = init.GetValue<FacingInit, WAngle>(Info.InitialFacing);
creationActivityDelay = init.GetValue<CreationActivityDelayInit, int>(0); creationActivityDelay = init.GetValue<CreationActivityDelayInit, int>(0);
@@ -1220,8 +1222,8 @@ namespace OpenRA.Mods.Common.Traits
Activity ICreationActivity.GetCreationActivity() Activity ICreationActivity.GetCreationActivity()
{ {
if (creationRallyPoint != null || creationActivityDelay > 0) if (creationRallyPoint != null || creationActivityDelay > 0 || creationByMap)
return new AssociateWithAirfieldActivity(self, creationActivityDelay, creationRallyPoint); return new AssociateWithAirfieldActivity(this, creationActivityDelay, creationRallyPoint, creationByMap);
return null; return null;
} }
@@ -1231,27 +1233,69 @@ namespace OpenRA.Mods.Common.Traits
readonly Aircraft aircraft; readonly Aircraft aircraft;
readonly int delay; readonly int delay;
readonly CPos[] rallyPoint; readonly CPos[] rallyPoint;
readonly bool creationByMap;
public AssociateWithAirfieldActivity(Actor self, int delay, CPos[] rallyPoint) public AssociateWithAirfieldActivity(Aircraft self, int delay, CPos[] rallyPoint, bool creationByMap)
{ {
aircraft = self.Trait<Aircraft>(); aircraft = self;
this.delay = delay; this.delay = delay;
this.rallyPoint = rallyPoint; this.rallyPoint = rallyPoint;
this.creationByMap = creationByMap;
} }
protected override void OnFirstRun(Actor self) protected override void OnFirstRun(Actor self)
{ {
var host = aircraft.GetActorBelow(); var cpos = self.Location;
if (host != null) var pos = self.CenterPosition;
bool TryDock()
{ {
aircraft.MakeReservation(host); var host = aircraft.GetActorBelow();
if (host != null)
{
// Center the actor on the resupplier.
var exit = host.NearestExitOrDefault(pos);
pos = host.CenterPosition;
pos = new WPos(pos.X, pos.Y, pos.Z - self.World.Map.DistanceAboveTerrain(pos).Length);
if (exit != null)
{
pos += exit.Info.SpawnOffset;
if (exit.Info.Facing != null)
aircraft.Facing = exit.Info.Facing.Value;
}
// Freshly created aircraft shouldn't block the exit, so we allow them to yield their reservation. aircraft.AddInfluence(cpos);
aircraft.AllowYieldingReservation(); aircraft.SetPosition(self, pos);
aircraft.MakeReservation(host);
// Freshly created aircraft shouldn't block the exit, so we allow them to yield their reservation.
aircraft.AllowYieldingReservation();
return true;
}
return false;
} }
if (delay > 0) if (creationByMap)
QueueChild(new Wait(delay)); {
if (TryDock())
return;
pos = new WPos(pos.X, pos.Y, pos.Z - self.World.Map.DistanceAboveTerrain(pos).Length);
if (!aircraft.Info.TakeOffOnCreation && aircraft.CanLand(cpos))
{
aircraft.AddInfluence(cpos);
aircraft.SetPosition(self, pos);
}
else
aircraft.SetPosition(self, new WPos(pos.X, pos.Y, pos.Z + aircraft.Info.CruiseAltitude.Length));
}
else
{
TryDock();
if (delay > 0)
QueueChild(new Wait(delay));
}
} }
public override bool Tick(Actor self) public override bool Tick(Actor self)
@@ -1260,16 +1304,29 @@ namespace OpenRA.Mods.Common.Traits
return true; return true;
if (rallyPoint != null && rallyPoint.Length > 0) if (rallyPoint != null && rallyPoint.Length > 0)
{
foreach (var cell in rallyPoint) foreach (var cell in rallyPoint)
QueueChild(new AttackMoveActivity(self, () => aircraft.MoveTo(cell, 1, evaluateNearestMovableCell: true, targetLineColor: Color.OrangeRed))); QueueChild(new AttackMoveActivity(self, () => aircraft.MoveTo(cell, 1, evaluateNearestMovableCell: true, targetLineColor: Color.OrangeRed)));
}
else if (self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition).Length <= aircraft.LandAltitude.Length)
QueueChild(new TakeOff(self));
aircraft.UnReserve(); if (!creationByMap)
aircraft.UnReserve();
return true; return true;
} }
public override IEnumerable<Target> GetTargets(Actor self)
{
if (ChildActivity != null)
return ChildActivity.GetTargets(self);
return Target.None;
}
public override IEnumerable<TargetLineNode> TargetLineNodes(Actor self)
{
if (ChildActivity != null)
foreach (var n in ChildActivity.TargetLineNodes(self))
yield return n;
}
} }
public class AircraftMoveOrderTargeter : IOrderTargeter public class AircraftMoveOrderTargeter : IOrderTargeter

View File

@@ -94,6 +94,7 @@ namespace OpenRA.Mods.Common.Traits
new OwnerInit(p), new OwnerInit(p),
new SkipMakeAnimsInit(), new SkipMakeAnimsInit(),
new FacingInit(facing), new FacingInit(facing),
new SpawnedByMapInit(),
}); });
} }
@@ -123,6 +124,7 @@ namespace OpenRA.Mods.Common.Traits
new LocationInit(validCell), new LocationInit(validCell),
new SubCellInit(subCell), new SubCellInit(subCell),
new FacingInit(facing), new FacingInit(facing),
new SpawnedByMapInit(),
}); });
} }
} }

View File

@@ -18,6 +18,7 @@ carryall.reinforce:
LandableTerrainTypes: Sand, Rock, Transition, Spice, SpiceSand, Dune, Concrete LandableTerrainTypes: Sand, Rock, Transition, Spice, SpiceSand, Dune, Concrete
Repulsable: False Repulsable: False
AirborneCondition: airborne AirborneCondition: airborne
CanForceLand: false
CanSlide: True CanSlide: True
VTOL: true VTOL: true
IdleTurnSpeed: 4 IdleTurnSpeed: 4