diff --git a/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs b/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs index 05bebc0bd9..ece58e17e6 100644 --- a/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs +++ b/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs @@ -83,29 +83,31 @@ namespace OpenRA.Mods.Common.Traits public override void Activate(Actor collector) { var positionable = collector.OccupiesSpace as IPositionable; - var candidateCells = collector.World.Map.FindTilesInCircle(collector.Location, info.MaxRadius) - .Where(c => positionable.CanEnterCell(c)).Shuffle(collector.World.SharedRandom) - .ToArray(); - - var duplicates = Math.Min(candidateCells.Length, info.MaxAmount); - - // Restrict duplicate count to a maximum value - if (info.MaxDuplicateValue > 0) + collector.World.AddFrameEndTask(w => { - var vi = collector.Info.TraitInfoOrDefault(); - if (vi != null && vi.Cost > 0) - duplicates = Math.Min(duplicates, info.MaxDuplicateValue / vi.Cost); - } + var candidateCells = collector.World.Map.FindTilesInCircle(collector.Location, info.MaxRadius) + .Where(c => positionable.CanEnterCell(c)).Shuffle(collector.World.SharedRandom) + .ToArray(); - for (var i = 0; i < duplicates; i++) - { - var cell = candidateCells[i]; // Avoid modified closure bug - collector.World.AddFrameEndTask(w => w.CreateActor(collector.Info.Name, new TypeDictionary + var duplicates = Math.Min(candidateCells.Length, info.MaxAmount); + + // Restrict duplicate count to a maximum value + if (info.MaxDuplicateValue > 0) { - new LocationInit(cell), - new OwnerInit(info.Owner ?? collector.Owner.InternalName) - })); - } + var vi = collector.Info.TraitInfoOrDefault(); + if (vi != null && vi.Cost > 0) + duplicates = Math.Min(duplicates, info.MaxDuplicateValue / vi.Cost); + } + + for (var i = 0; i < duplicates; i++) + { + w.CreateActor(collector.Info.Name, new TypeDictionary + { + new LocationInit(candidateCells[i]), + new OwnerInit(info.Owner ?? collector.Owner.InternalName) + }); + } + }); base.Activate(collector); } diff --git a/OpenRA.Mods.Common/Traits/Crates/GiveUnitCrateAction.cs b/OpenRA.Mods.Common/Traits/Crates/GiveUnitCrateAction.cs index ee184a3711..71536e73b2 100644 --- a/OpenRA.Mods.Common/Traits/Crates/GiveUnitCrateAction.cs +++ b/OpenRA.Mods.Common/Traits/Crates/GiveUnitCrateAction.cs @@ -38,7 +38,6 @@ namespace OpenRA.Mods.Common.Traits { readonly Actor self; readonly GiveUnitCrateActionInfo info; - readonly List usedCells = new(); public GiveUnitCrateAction(Actor self, GiveUnitCrateActionInfo info) : base(self, info) @@ -77,22 +76,21 @@ namespace OpenRA.Mods.Common.Traits public override void Activate(Actor collector) { - foreach (var u in info.Units) + collector.World.AddFrameEndTask(w => { - var unit = u; // avoiding access to modified closure - - var location = ChooseEmptyCellNear(collector, unit); - if (location != null) + foreach (var unit in info.Units) { - usedCells.Add(location.Value); - collector.World.AddFrameEndTask( - w => w.CreateActor(unit, new TypeDictionary + var location = ChooseEmptyCellNear(collector, unit); + if (location != null) { - new LocationInit(location.Value), - new OwnerInit(info.Owner ?? collector.Owner.InternalName) - })); + w.CreateActor(unit, new TypeDictionary + { + new LocationInit(location.Value), + new OwnerInit(info.Owner ?? collector.Owner.InternalName) + }); + } } - } + }); base.Activate(collector); } @@ -109,8 +107,8 @@ namespace OpenRA.Mods.Common.Traits CPos? ChooseEmptyCellNear(Actor a, string unit) { - var possibleCells = GetSuitableCells(a.Location, unit).Where(c => !usedCells.Contains(c)).ToList(); - if (possibleCells.Count == 0) + var possibleCells = GetSuitableCells(a.Location, unit); + if (!possibleCells.Any()) return null; return possibleCells.Random(self.World.SharedRandom);