Account for visibility when selecting AI superweapon targets.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user