Account for visibility when selecting AI superweapon targets.

This commit is contained in:
Paul Chote
2017-12-10 16:58:48 +00:00
committed by abcdefg30
parent 9dc330b300
commit 2ad42b6a7e
2 changed files with 64 additions and 8 deletions

View File

@@ -277,6 +277,7 @@ namespace OpenRA.Mods.Common.AI
PowerManager playerPower;
SupportPowerManager supportPowerMngr;
PlayerResources playerResource;
FrozenActorLayer frozenLayer;
int ticks;
BitArray resourceTypeIndices;
@@ -343,6 +344,7 @@ namespace OpenRA.Mods.Common.AI
playerPower = p.PlayerActor.Trait<PowerManager>();
supportPowerMngr = p.PlayerActor.Trait<SupportPowerManager>();
playerResource = p.PlayerActor.Trait<PlayerResources>();
frozenLayer = p.PlayerActor.Trait<FrozenActorLayer>();
foreach (var building in Info.BuildingQueues)
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)
{
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));
var br = World.Map.CenterOfCell(new MPos(i + checkRadius, j + checkRadius).ToCPos(map));
var targets = World.ActorMap.ActorsInBox(tl, br);
// HACK: The AI code should not be messing with raw coordinate transformations
var wtl = World.Map.CenterOfCell(tl.ToCPos(map));
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)
continue;
@@ -1141,7 +1147,7 @@ namespace OpenRA.Mods.Common.AI
var y = checkPos.Y + j;
var pos = World.Map.CenterOfCell(new CPos(x, y));
var consideredAttractiveness = 0;
consideredAttractiveness += powerDecision.GetAttractiveness(pos, Player);
consideredAttractiveness += powerDecision.GetAttractiveness(pos, Player, frozenLayer);
if (consideredAttractiveness <= bestAttractiveness || consideredAttractiveness < powerDecision.MinimumAttractiveness)
continue;

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.AI
}
/// <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 world = firedBy.World;
@@ -72,6 +72,16 @@ namespace OpenRA.Mods.Common.AI
var checkActors = world.FindActorsInCircle(pos, radiusToUse);
foreach (var scrutinized in checkActors)
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;
@@ -89,6 +99,18 @@ namespace OpenRA.Mods.Common.AI
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); }
/// <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)
return 0;
if (!a.IsTargetableBy(firedBy.PlayerActor))
if (!a.IsTargetableBy(firedBy.PlayerActor) || !a.CanBeViewedByPlayer(firedBy))
return 0;
if (Types.Overlaps(a.GetEnabledTargetTypes()))
@@ -147,6 +169,34 @@ namespace OpenRA.Mods.Common.AI
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;
}
}
}
}