Improve Carryall behaviour and integration with Aircraft.

This commit is contained in:
tovl
2019-06-30 14:01:55 +00:00
committed by reaperrr
parent adecd4ca87
commit 8e5875453a
9 changed files with 96 additions and 155 deletions

View File

@@ -187,10 +187,12 @@ namespace OpenRA.Mods.Common.Traits
Repairable repairable;
Rearmable rearmable;
IAircraftCenterPositionOffset[] positionOffsets;
ConditionManager conditionManager;
IDisposable reservation;
IEnumerable<int> speedModifiers;
INotifyMoving[] notifyMoving;
IOverrideAircraftLanding overrideAircraftLanding;
[Sync]
public int Facing { get; set; }
@@ -206,13 +208,13 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<CPos> landingCells = Enumerable.Empty<CPos>();
bool requireForceMove;
public WDist LandAltitude { get; private set; }
public static WPos GroundPosition(Actor self)
{
return self.CenterPosition - new WVec(WDist.Zero, WDist.Zero, self.World.Map.DistanceAboveTerrain(self.CenterPosition));
}
public bool AtLandAltitude { get { return self.World.Map.DistanceAboveTerrain(GetPosition()) == LandAltitude; } }
bool airborne;
bool cruising;
bool firstTick = true;
@@ -236,17 +238,27 @@ namespace OpenRA.Mods.Common.Traits
SetPosition(self, init.Get<CenterPositionInit, WPos>());
Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : Info.InitialFacing;
LandAltitude = info.LandAltitude;
}
public void AddLandingOffset(int offset)
public WDist LandAltitude
{
LandAltitude += new WDist(offset);
get
{
var alt = Info.LandAltitude;
foreach (var offset in positionOffsets)
alt -= new WDist(offset.PositionOffset.Z);
return alt;
}
}
public void SubtractLandingOffset(int offset)
public WPos GetPosition()
{
LandAltitude -= new WDist(offset);
var pos = self.CenterPosition;
foreach (var offset in positionOffsets)
pos += offset.PositionOffset;
return pos;
}
public virtual IEnumerable<VariableObserver> GetVariableObservers()
@@ -281,6 +293,8 @@ namespace OpenRA.Mods.Common.Traits
speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray().Select(sm => sm.GetSpeedModifier());
cachedPosition = self.CenterPosition;
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
positionOffsets = self.TraitsImplementing<IAircraftCenterPositionOffset>().ToArray();
overrideAircraftLanding = self.TraitOrDefault<IOverrideAircraftLanding>();
}
void INotifyAddedToWorld.AddedToWorld(Actor self)
@@ -589,8 +603,8 @@ namespace OpenRA.Mods.Common.Traits
if (dockingActor != null)
return true;
var type = self.World.Map.GetTerrainInfo(cell).Type;
return Info.LandableTerrainTypes.Contains(type);
var landableTerrain = overrideAircraftLanding != null ? overrideAircraftLanding.LandableTerrainTypes : Info.LandableTerrainTypes;
return landableTerrain.Contains(self.World.Map.GetTerrainInfo(cell).Type);
}
bool IsBlockedBy(Actor self, Actor otherActor, Actor ignoreActor, bool blockedByMobile = true)

View File

@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
if (ReserveCarryable(self, carryable))
{
self.QueueActivity(false, new PickupUnit(self, carryable, 0));
self.QueueActivity(true, new DeliverUnit(self, destination));
self.QueueActivity(true, new DeliverUnit(self, Target.FromCell(self.World, destination), Info.DropRange));
return true;
}
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Traits
{
busy = true;
self.QueueActivity(false, new PickupUnit(self, p.Actor, 0));
self.QueueActivity(true, new DeliverUnit(self, p.Trait.Destination.Value));
self.QueueActivity(true, new DeliverUnit(self, Target.FromCell(self.World, p.Trait.Destination.Value), Info.DropRange));
break;
}
}

View File

@@ -30,6 +30,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Offset relative to the top-left cell of the building.")]
public readonly CVec DeliveryOffset = CVec.Zero;
[Desc("Range to search for an alternative delivery location if the DeliveryOffset cell is blocked.")]
public readonly WDist DeliveryRange = WDist.Zero;
public override object Create(ActorInitializer init) { return new FreeActorWithDelivery(init, this); }
}
@@ -58,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits
carryable.Reserve(cargo, carrier);
carrier.Trait<Carryall>().AttachCarryable(carrier, cargo);
carrier.QueueActivity(new DeliverUnit(carrier, location));
carrier.QueueActivity(new DeliverUnit(carrier, Target.FromCell(self.World, location), Info.DeliveryRange));
carrier.QueueActivity(new Fly(carrier, Target.FromCell(self.World, self.World.Map.ChooseRandomEdgeCell(self.World.SharedRandom))));
carrier.QueueActivity(new RemoveSelf());

View File

@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
}
public class Carryall : INotifyKilled, ISync, ITick, IRender, INotifyActorDisposing, IIssueOrder, IResolveOrder,
IOrderVoice, IIssueDeployOrder
IOrderVoice, IIssueDeployOrder, IAircraftCenterPositionOffset, IOverrideAircraftLanding
{
public enum CarryallState
{
@@ -80,7 +80,8 @@ namespace OpenRA.Mods.Common.Traits
public CarryallState State { get; private set; }
int cachedFacing;
IActorPreview[] carryablePreview = null;
IActorPreview[] carryablePreview;
HashSet<string> landableTerrainTypes;
/// <summary>Offset between the carryall's and the carried actor's CenterPositions</summary>
public WVec CarryableOffset { get; private set; }
@@ -154,6 +155,17 @@ namespace OpenRA.Mods.Common.Traits
return Info.LocalOffset - carryable.Info.TraitInfo<CarryableInfo>().LocalOffset;
}
WVec IAircraftCenterPositionOffset.PositionOffset
{
get
{
var localOffset = CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
return body.LocalToWorld(localOffset);
}
}
HashSet<string> IOverrideAircraftLanding.LandableTerrainTypes { get { return landableTerrainTypes ?? aircraft.Info.LandableTerrainTypes; } }
public virtual bool AttachCarryable(Actor self, Actor carryable)
{
if (State == CarryallState.Carrying)
@@ -164,7 +176,8 @@ namespace OpenRA.Mods.Common.Traits
self.World.ScreenMap.AddOrUpdate(self);
CarryableOffset = OffsetForCarryable(self, carryable);
aircraft.AddLandingOffset(-CarryableOffset.Z);
landableTerrainTypes = Carryable.Trait<Mobile>().Info.LocomotorInfo.TerrainSpeeds.Keys.ToHashSet();
return true;
}
@@ -174,7 +187,7 @@ namespace OpenRA.Mods.Common.Traits
self.World.ScreenMap.AddOrUpdate(self);
carryablePreview = null;
aircraft.SubtractLandingOffset(-CarryableOffset.Z);
landableTerrainTypes = null;
CarryableOffset = WVec.Zero;
}
@@ -245,9 +258,8 @@ namespace OpenRA.Mods.Common.Traits
// Check if we can drop the unit at our current location.
public bool CanUnload()
{
var localOffset = CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
var targetCell = self.World.Map.CellContaining(self.CenterPosition + body.LocalToWorld(localOffset));
return Carryable != null && Carryable.Trait<IPositionable>().CanEnterCell(targetCell, self);
var targetCell = self.World.Map.CellContaining(aircraft.GetPosition());
return Carryable != null && aircraft.CanLand(targetCell, blockedByMobile: false);
}
IEnumerable<IOrderTargeter> IIssueOrder.Orders
@@ -286,14 +298,14 @@ namespace OpenRA.Mods.Common.Traits
var targetLocation = move.NearestMoveableCell(cell);
self.SetTargetLine(Target.FromCell(self.World, targetLocation), Color.Yellow);
self.QueueActivity(order.Queued, new DeliverUnit(self, targetLocation));
self.QueueActivity(order.Queued, new DeliverUnit(self, order.Target, Info.DropRange));
}
else if (order.OrderString == "Unload")
{
if (!order.Queued && !CanUnload())
return;
self.QueueActivity(order.Queued, new DeliverUnit(self));
self.QueueActivity(order.Queued, new DeliverUnit(self, Info.DropRange));
}
if (order.OrderString == "PickupUnit")