From 98896f9a755b5f4636dbc69ea808db5562218e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Tue, 25 Jul 2023 21:43:23 +0200 Subject: [PATCH] Make Cargo and Carryall conditional. --- OpenRA.Mods.Common/Activities/PickupUnit.cs | 6 ++--- .../Activities/RideTransport.cs | 8 ++++++- OpenRA.Mods.Common/Traits/AutoCarryable.cs | 4 ++-- OpenRA.Mods.Common/Traits/AutoCarryall.cs | 8 +++---- OpenRA.Mods.Common/Traits/Cargo.cs | 20 +++++++++++------ OpenRA.Mods.Common/Traits/Carryall.cs | 22 +++++++++++++------ OpenRA.Mods.Common/Traits/Passenger.cs | 6 ++--- 7 files changed, 47 insertions(+), 27 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/PickupUnit.cs b/OpenRA.Mods.Common/Activities/PickupUnit.cs index 344498bc9b..1e3f4da1e8 100644 --- a/OpenRA.Mods.Common/Activities/PickupUnit.cs +++ b/OpenRA.Mods.Common/Activities/PickupUnit.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Activities protected override void OnFirstRun(Actor self) { // The cargo might have become invalid while we were moving towards it. - if (cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self)) + if (cargo.IsDead || carryable.IsTraitDisabled || carryall.IsTraitDisabled || !cargo.AppearsFriendlyTo(self)) return; if (carryall.ReserveCarryable(self, cargo)) @@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceling) return true; - if (cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self) || cargo != carryall.Carryable) + if (cargo.IsDead || carryable.IsTraitDisabled || carryall.IsTraitDisabled || !cargo.AppearsFriendlyTo(self) || cargo != carryall.Carryable) { Cancel(self, true); return false; @@ -160,7 +160,7 @@ namespace OpenRA.Mods.Common.Activities protected override void OnFirstRun(Actor self) { // The cargo might have become invalid while we were moving towards it. - if (cargo == null || cargo.IsDead || carryable.IsTraitDisabled || carryall.Carryable != cargo || !cargo.AppearsFriendlyTo(self)) + if (cargo == null || cargo.IsDead || carryable.IsTraitDisabled || carryall.IsTraitDisabled || carryall.Carryable != cargo || !cargo.AppearsFriendlyTo(self)) return; self.World.AddFrameEndTask(w => diff --git a/OpenRA.Mods.Common/Activities/RideTransport.cs b/OpenRA.Mods.Common/Activities/RideTransport.cs index d9ae9d1c7f..c412c03b7d 100644 --- a/OpenRA.Mods.Common/Activities/RideTransport.cs +++ b/OpenRA.Mods.Common/Activities/RideTransport.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Activities // Make sure we can still enter the transport // (but not before, because this may stop the actor in the middle of nowhere) - if (enterCargo == null || !passenger.Reserve(self, enterCargo)) + if (enterCargo == null || enterCargo.IsTraitDisabled || !passenger.Reserve(self, enterCargo)) { Cancel(self, true); return false; @@ -49,6 +49,12 @@ namespace OpenRA.Mods.Common.Activities return true; } + protected override void TickInner(Actor self, in Target target, bool targetIsDeadOrHiddenActor) + { + if (enterCargo != null && enterCargo.IsTraitDisabled) + Cancel(self, true); + } + protected override void OnEnterComplete(Actor self, Actor targetActor) { self.World.AddFrameEndTask(w => diff --git a/OpenRA.Mods.Common/Traits/AutoCarryable.cs b/OpenRA.Mods.Common/Traits/AutoCarryable.cs index c85c2cf29b..7dc96881f0 100644 --- a/OpenRA.Mods.Common/Traits/AutoCarryable.cs +++ b/OpenRA.Mods.Common/Traits/AutoCarryable.cs @@ -13,7 +13,7 @@ using System.Linq; namespace OpenRA.Mods.Common.Traits { - [Desc("Can be carried by units with the trait `Carryall`.")] + [Desc("Can be carried by units with the trait `" + nameof(Carryall) + "`.")] public class AutoCarryableInfo : CarryableInfo { [Desc("Required distance away from destination before requesting a pickup. Default is 6 cells.")] @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits // Inform all idle carriers var carriers = self.World.ActorsWithTrait() - .Where(c => c.Trait.State == Carryall.CarryallState.Idle && !c.Actor.IsDead && c.Actor.Owner == self.Owner && c.Actor.IsInWorld) + .Where(c => c.Trait.State == Carryall.CarryallState.Idle && !c.Trait.IsTraitDisabled && !c.Actor.IsDead && c.Actor.Owner == self.Owner && c.Actor.IsInWorld) .OrderBy(p => (self.Location - p.Actor.Location).LengthSquared); // Enumerate idle carriers to find the first that is able to transport us diff --git a/OpenRA.Mods.Common/Traits/AutoCarryall.cs b/OpenRA.Mods.Common/Traits/AutoCarryall.cs index 39a7a182e0..bd6b2117ef 100644 --- a/OpenRA.Mods.Common/Traits/AutoCarryall.cs +++ b/OpenRA.Mods.Common/Traits/AutoCarryall.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits // A carryable notifying us that he'd like to be carried public override bool RequestTransportNotify(Actor self, Actor carryable, CPos destination) { - if (busy) + if (busy || IsTraitDisabled) return false; if (ReserveCarryable(self, carryable)) @@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits void FindCarryableForTransport(Actor self) { - if (!self.IsInWorld) + if (!self.IsInWorld || IsTraitDisabled) return; // Get all carryables who want transport @@ -117,14 +117,14 @@ namespace OpenRA.Mods.Common.Traits protected override void OnFirstRun(Actor self) { - if (!cargo.IsDead) + if (!cargo.IsDead && !carryall.IsTraitDisabled) QueueChild(new PickupUnit(self, cargo, 0, carryall.Info.TargetLineColor)); } public override bool Tick(Actor self) { // Cargo may have become invalid or PickupUnit cancelled. - if (carryall.Carryable == null || carryall.Carryable.IsDead) + if (carryall.IsTraitDisabled || carryall.Carryable == null || carryall.Carryable.IsDead) return true; var dropRange = carryall.Info.DropRange; diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index aecccaa67c..62d79b9610 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -21,7 +21,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("This actor can transport Passenger actors.")] - public class CargoInfo : TraitInfo, Requires + public class CargoInfo : ConditionalTraitInfo, Requires { [Desc("The maximum sum of Passenger.Weight that this actor can support.")] public readonly int MaxWeight = 0; @@ -88,11 +88,10 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new Cargo(init, this); } } - public class Cargo : IIssueOrder, IResolveOrder, IOrderVoice, INotifyCreated, INotifyKilled, + public class Cargo : ConditionalTrait, IIssueOrder, IResolveOrder, IOrderVoice, INotifyOwnerChanged, INotifySold, INotifyActorDisposing, IIssueDeployOrder, - ITransformActorInitModifier + INotifyCreated, INotifyKilled, ITransformActorInitModifier { - public readonly CargoInfo Info; readonly Actor self; readonly List cargo = new(); readonly HashSet reserves = new(); @@ -119,9 +118,9 @@ namespace OpenRA.Mods.Common.Traits State state = State.Free; public Cargo(ActorInitializer init, CargoInfo info) + : base(info) { self = init.Self; - Info = info; checkTerrainType = info.UnloadTerrainTypes.Count > 0; currentAdjacentCells = new CachedTransform>(loc => @@ -162,8 +161,9 @@ namespace OpenRA.Mods.Common.Traits facing = Exts.Lazy(self.TraitOrDefault); } - void INotifyCreated.Created(Actor self) + protected override void Created(Actor self) { + base.Created(self); aircraft = self.TraitOrDefault(); if (cargo.Count > 0) @@ -200,6 +200,9 @@ namespace OpenRA.Mods.Common.Traits { get { + if (IsTraitDisabled) + yield break; + yield return new DeployOrderTargeter("Unload", 10, () => CanUnload() ? Info.UnloadCursor : Info.UnloadBlockedCursor); } @@ -233,6 +236,9 @@ namespace OpenRA.Mods.Common.Traits public bool CanUnload(BlockedByActor check = BlockedByActor.None) { + if (IsTraitDisabled) + return false; + if (checkTerrainType) { var terrainType = self.World.Map.GetTerrainInfo(self.Location).Type; @@ -247,7 +253,7 @@ namespace OpenRA.Mods.Common.Traits public bool CanLoad(Actor a) { - return reserves.Contains(a) || HasSpace(GetWeight(a)); + return !IsTraitDisabled && (reserves.Contains(a) || HasSpace(GetWeight(a))); } internal bool ReserveSpace(Actor a) diff --git a/OpenRA.Mods.Common/Traits/Carryall.cs b/OpenRA.Mods.Common/Traits/Carryall.cs index 8f03af54c8..76c285f6db 100644 --- a/OpenRA.Mods.Common/Traits/Carryall.cs +++ b/OpenRA.Mods.Common/Traits/Carryall.cs @@ -21,7 +21,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Transports actors with the `" + nameof(Carryable) + "` trait.")] - public class CarryallInfo : TraitInfo, Requires, Requires + public class CarryallInfo : ConditionalTraitInfo, Requires, Requires { [ActorReference(typeof(CarryableInfo))] [Desc("Actor type that is initially spawned into this actor.")] @@ -83,8 +83,9 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new Carryall(init.Self, this); } } - public class Carryall : INotifyKilled, ISync, ITick, IRender, INotifyActorDisposing, IIssueOrder, IResolveOrder, - IOrderVoice, IIssueDeployOrder, IAircraftCenterPositionOffset, IOverrideAircraftLanding + public class Carryall : ConditionalTrait, INotifyKilled, ISync, ITick, IRender, + INotifyActorDisposing, IIssueOrder, IResolveOrder, IOrderVoice, IIssueDeployOrder, + IAircraftCenterPositionOffset, IOverrideAircraftLanding { public enum CarryallState { @@ -93,7 +94,6 @@ namespace OpenRA.Mods.Common.Traits Carrying } - public readonly CarryallInfo Info; readonly AircraftInfo aircraftInfo; readonly Aircraft aircraft; readonly BodyOrientation body; @@ -115,9 +115,8 @@ namespace OpenRA.Mods.Common.Traits public WVec CarryableOffset { get; private set; } public Carryall(Actor self, CarryallInfo info) + : base(info) { - Info = info; - Carryable = null; State = CarryallState.Idle; @@ -311,6 +310,9 @@ namespace OpenRA.Mods.Common.Traits // Check if we can drop the unit at our current location. public bool CanUnload() { + if (IsTraitDisabled) + return false; + var targetCell = self.World.Map.CellContaining(aircraft.GetPosition()); return Carryable != null && aircraft.CanLand(targetCell, blockedByMobile: false); } @@ -319,6 +321,9 @@ namespace OpenRA.Mods.Common.Traits { get { + if (IsTraitDisabled) + yield break; + yield return new CarryallPickupOrderTargeter(Info); yield return new DeployOrderTargeter("Unload", 10, () => CanUnload() ? Info.UnloadCursor : Info.UnloadBlockedCursor); @@ -339,7 +344,10 @@ namespace OpenRA.Mods.Common.Traits return new Order("Unload", self, queued); } - bool IIssueDeployOrder.CanIssueDeployOrder(Actor self, bool queued) { return true; } + bool IIssueDeployOrder.CanIssueDeployOrder(Actor self, bool queued) + { + return !IsTraitDisabled; + } void IResolveOrder.ResolveOrder(Actor self, Order order) { diff --git a/OpenRA.Mods.Common/Traits/Passenger.cs b/OpenRA.Mods.Common/Traits/Passenger.cs index f0a10e1ea7..c72544fbe4 100644 --- a/OpenRA.Mods.Common/Traits/Passenger.cs +++ b/OpenRA.Mods.Common/Traits/Passenger.cs @@ -109,13 +109,13 @@ namespace OpenRA.Mods.Common.Traits bool IsCorrectCargoType(Actor target) { - var ci = target.Info.TraitInfo(); - return ci.Types.Contains(Info.CargoType); + var cargo = target.Trait(); + return !cargo.IsTraitDisabled && cargo.Info.Types.Contains(Info.CargoType); } bool CanEnter(Cargo cargo) { - return cargo != null && cargo.HasSpace(Info.Weight); + return cargo != null && !cargo.IsTraitDisabled && cargo.HasSpace(Info.Weight); } bool CanEnter(Actor target)