Fix CaptureManagerBotModule crashing on multiple Capturable
By removing the now-redundant CaptureTarget class.
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user