Fixed AI BaseBuilder low power check.
This was extremely borked: The priority overrides for refinery, production and silo ignored power completely and never checked whether the structure might drive the AI into low power state; whereas the check for regular building checked whether the structure's power -exceeded- MinimumExcessPower (previously just 0). The catch is that power draw is represented by negative numbers, so the only buildings that would trigger this were - power plants. Now it checks whether the sum of building power draw (negative) and AI's current power level are lower than MinimumExcessPower, if not, build the structure, if yes, build a power plant instead. Additionally, this check is now performed for the early-game priority overrides as well. Last but not least the AI would not(!) give power plants priority if it was already low on power. This has been fixed as well.
This commit is contained in:
@@ -130,56 +130,79 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
return available.RandomOrDefault(ai.Random);
|
return available.RandomOrDefault(ai.Random);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasSufficientPowerForActor(ActorInfo actorInfo)
|
||||||
|
{
|
||||||
|
return (actorInfo.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1)
|
||||||
|
.Sum(p => p.Amount) + playerPower.ExcessPower) >= ai.Info.MinimumExcessPower;
|
||||||
|
}
|
||||||
|
|
||||||
ActorInfo ChooseBuildingToBuild(ProductionQueue queue)
|
ActorInfo ChooseBuildingToBuild(ProductionQueue queue)
|
||||||
{
|
{
|
||||||
var buildableThings = queue.BuildableItems();
|
var buildableThings = queue.BuildableItems();
|
||||||
|
|
||||||
|
// This gets used quite a bit, so let's cache it here
|
||||||
|
var power = GetProducibleBuilding("Power", buildableThings,
|
||||||
|
a => a.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount));
|
||||||
|
|
||||||
// First priority is to get out of a low power situation
|
// First priority is to get out of a low power situation
|
||||||
if (playerPower.ExcessPower < ai.Info.MinimumExcessPower)
|
if (playerPower.ExcessPower < ai.Info.MinimumExcessPower)
|
||||||
{
|
{
|
||||||
var power = GetProducibleBuilding("Power", buildableThings, a => a.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount));
|
|
||||||
if (power != null && power.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount) > 0)
|
if (power != null && power.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount) > 0)
|
||||||
{
|
|
||||||
// TODO: Handle the case when of when we actually do need a power plant because we don't have enough but are also suffering from a power outage
|
|
||||||
if (playerPower.PowerOutageRemainingTicks <= 0)
|
|
||||||
{
|
{
|
||||||
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (low power)", queue.Actor.Owner, power.Name);
|
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (low power)", queue.Actor.Owner, power.Name);
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Next is to build up a strong economy
|
// Next is to build up a strong economy
|
||||||
if (!ai.HasAdequateProc() || !ai.HasMinimumProc())
|
if (!ai.HasAdequateProc() || !ai.HasMinimumProc())
|
||||||
{
|
{
|
||||||
var refinery = GetProducibleBuilding("Refinery", buildableThings);
|
var refinery = GetProducibleBuilding("Refinery", buildableThings);
|
||||||
if (refinery != null)
|
if (refinery != null && HasSufficientPowerForActor(refinery))
|
||||||
{
|
{
|
||||||
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (refinery)", queue.Actor.Owner, refinery.Name);
|
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (refinery)", queue.Actor.Owner, refinery.Name);
|
||||||
return refinery;
|
return refinery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (power != null && refinery != null && !HasSufficientPowerForActor(refinery))
|
||||||
|
{
|
||||||
|
HackyAI.BotDebug("{0} decided to build {1}: Priority override (would be low power)", queue.Actor.Owner, power.Name);
|
||||||
|
return power;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that we can can spend as fast as we are earning
|
// Make sure that we can can spend as fast as we are earning
|
||||||
if (ai.Info.NewProductionCashThreshold > 0 && playerResources.Resources > ai.Info.NewProductionCashThreshold)
|
if (ai.Info.NewProductionCashThreshold > 0 && playerResources.Resources > ai.Info.NewProductionCashThreshold)
|
||||||
{
|
{
|
||||||
var production = GetProducibleBuilding("Production", buildableThings);
|
var production = GetProducibleBuilding("Production", buildableThings);
|
||||||
if (production != null)
|
if (production != null && HasSufficientPowerForActor(production))
|
||||||
{
|
{
|
||||||
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (production)", queue.Actor.Owner, production.Name);
|
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (production)", queue.Actor.Owner, production.Name);
|
||||||
return production;
|
return production;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (power != null && production != null && !HasSufficientPowerForActor(production))
|
||||||
|
{
|
||||||
|
HackyAI.BotDebug("{0} decided to build {1}: Priority override (would be low power)", queue.Actor.Owner, power.Name);
|
||||||
|
return power;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create some head room for resource storage if we really need it
|
// Create some head room for resource storage if we really need it
|
||||||
if (playerResources.AlertSilo)
|
if (playerResources.AlertSilo)
|
||||||
{
|
{
|
||||||
var silo = GetProducibleBuilding("Silo", buildableThings);
|
var silo = GetProducibleBuilding("Silo", buildableThings);
|
||||||
if (silo != null)
|
if (silo != null && HasSufficientPowerForActor(silo))
|
||||||
{
|
{
|
||||||
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (silo)", queue.Actor.Owner, silo.Name);
|
HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (silo)", queue.Actor.Owner, silo.Name);
|
||||||
return silo;
|
return silo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (power != null && silo != null && !HasSufficientPowerForActor(silo))
|
||||||
|
{
|
||||||
|
HackyAI.BotDebug("{0} decided to build {1}: Priority override (would be low power)", queue.Actor.Owner, power.Name);
|
||||||
|
return power;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build everything else
|
// Build everything else
|
||||||
@@ -200,25 +223,20 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Will this put us into low power?
|
// Will this put us into low power?
|
||||||
var actor = world.Map.Rules.Actors[frac.Key];
|
var actor = world.Map.Rules.Actors[name];
|
||||||
var pis = actor.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1);
|
if (playerPower.ExcessPower < ai.Info.MinimumExcessPower || !HasSufficientPowerForActor(actor))
|
||||||
if (playerPower.ExcessPower < ai.Info.MinimumExcessPower || playerPower.ExcessPower < pis.Sum(pi => pi.Amount))
|
|
||||||
{
|
{
|
||||||
// Try building a power plant instead
|
// Try building a power plant instead
|
||||||
var power = GetProducibleBuilding("Power",
|
|
||||||
buildableThings, a => a.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(pi => pi.Amount));
|
|
||||||
if (power != null && power.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(pi => pi.Amount) > 0)
|
if (power != null && power.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(pi => pi.Amount) > 0)
|
||||||
{
|
{
|
||||||
// TODO: Handle the case when of when we actually do need a power plant because we don't have enough but are also suffering from a power outage
|
|
||||||
if (playerPower.PowerOutageRemainingTicks > 0)
|
if (playerPower.PowerOutageRemainingTicks > 0)
|
||||||
HackyAI.BotDebug("AI: {0} is suffering from a power outage; not going to build {1}", queue.Actor.Owner, power.Name);
|
HackyAI.BotDebug("{0} decided to build {1}: Priority override (is low power)", queue.Actor.Owner, power.Name);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
HackyAI.BotDebug("{0} decided to build {1}: Priority override (would be low power)", queue.Actor.Owner, power.Name);
|
HackyAI.BotDebug("{0} decided to build {1}: Priority override (would be low power)", queue.Actor.Owner, power.Name);
|
||||||
|
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Lets build this
|
// Lets build this
|
||||||
HackyAI.BotDebug("{0} decided to build {1}: Desired is {2} ({3} / {4}); current is {5} / {4}",
|
HackyAI.BotDebug("{0} decided to build {1}: Desired is {2} ({3} / {4}); current is {5} / {4}",
|
||||||
|
|||||||
Reference in New Issue
Block a user