Skip to content

Commit

Permalink
Don't cache ActorSpawners at creation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
reaperrr committed Mar 8, 2018
1 parent 99e5023 commit d8b76aa
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions OpenRA.Mods.Common/Traits/World/ActorSpawnManager.cs
Expand Up @@ -45,7 +45,6 @@ public class ActorSpawnManagerInfo : ConditionalTraitInfo, Requires<MapCreepsInf
public class ActorSpawnManager : ConditionalTrait<ActorSpawnManagerInfo>, ITick, INotifyCreated
{
readonly ActorSpawnManagerInfo info;
TraitPair<ActorSpawner>[] spawnPointActors;

bool enabled;
int spawnCountdown;
Expand All @@ -58,14 +57,7 @@ public ActorSpawnManager(Actor self, ActorSpawnManagerInfo info) : base(info)

void INotifyCreated.Created(Actor self)
{
self.World.AddFrameEndTask(w =>
{
spawnPointActors = w.ActorsWithTrait<ActorSpawner>()
.Where(x => info.Types.Overlaps(x.Trait.Types) || !x.Trait.Types.Any())
.ToArray();
enabled = self.Trait<MapCreeps>().Enabled && spawnPointActors.Any();
});
enabled = self.Trait<MapCreeps>().Enabled;
}

void ITick.Tick(Actor self)
Expand All @@ -79,19 +71,23 @@ void ITick.Tick(Actor self)
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)),
Expand All @@ -103,9 +99,13 @@ WPos SpawnActor(Actor self)
return spawnPoint.CenterPosition;
}

Actor GetRandomSpawnPoint(Support.MersenneTwister random)
Actor GetRandomSpawnPoint(World world, Support.MersenneTwister random)
{
return spawnPointActors.Random(random).Actor;
var spawnPointActors = world.ActorsWithTrait<ActorSpawner>()
.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()
Expand Down

0 comments on commit d8b76aa

Please sign in to comment.