Account for visibility when selecting AI superweapon targets.
This commit is contained in:
@@ -277,6 +277,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
PowerManager playerPower;
|
PowerManager playerPower;
|
||||||
SupportPowerManager supportPowerMngr;
|
SupportPowerManager supportPowerMngr;
|
||||||
PlayerResources playerResource;
|
PlayerResources playerResource;
|
||||||
|
FrozenActorLayer frozenLayer;
|
||||||
int ticks;
|
int ticks;
|
||||||
|
|
||||||
BitArray resourceTypeIndices;
|
BitArray resourceTypeIndices;
|
||||||
@@ -343,6 +344,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
playerPower = p.PlayerActor.Trait<PowerManager>();
|
playerPower = p.PlayerActor.Trait<PowerManager>();
|
||||||
supportPowerMngr = p.PlayerActor.Trait<SupportPowerManager>();
|
supportPowerMngr = p.PlayerActor.Trait<SupportPowerManager>();
|
||||||
playerResource = p.PlayerActor.Trait<PlayerResources>();
|
playerResource = p.PlayerActor.Trait<PlayerResources>();
|
||||||
|
frozenLayer = p.PlayerActor.Trait<FrozenActorLayer>();
|
||||||
|
|
||||||
foreach (var building in Info.BuildingQueues)
|
foreach (var building in Info.BuildingQueues)
|
||||||
builders.Add(new BaseBuilder(this, building, p, playerPower, playerResource));
|
builders.Add(new BaseBuilder(this, building, p, playerPower, playerResource));
|
||||||
@@ -1100,13 +1102,17 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
for (var j = 0; j < map.MapSize.Y; j += checkRadius)
|
for (var j = 0; j < map.MapSize.Y; j += checkRadius)
|
||||||
{
|
{
|
||||||
var consideredAttractiveness = 0;
|
var tl = new MPos(i, j);
|
||||||
|
var br = new MPos(i + checkRadius, j + checkRadius);
|
||||||
|
var region = new CellRegion(map.Grid.Type, tl, br);
|
||||||
|
|
||||||
var tl = World.Map.CenterOfCell(new MPos(i, j).ToCPos(map));
|
// HACK: The AI code should not be messing with raw coordinate transformations
|
||||||
var br = World.Map.CenterOfCell(new MPos(i + checkRadius, j + checkRadius).ToCPos(map));
|
var wtl = World.Map.CenterOfCell(tl.ToCPos(map));
|
||||||
var targets = World.ActorMap.ActorsInBox(tl, br);
|
var wbr = World.Map.CenterOfCell(br.ToCPos(map));
|
||||||
|
var targets = World.ActorMap.ActorsInBox(wtl, wbr);
|
||||||
|
|
||||||
consideredAttractiveness = powerDecision.GetAttractiveness(targets, Player);
|
var frozenTargets = frozenLayer.FrozenActorsInRegion(region);
|
||||||
|
var consideredAttractiveness = powerDecision.GetAttractiveness(targets, Player) + powerDecision.GetAttractiveness(frozenTargets, Player);
|
||||||
if (consideredAttractiveness <= bestAttractiveness || consideredAttractiveness < powerDecision.MinimumAttractiveness)
|
if (consideredAttractiveness <= bestAttractiveness || consideredAttractiveness < powerDecision.MinimumAttractiveness)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -1141,7 +1147,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var y = checkPos.Y + j;
|
var y = checkPos.Y + j;
|
||||||
var pos = World.Map.CenterOfCell(new CPos(x, y));
|
var pos = World.Map.CenterOfCell(new CPos(x, y));
|
||||||
var consideredAttractiveness = 0;
|
var consideredAttractiveness = 0;
|
||||||
consideredAttractiveness += powerDecision.GetAttractiveness(pos, Player);
|
consideredAttractiveness += powerDecision.GetAttractiveness(pos, Player, frozenLayer);
|
||||||
|
|
||||||
if (consideredAttractiveness <= bestAttractiveness || consideredAttractiveness < powerDecision.MinimumAttractiveness)
|
if (consideredAttractiveness <= bestAttractiveness || consideredAttractiveness < powerDecision.MinimumAttractiveness)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Evaluates the attractiveness of a position according to all considerations</summary>
|
/// <summary>Evaluates the attractiveness of a position according to all considerations</summary>
|
||||||
public int GetAttractiveness(WPos pos, Player firedBy)
|
public int GetAttractiveness(WPos pos, Player firedBy, FrozenActorLayer frozenLayer)
|
||||||
{
|
{
|
||||||
var answer = 0;
|
var answer = 0;
|
||||||
var world = firedBy.World;
|
var world = firedBy.World;
|
||||||
@@ -72,6 +72,16 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var checkActors = world.FindActorsInCircle(pos, radiusToUse);
|
var checkActors = world.FindActorsInCircle(pos, radiusToUse);
|
||||||
foreach (var scrutinized in checkActors)
|
foreach (var scrutinized in checkActors)
|
||||||
answer += consideration.GetAttractiveness(scrutinized, firedBy.Stances[scrutinized.Owner], firedBy);
|
answer += consideration.GetAttractiveness(scrutinized, firedBy.Stances[scrutinized.Owner], firedBy);
|
||||||
|
|
||||||
|
var delta = new WVec(radiusToUse, radiusToUse, WDist.Zero);
|
||||||
|
var tl = world.Map.CellContaining(pos - delta);
|
||||||
|
var br = world.Map.CellContaining(pos + delta);
|
||||||
|
var checkFrozen = frozenLayer.FrozenActorsInRegion(new CellRegion(world.Map.Grid.Type, tl, br));
|
||||||
|
|
||||||
|
// IsValid check filters out Frozen Actors that have not initizialized their Owner
|
||||||
|
foreach (var scrutinized in checkFrozen)
|
||||||
|
if (scrutinized.IsValid)
|
||||||
|
answer += consideration.GetAttractiveness(scrutinized, firedBy.Stances[scrutinized.Owner], firedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return answer;
|
return answer;
|
||||||
@@ -89,6 +99,18 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetAttractiveness(IEnumerable<FrozenActor> frozenActors, Player firedBy)
|
||||||
|
{
|
||||||
|
var answer = 0;
|
||||||
|
|
||||||
|
foreach (var consideration in Considerations)
|
||||||
|
foreach (var scrutinized in frozenActors)
|
||||||
|
if (scrutinized.IsValid && scrutinized.Visible)
|
||||||
|
answer += consideration.GetAttractiveness(scrutinized, firedBy.Stances[scrutinized.Owner], firedBy);
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetNextScanTime(HackyAI ai) { return ai.Random.Next(MinimumScanTimeInterval, MaximumScanTimeInterval); }
|
public int GetNextScanTime(HackyAI ai) { return ai.Random.Next(MinimumScanTimeInterval, MaximumScanTimeInterval); }
|
||||||
|
|
||||||
/// <summary>Makes up part of a decision, describing how to evaluate a target.</summary>
|
/// <summary>Makes up part of a decision, describing how to evaluate a target.</summary>
|
||||||
@@ -125,7 +147,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
if (a == null)
|
if (a == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!a.IsTargetableBy(firedBy.PlayerActor))
|
if (!a.IsTargetableBy(firedBy.PlayerActor) || !a.CanBeViewedByPlayer(firedBy))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (Types.Overlaps(a.GetEnabledTargetTypes()))
|
if (Types.Overlaps(a.GetEnabledTargetTypes()))
|
||||||
@@ -147,6 +169,34 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetAttractiveness(FrozenActor fa, Stance stance, Player firedBy)
|
||||||
|
{
|
||||||
|
if (stance != Against)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fa == null || !fa.IsValid || !fa.Visible)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (Types.Overlaps(fa.TargetTypes))
|
||||||
|
{
|
||||||
|
switch (TargetMetric)
|
||||||
|
{
|
||||||
|
case DecisionMetric.Value:
|
||||||
|
var valueInfo = fa.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
|
return (valueInfo != null) ? valueInfo.Cost * Attractiveness : 0;
|
||||||
|
|
||||||
|
case DecisionMetric.Health:
|
||||||
|
var healthInfo = fa.Info.TraitInfoOrDefault<HealthInfo>();
|
||||||
|
return (healthInfo != null) ? fa.HP * Attractiveness / healthInfo.HP : 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Attractiveness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user