Skip to content

Commit

Permalink
Fix BaseBuilderBotModule.LocomotorsForProducibles.
Browse files Browse the repository at this point in the history
Account for per-actor production (e.g. ProductionQueue) and per-player production (e.g. ClassicProductionQueue). This requires resolving the Production and ProductionQueue traits on both the producing actor, and the owning player actor.

When setting rally points, check the actor didn't die first.
  • Loading branch information
RoosterDragon committed Dec 16, 2024
1 parent 43325fd commit e5401e4
Showing 1 changed file with 24 additions and 10 deletions.
34 changes: 24 additions & 10 deletions OpenRA.Mods.Common/Traits/BotModules/BaseBuilderBotModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void IBotTick.BotTick(IBot bot)
for (var i = 0; i < updateCount; i++)
{
var rp = rallyPoints.Pop();
if (rp.Actor.Owner == player)
if (rp.Actor.Owner == player && !rp.Actor.Disposed)
SetRallyPoint(bot, rp);
}
}
Expand Down Expand Up @@ -343,23 +343,37 @@ CPos ChooseRallyLocationNear(Actor producer)

Locomotor[] LocomotorsForProducibles(Actor producer)
{
var buildingInfo = producer.Info.TraitInfoOrDefault<BuildingInfo>();
var productionInfo = producer.Info.TraitInfoOrDefault<ProductionInfo>();
var locomotors = Array.Empty<Locomotor>();
// Per-actor production
var productions = producer.TraitsImplementing<Production>();

// Player-wide production
if (!productions.Any())
productions = producer.World.ActorsWithTrait<Production>().Where(x => x.Actor.Owner != producer.Owner).Select(x => x.Trait);

if (productionInfo != null && productionInfo.Produces.Length > 0)
var produces = productions.SelectMany(p => p.Info.Produces).ToHashSet();
var locomotors = Array.Empty<Locomotor>();
if (produces.Count > 0)
{
var productionQueues = producer.Owner.PlayerActor.TraitsImplementing<ProductionQueue>()
.Where(pq => productionInfo.Produces.Contains(pq.Info.Type));
// Per-actor production
var productionQueues = producer.TraitsImplementing<ProductionQueue>();

// Player-wide production
if (!productionQueues.Any())
productionQueues = producer.Owner.PlayerActor.TraitsImplementing<ProductionQueue>();

productionQueues = productionQueues.Where(pq => produces.Contains(pq.Info.Type));

var producibles = productionQueues.SelectMany(pq => pq.BuildableItems());
var locomotorNames = producibles
.Select(p => p.TraitInfoOrDefault<MobileInfo>())
.Where(mi => mi != null)
.Select(mi => mi.Locomotor)
.ToHashSet();
locomotors = world.WorldActor.TraitsImplementing<Locomotor>()
.Where(l => locomotorNames.Contains(l.Info.Name))
.ToArray();

if (locomotorNames.Count != 0)
locomotors = world.WorldActor.TraitsImplementing<Locomotor>()
.Where(l => locomotorNames.Contains(l.Info.Name))
.ToArray();
}

return locomotors;
Expand Down

0 comments on commit e5401e4

Please sign in to comment.