From 55b11d1745380b53015a75e4c16e87631d5840c3 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 25 Feb 2018 16:56:47 +0100 Subject: [PATCH] Don't cache ActorSpawners at creation Re-evaluate before every spawn attempt instead. Also accounts for ActorSpawner being conditional now. While a bit more costly in terms of performance, this allows to create spawns mid-game. --- .../Traits/World/ActorSpawnManager.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/World/ActorSpawnManager.cs b/OpenRA.Mods.Common/Traits/World/ActorSpawnManager.cs index e10249e896..bea1709992 100644 --- a/OpenRA.Mods.Common/Traits/World/ActorSpawnManager.cs +++ b/OpenRA.Mods.Common/Traits/World/ActorSpawnManager.cs @@ -45,7 +45,6 @@ namespace OpenRA.Mods.Common.Traits public class ActorSpawnManager : ConditionalTrait, ITick, INotifyCreated { readonly ActorSpawnManagerInfo info; - TraitPair[] spawnPointActors; bool enabled; int spawnCountdown; @@ -58,14 +57,7 @@ namespace OpenRA.Mods.Common.Traits void INotifyCreated.Created(Actor self) { - self.World.AddFrameEndTask(w => - { - spawnPointActors = w.ActorsWithTrait() - .Where(x => info.Types.Overlaps(x.Trait.Types) || !x.Trait.Types.Any()) - .ToArray(); - - enabled = self.Trait().Enabled && spawnPointActors.Any(); - }); + enabled = self.Trait().Enabled; } void ITick.Tick(Actor self) @@ -79,19 +71,23 @@ namespace OpenRA.Mods.Common.Traits if (--spawnCountdown > 0 && actorsPresent >= info.Minimum) return; + var spawnPoint = GetRandomSpawnPoint(self.World, self.World.SharedRandom); + + if (spawnPoint == null) + return; + spawnCountdown = info.SpawnInterval; do { // Always spawn at least one actor, plus // however many needed to reach the minimum. - SpawnActor(self); + SpawnActor(self, spawnPoint); } while (actorsPresent < info.Minimum); } - WPos SpawnActor(Actor self) + WPos SpawnActor(Actor self, Actor spawnPoint) { - var spawnPoint = GetRandomSpawnPoint(self.World.SharedRandom); self.World.AddFrameEndTask(w => w.CreateActor(info.Actors.Random(self.World.SharedRandom), new TypeDictionary { new OwnerInit(w.Players.First(x => x.PlayerName == info.Owner)), @@ -103,9 +99,13 @@ namespace OpenRA.Mods.Common.Traits return spawnPoint.CenterPosition; } - Actor GetRandomSpawnPoint(Support.MersenneTwister random) + Actor GetRandomSpawnPoint(World world, Support.MersenneTwister random) { - return spawnPointActors.Random(random).Actor; + var spawnPointActors = world.ActorsWithTrait() + .Where(x => !x.Trait.IsTraitDisabled && (info.Types.Overlaps(x.Trait.Types) || !x.Trait.Types.Any())) + .ToArray(); + + return spawnPointActors.Any() ? spawnPointActors.Random(random).Actor : null; } public void DecreaseActorCount()