diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index 0ce4b9b853..5fa9bb9806 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -56,8 +56,13 @@ namespace OpenRA.Mods.Common.Traits public readonly string UnloadBlockedCursor = "deploy-blocked"; [UpgradeGrantedReference] - [Desc("The upgrades to grant to self while loading cargo.")] - public readonly string[] LoadingUpgrades = { }; + [Desc("The condition to grant to self while waiting for cargo to load.")] + public readonly string LoadingCondition = null; + + [UpgradeGrantedReference] + [Desc("Conditions to grant when specified actors are loaded inside the transport.", + "A dictionary of [actor id]: [condition].")] + public readonly Dictionary PassengerConditions = new Dictionary(); public object Create(ActorInitializer init) { return new Cargo(init, this); } } @@ -69,6 +74,7 @@ namespace OpenRA.Mods.Common.Traits readonly Actor self; readonly Stack cargo = new Stack(); readonly HashSet reserves = new HashSet(); + readonly Dictionary> passengerTokens = new Dictionary>(); readonly Lazy facing; readonly bool checkTerrainType; @@ -76,6 +82,7 @@ namespace OpenRA.Mods.Common.Traits int reservedWeight = 0; Aircraft aircraft; UpgradeManager upgradeManager; + int loadingToken = UpgradeManager.InvalidConditionToken; CPos currentCell; public IEnumerable CurrentAdjacentCells { get; private set; } @@ -193,9 +200,8 @@ namespace OpenRA.Mods.Common.Traits if (!HasSpace(w)) return false; - if (reserves.Count == 0) - foreach (var u in Info.LoadingUpgrades) - upgradeManager.GrantUpgrade(self, u, this); + if (upgradeManager != null && loadingToken == UpgradeManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.LoadingCondition)) + loadingToken = upgradeManager.GrantCondition(self, Info.LoadingCondition); reserves.Add(a); reservedWeight += w; @@ -211,9 +217,8 @@ namespace OpenRA.Mods.Common.Traits reservedWeight -= GetWeight(a); reserves.Remove(a); - if (reserves.Count == 0) - foreach (var u in Info.LoadingUpgrades) - upgradeManager.RevokeUpgrade(self, u, this); + if (loadingToken != UpgradeManager.InvalidConditionToken) + loadingToken = upgradeManager.RevokeCondition(self, loadingToken); } public string CursorForOrder(Actor self, Order order) @@ -251,8 +256,9 @@ namespace OpenRA.Mods.Common.Traits var p = a.Trait(); p.Transport = null; - foreach (var u in p.Info.GrantUpgrades) - upgradeManager.RevokeUpgrade(self, u, p); + Stack passengerToken; + if (passengerTokens.TryGetValue(a.Info.Name, out passengerToken) && passengerToken.Any()) + upgradeManager.RevokeCondition(self, passengerToken.Pop()); return a; } @@ -304,9 +310,8 @@ namespace OpenRA.Mods.Common.Traits reservedWeight -= w; reserves.Remove(a); - if (reserves.Count == 0) - foreach (var u in Info.LoadingUpgrades) - upgradeManager.RevokeUpgrade(self, u, this); + if (loadingToken != UpgradeManager.InvalidConditionToken) + loadingToken = upgradeManager.RevokeCondition(self, loadingToken); } // If not initialized then this will be notified in the first tick @@ -316,8 +321,10 @@ namespace OpenRA.Mods.Common.Traits var p = a.Trait(); p.Transport = self; - foreach (var u in p.Info.GrantUpgrades) - upgradeManager.GrantUpgrade(self, u, p); + + string passengerCondition; + if (upgradeManager != null && Info.PassengerConditions.TryGetValue(a.Info.Name, out passengerCondition)) + passengerTokens.GetOrAdd(a.Info.Name).Push(upgradeManager.GrantCondition(self, passengerCondition)); } void INotifyKilled.Killed(Actor self, AttackInfo e) diff --git a/OpenRA.Mods.Common/Traits/Passenger.cs b/OpenRA.Mods.Common/Traits/Passenger.cs index f8da87dbd1..3634a406c2 100644 --- a/OpenRA.Mods.Common/Traits/Passenger.cs +++ b/OpenRA.Mods.Common/Traits/Passenger.cs @@ -38,9 +38,6 @@ namespace OpenRA.Mods.Common.Traits [Desc("Range from self for looking for an alternate transport (default: 5.5 cells).")] public readonly WDist AlternateTransportScanRange = WDist.FromCells(11) / 2; - [Desc("Upgrade types to grant to transport.")] - [UpgradeGrantedReference] public readonly string[] GrantUpgrades = { }; - [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new Passenger(this); } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index fec57ffaac..739f454fff 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -574,6 +574,16 @@ namespace OpenRA.Mods.Common.UtilityCommands RenameNodeKey(node, "ProximityExternalCondition"); ConvertUpgradesToCondition(parent, node, "Upgrades", "Condition"); } + + if (node.Key == "Cargo") + ConvertUpgradesToCondition(parent, node, "LoadingUpgrades", "LoadingCondition"); + + if (node.Key == "Passenger" && node.Value.Nodes.Any(n => n.Key == "GrantUpgrades")) + { + Console.WriteLine("Passenger.GrantUpgrades support has been removed."); + Console.WriteLine("Define passenger-conditions using Cargo.PassengerConditions on the transports instead."); + node.Value.Nodes.RemoveAll(n => n.Key == "GrantUpgrades"); + } } UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); diff --git a/mods/cnc/rules/ships.yaml b/mods/cnc/rules/ships.yaml index b3031205a0..22adf1106e 100644 --- a/mods/cnc/rules/ships.yaml +++ b/mods/cnc/rules/ships.yaml @@ -76,4 +76,4 @@ LST: MaxWeight: 5 PipCount: 5 PassengerFacing: 0 - LoadingUpgrades: notmobile + LoadingCondition: notmobile diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index 34b3b10f55..2b1993933d 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -120,7 +120,7 @@ APC: Types: Infantry MaxWeight: 5 PipCount: 5 - LoadingUpgrades: notmobile + LoadingCondition: notmobile SpawnActorOnDeath: Actor: APC.Husk diff --git a/mods/ra/maps/infiltration/rules.yaml b/mods/ra/maps/infiltration/rules.yaml index 4c5e72a40b..402ec85ca9 100644 --- a/mods/ra/maps/infiltration/rules.yaml +++ b/mods/ra/maps/infiltration/rules.yaml @@ -55,7 +55,6 @@ SPY.Strong: ExternalCaptures: CaptureTypes: MissionObjective Passenger: - GrantUpgrades: mobile DOG.Patrol: Inherits: DOG @@ -76,6 +75,8 @@ TRUK.Hijackable: Types: Infantry MaxWeight: 5 PipCount: 5 + PassengerConditions: + spy.strong: mobile AutoTargetIgnore: -Huntable: ExternalCapturable: diff --git a/mods/ra/rules/ships.yaml b/mods/ra/rules/ships.yaml index 2c2c0fb2d6..7af2caa9d0 100644 --- a/mods/ra/rules/ships.yaml +++ b/mods/ra/rules/ships.yaml @@ -242,7 +242,7 @@ LST: MaxWeight: 5 PipCount: 5 PassengerFacing: 0 - LoadingUpgrades: notmobile + LoadingCondition: notmobile -Chronoshiftable: PT: diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index 2578daeaf4..afec84f2b2 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -355,7 +355,7 @@ JEEP: Types: Infantry MaxWeight: 1 PipCount: 1 - LoadingUpgrades: notmobile + LoadingCondition: notmobile ProducibleWithLevel: Prerequisites: vehicles.upgraded @@ -391,7 +391,7 @@ APC: Types: Infantry MaxWeight: 5 PipCount: 5 - LoadingUpgrades: notmobile + LoadingCondition: notmobile ProducibleWithLevel: Prerequisites: vehicles.upgraded @@ -752,7 +752,7 @@ STNK: Types: Infantry MaxWeight: 4 PipCount: 4 - LoadingUpgrades: notmobile + LoadingCondition: notmobile Cloak: InitialDelay: 125 CloakDelay: 250 diff --git a/mods/ts/rules/civilian-vehicles.yaml b/mods/ts/rules/civilian-vehicles.yaml index f43065b380..ec81344d6b 100644 --- a/mods/ts/rules/civilian-vehicles.yaml +++ b/mods/ts/rules/civilian-vehicles.yaml @@ -102,7 +102,7 @@ BUS: MaxWeight: 20 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true PICK: @@ -126,7 +126,7 @@ PICK: MaxWeight: 2 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true CAR: @@ -150,7 +150,7 @@ CAR: MaxWeight: 4 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true WINI: @@ -174,7 +174,7 @@ WINI: MaxWeight: 5 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true LOCOMOTIVE: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index e5d7fde952..fbea23e652 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -802,7 +802,7 @@ Cargo: Types: Infantry UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading Health: HP: 100 Armor: diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index e57ea36dbb..4ae451de5e 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -28,7 +28,7 @@ APC: MaxWeight: 5 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true UpgradeOnTerrain: Upgrades: inwater diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml index 965ede8f7f..550b8554ae 100644 --- a/mods/ts/rules/nod-vehicles.yaml +++ b/mods/ts/rules/nod-vehicles.yaml @@ -285,7 +285,7 @@ SAPC: MaxWeight: 5 PipCount: 5 UnloadVoice: Unload - LoadingUpgrades: loading + LoadingCondition: loading EjectOnDeath: true SUBTANK: