HackyAI can now build buildings with new MCV

There was an issue where HackyAI would try to build buildings
at old base location and would fail, unless it was placed at the
same place where the old MCV was.
This commit is contained in:
Saulius Menkevičius
2015-03-11 18:27:13 +02:00
parent f5535c00a2
commit e1fa6af954
2 changed files with 25 additions and 11 deletions

View File

@@ -143,12 +143,24 @@ namespace OpenRA.Mods.Common.AI
{ {
public MersenneTwister Random { get; private set; } public MersenneTwister Random { get; private set; }
public readonly HackyAIInfo Info; public readonly HackyAIInfo Info;
public CPos BaseCenter { get; private set; }
public CPos GetRandomBaseCenter()
{
var randomBaseBuilding = World.Actors.Where(
a => a.Owner == Player
&& a.HasTrait<BaseBuilding>()
&& !a.HasTrait<Mobile>())
.RandomOrDefault(Random);
return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter;
}
public Player Player { get; private set; } public Player Player { get; private set; }
Dictionary<SupportPowerInstance, int> waitingPowers = new Dictionary<SupportPowerInstance, int>(); Dictionary<SupportPowerInstance, int> waitingPowers = new Dictionary<SupportPowerInstance, int>();
Dictionary<string, SupportPowerDecision> powerDecisions = new Dictionary<string, SupportPowerDecision>(); Dictionary<string, SupportPowerDecision> powerDecisions = new Dictionary<string, SupportPowerDecision>();
CPos initialBaseCenter;
PowerManager playerPower; PowerManager playerPower;
SupportPowerManager supportPowerMngr; SupportPowerManager supportPowerMngr;
PlayerResources playerResource; PlayerResources playerResource;
@@ -352,6 +364,8 @@ namespace OpenRA.Mods.Common.AI
return null; return null;
}; };
var baseCenter = GetRandomBaseCenter();
switch (type) switch (type)
{ {
case BuildingType.Defense: case BuildingType.Defense:
@@ -360,28 +374,28 @@ namespace OpenRA.Mods.Common.AI
var closestEnemy = World.Actors.Where(a => !a.Destroyed && a.HasTrait<Building>() && Player.Stances[a.Owner] == Stance.Enemy) var closestEnemy = World.Actors.Where(a => !a.Destroyed && a.HasTrait<Building>() && Player.Stances[a.Owner] == Stance.Enemy)
.ClosestTo(World.Map.CenterOfCell(defenseCenter)); .ClosestTo(World.Map.CenterOfCell(defenseCenter));
var targetCell = closestEnemy != null ? closestEnemy.Location : BaseCenter; var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
return findPos(defenseCenter, targetCell, Info.MinimumDefenseRadius, Info.MaximumDefenseRadius); return findPos(defenseCenter, targetCell, Info.MinimumDefenseRadius, Info.MaximumDefenseRadius);
case BuildingType.Refinery: case BuildingType.Refinery:
// Try and place the refinery near a resource field // Try and place the refinery near a resource field
var nearbyResources = Map.FindTilesInCircle(BaseCenter, Info.MaxBaseRadius) var nearbyResources = Map.FindTilesInCircle(baseCenter, Info.MaxBaseRadius)
.Where(a => resourceTypeIndices.Get(Map.GetTerrainIndex(a))) .Where(a => resourceTypeIndices.Get(Map.GetTerrainIndex(a)))
.Shuffle(Random); .Shuffle(Random);
foreach (var c in nearbyResources) foreach (var c in nearbyResources)
{ {
var found = findPos(c, BaseCenter, 0, Info.MaxBaseRadius); var found = findPos(c, baseCenter, 0, Info.MaxBaseRadius);
if (found != null) if (found != null)
return found; return found;
} }
// Try and find a free spot somewhere else in the base // Try and find a free spot somewhere else in the base
return findPos(BaseCenter, BaseCenter, 0, Info.MaxBaseRadius); return findPos(baseCenter, baseCenter, 0, Info.MaxBaseRadius);
case BuildingType.Building: case BuildingType.Building:
return findPos(BaseCenter, BaseCenter, 0, distanceToBaseIsImportant ? Info.MaxBaseRadius : Map.MaxTilesInCircleRange); return findPos(baseCenter, baseCenter, 0, distanceToBaseIsImportant ? Info.MaxBaseRadius : Map.MaxTilesInCircleRange);
} }
// Can't find a build location // Can't find a build location
@@ -430,7 +444,7 @@ namespace OpenRA.Mods.Common.AI
// Pick something worth attacking owned by that player // Pick something worth attacking owned by that player
var target = World.Actors var target = World.Actors
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>()) .Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>())
.ClosestTo(World.Map.CenterOfCell(BaseCenter)); .ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter()));
if (target == null) if (target == null)
{ {
@@ -638,7 +652,7 @@ namespace OpenRA.Mods.Common.AI
if (!protectSq.IsValid) if (!protectSq.IsValid)
{ {
var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(BaseCenter), WRange.FromCells(Info.ProtectUnitScanRadius)) var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(GetRandomBaseCenter()), WRange.FromCells(Info.ProtectUnitScanRadius))
.Where(unit => unit.Owner == Player && !unit.HasTrait<Building>() .Where(unit => unit.Owner == Player && !unit.HasTrait<Building>()
&& unit.HasTrait<AttackBase>()); && unit.HasTrait<AttackBase>());
@@ -685,8 +699,8 @@ namespace OpenRA.Mods.Common.AI
if (mcv != null) if (mcv != null)
{ {
BaseCenter = mcv.Location; initialBaseCenter = mcv.Location;
defenseCenter = BaseCenter; defenseCenter = mcv.Location;
// Don't transform the mcv if it is a fact // Don't transform the mcv if it is a fact
// HACK: This needs to query against MCVs directly // HACK: This needs to query against MCVs directly

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.AI
protected static CPos RandomBuildingLocation(Squad squad) protected static CPos RandomBuildingLocation(Squad squad)
{ {
var location = squad.Bot.BaseCenter; var location = squad.Bot.GetRandomBaseCenter();
var buildings = squad.World.ActorsWithTrait<Building>() var buildings = squad.World.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == squad.Bot.Player).Select(a => a.Actor).ToList(); .Where(a => a.Actor.Owner == squad.Bot.Player).Select(a => a.Actor).ToList();
if (buildings.Count > 0) if (buildings.Count > 0)