Fix BaseBuilderBotModule.LocomotorsForProducibles.
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.
This commit is contained in:
@@ -240,7 +240,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
for (var i = 0; i < updateCount; i++)
|
for (var i = 0; i < updateCount; i++)
|
||||||
{
|
{
|
||||||
var rp = rallyPoints.Pop();
|
var rp = rallyPoints.Pop();
|
||||||
if (rp.Actor.Owner == player)
|
if (rp.Actor.Owner == player && !rp.Actor.Disposed)
|
||||||
SetRallyPoint(bot, rp);
|
SetRallyPoint(bot, rp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,23 +343,37 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
Locomotor[] LocomotorsForProducibles(Actor producer)
|
Locomotor[] LocomotorsForProducibles(Actor producer)
|
||||||
{
|
{
|
||||||
var buildingInfo = producer.Info.TraitInfoOrDefault<BuildingInfo>();
|
// Per-actor production
|
||||||
var productionInfo = producer.Info.TraitInfoOrDefault<ProductionInfo>();
|
var productions = producer.TraitsImplementing<Production>();
|
||||||
var locomotors = Array.Empty<Locomotor>();
|
|
||||||
|
|
||||||
if (productionInfo != null && productionInfo.Produces.Length > 0)
|
// Player-wide production
|
||||||
|
if (!productions.Any())
|
||||||
|
productions = producer.World.ActorsWithTrait<Production>().Where(x => x.Actor.Owner != producer.Owner).Select(x => x.Trait);
|
||||||
|
|
||||||
|
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>()
|
// Per-actor production
|
||||||
.Where(pq => productionInfo.Produces.Contains(pq.Info.Type));
|
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 producibles = productionQueues.SelectMany(pq => pq.BuildableItems());
|
||||||
var locomotorNames = producibles
|
var locomotorNames = producibles
|
||||||
.Select(p => p.TraitInfoOrDefault<MobileInfo>())
|
.Select(p => p.TraitInfoOrDefault<MobileInfo>())
|
||||||
.Where(mi => mi != null)
|
.Where(mi => mi != null)
|
||||||
.Select(mi => mi.Locomotor)
|
.Select(mi => mi.Locomotor)
|
||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
locomotors = world.WorldActor.TraitsImplementing<Locomotor>()
|
|
||||||
.Where(l => locomotorNames.Contains(l.Info.Name))
|
if (locomotorNames.Count != 0)
|
||||||
.ToArray();
|
locomotors = world.WorldActor.TraitsImplementing<Locomotor>()
|
||||||
|
.Where(l => locomotorNames.Contains(l.Info.Name))
|
||||||
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return locomotors;
|
return locomotors;
|
||||||
|
|||||||
Reference in New Issue
Block a user