Fix CaptureManagerBotModule crashing on multiple Capturable

By removing the now-redundant CaptureTarget class.
This commit is contained in:
reaperrr
2019-01-27 16:47:26 +01:00
committed by Paul Chote
parent 3093f67427
commit 32a3caf423
2 changed files with 14 additions and 50 deletions

View File

@@ -20,23 +20,6 @@ namespace OpenRA.Mods.Common
public enum WaterCheck { NotChecked, EnoughWater, NotEnoughWater } public enum WaterCheck { NotChecked, EnoughWater, NotEnoughWater }
public class CaptureTarget<TInfoType> where TInfoType : class, ITraitInfoInterface
{
internal readonly Actor Actor;
internal readonly TInfoType Info;
/// <summary>The order string given to the capturer so they can capture this actor.</summary>
/// <example>ExternalCaptureActor</example>
internal readonly string OrderString;
internal CaptureTarget(Actor actor, string orderString)
{
Actor = actor;
Info = actor.Info.TraitInfoOrDefault<TInfoType>();
OrderString = orderString;
}
}
public static class AIUtils public static class AIUtils
{ {
public static bool IsAreaAvailable<T>(World world, Player player, Map map, int radius, HashSet<string> terrainTypes) public static bool IsAreaAvailable<T>(World world, Player player, Map map, int radius, HashSet<string> terrainTypes)

View File

@@ -124,7 +124,7 @@ namespace OpenRA.Mods.Common.Traits
.Where(a => a.Owner == player && !activeCapturers.Contains(a)); .Where(a => a.Owner == player && !activeCapturers.Contains(a));
var capturers = newUnits var capturers = newUnits
.Where(a => a.IsIdle && Info.CapturingActorTypes.Contains(a.Info.Name)) .Where(a => a.IsIdle && Info.CapturingActorTypes.Contains(a.Info.Name) && a.Info.HasTraitInfo<CapturesInfo>())
.Select(a => new TraitPair<CaptureManager>(a, a.TraitOrDefault<CaptureManager>())) .Select(a => new TraitPair<CaptureManager>(a, a.TraitOrDefault<CaptureManager>()))
.Where(tp => tp.Trait != null) .Where(tp => tp.Trait != null)
.ToArray(); .ToArray();
@@ -140,52 +140,33 @@ namespace OpenRA.Mods.Common.Traits
: GetActorsThatCanBeOrderedByPlayer(randPlayer); : GetActorsThatCanBeOrderedByPlayer(randPlayer);
var capturableTargetOptions = targetOptions var capturableTargetOptions = targetOptions
.Select(a => new CaptureTarget<CapturableInfo>(a, "CaptureActor"))
.Where(target => .Where(target =>
{ {
if (target.Info == null) var captureManager = target.TraitOrDefault<CaptureManager>();
return false;
var captureManager = target.Actor.TraitOrDefault<CaptureManager>();
if (captureManager == null) if (captureManager == null)
return false; return false;
return capturers.Any(tp => captureManager.CanBeTargetedBy(target.Actor, tp.Actor, tp.Trait)); return capturers.Any(tp => captureManager.CanBeTargetedBy(target, tp.Actor, tp.Trait));
}) })
.OrderByDescending(target => target.Actor.GetSellValue()) .OrderByDescending(target => target.GetSellValue())
.Take(maximumCaptureTargetOptions); .Take(maximumCaptureTargetOptions);
if (Info.CapturableActorTypes.Any()) if (Info.CapturableActorTypes.Any())
capturableTargetOptions = capturableTargetOptions.Where(target => Info.CapturableActorTypes.Contains(target.Actor.Info.Name.ToLowerInvariant())); capturableTargetOptions = capturableTargetOptions.Where(target => Info.CapturableActorTypes.Contains(target.Info.Name.ToLowerInvariant()));
if (!capturableTargetOptions.Any()) if (!capturableTargetOptions.Any())
return; return;
var capturesCapturers = capturers.Where(tp => tp.Actor.Info.HasTraitInfo<CapturesInfo>()); foreach (var capturer in capturers)
foreach (var tp in capturesCapturers) {
QueueCaptureOrderFor(bot, tp.Actor, GetCapturerTargetClosestToOrDefault(tp.Actor, capturableTargetOptions)); var targetActor = capturableTargetOptions.MinByOrDefault(target => (target.CenterPosition - capturer.Actor.CenterPosition).LengthSquared);
} if (targetActor == null)
continue;
void QueueCaptureOrderFor<TTargetType>(IBot bot, Actor capturer, CaptureTarget<TTargetType> target) where TTargetType : class, ITraitInfoInterface bot.QueueOrder(new Order("CaptureActor", capturer.Actor, Target.FromActor(targetActor), true));
{ AIUtils.BotDebug("AI ({0}): Ordered {1} to capture {2}", player.ClientIndex, capturer.Actor, targetActor);
if (capturer == null) activeCapturers.Add(capturer.Actor);
return; }
if (target == null)
return;
if (target.Actor == null)
return;
bot.QueueOrder(new Order(target.OrderString, capturer, Target.FromActor(target.Actor), true));
AIUtils.BotDebug("AI ({0}): Ordered {1} to capture {2}", player.ClientIndex, capturer, target.Actor);
activeCapturers.Add(capturer);
}
CaptureTarget<TTargetType> GetCapturerTargetClosestToOrDefault<TTargetType>(Actor capturer, IEnumerable<CaptureTarget<TTargetType>> targets)
where TTargetType : class, ITraitInfoInterface
{
return targets.MinByOrDefault(target => (target.Actor.CenterPosition - capturer.CenterPosition).LengthSquared);
} }
} }
} }