Correct and add comments for expansion related

This commit is contained in:
dnqbob
2025-10-15 23:19:18 +08:00
committed by Gustas Kažukauskas
parent 1c693a2c4b
commit ea775ab824
3 changed files with 31 additions and 17 deletions

View File

@@ -58,8 +58,7 @@ namespace OpenRA.Mods.Common.Traits
public void Tick(IBot bot, ILookup<string, ProductionQueue> queuesByCategory)
{
// If failed to place something N consecutive times, we will try move the MCV
// If it is possible.
// If we can't place any structures, give a nudge to BaseExpansionModules and hope it gets fixed.
if (failCount >= baseBuilder.Info.MaximumFailedPlacementAttempts)
{
if (baseBuilder.BaseExpansionModules != null && baseCenterKeepsFailing != null)
@@ -77,7 +76,8 @@ namespace OpenRA.Mods.Common.Traits
failCount = 0;
}
// Otherwise, only bother resetting failCount if either a) the number of buildings has decreased since last failure M ticks ago,
// No BaseExpansionModules exist. Only bother resetting failCount when either
// a) the number of buildings has decreased since last failure M ticks ago,
// or b) number of BaseProviders (construction yard or similar) has increased since then.
// Otherwise reset failRetryTicks instead to wait again.
else if (baseBuilder.BaseExpansionModules == null && --failRetryTicks <= 0)
@@ -232,6 +232,8 @@ namespace OpenRA.Mods.Common.Traits
SuppressVisualFeedback = true
});
// After succesfuly placing a building, nudge BaseExpansionModules to expand.
// We want to avoid expanding too often, so we make a judgement by counting buildings.
if (baseBuilder.Info.ProductionTypes.Contains(currentBuilding.Item)
|| baseBuilder.Info.TechTypes.Contains(currentBuilding.Item) || baseBuilder.Info.RefineryTypes.Contains(currentBuilding.Item))
{
@@ -541,25 +543,35 @@ namespace OpenRA.Mods.Common.Traits
// Try and place the refinery near a resource field
if (resourceLayer != null)
{
// If we have failed to place to the best refinery point, try and place it near the base center
var resourceBaseCenter = failCount > 0 ? baseCenter : (requestRef != null ?
baseBuilder.RequestedRefineries[requestRef].ConyardLoc : (baseBuilder.ResourceConyardCenter ?? baseCenter));
// If we have failed to place to the requested refinery point, try and place it near the base center
var resourceBaseCenter = failCount > 0 ? baseCenter :
(requestRef != null ? baseBuilder.RequestedRefineries[requestRef].ConyardLoc : (baseBuilder.ResourceConyardCenter ?? baseCenter));
// If we have a ResourceMapModule, only consider the resource types it considers valuable
// Otherwise consider any resource type
var nearbyResources = world.Map
.FindTilesInAnnulus(resourceBaseCenter, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius)
.Where(c => baseBuilder.ResourceMapModule != null ?
baseBuilder.ResourceMapModule.Info.ValuableResourceTypes.Contains(resourceLayer.GetResource(c).Type)
: resourceLayer.GetResource(c).Type != null);
// Find the closest refinery we have if we have any when not failing to place for the first time
var closestRefinery = failCount <= 0
? baseBuilder.RefineryBuildings.Actors.Where(a => !a.IsDead)?.ClosestToIgnoringPath(world.Map.CenterOfCell(resourceBaseCenter))
: null;
var resourcesShouldCheck = closestRefinery == null ?
nearbyResources.Shuffle(world.LocalRandom) :
(requestRef != null ? nearbyResources.OrderBy(c => (c - baseBuilder.RequestedRefineries[requestRef].ResourceLoc).LengthSquared)
: nearbyResources.OrderByDescending(c => (c - closestRefinery.Location).LengthSquared))
.Take(baseBuilder.Info.MaxResourceCellsToCheck);
IEnumerable<CPos> resourcesShouldCheck = null;
if (closestRefinery == null)
resourcesShouldCheck = nearbyResources.Shuffle(world.LocalRandom).Take(baseBuilder.Info.MaxResourceCellsToCheck);
else if (requestRef != null)
{
resourcesShouldCheck = nearbyResources.OrderBy(c => (c - baseBuilder.RequestedRefineries[requestRef].ResourceLoc).LengthSquared)
.Take(baseBuilder.Info.MaxResourceCellsToCheck);
}
else
resourcesShouldCheck = nearbyResources.OrderByDescending(c => (c - closestRefinery.Location).LengthSquared)
.Take(baseBuilder.Info.MaxResourceCellsToCheck);
foreach (var r in resourcesShouldCheck)
{

View File

@@ -193,9 +193,11 @@ namespace OpenRA.Mods.Common.Traits
var worstEffectHarvesterCount = int.MaxValue;
var lackHarvesterIndices = new List<(int Attraction, int LackHarvs, CPos ResoueceCenter)>();
/*
* indiceSideLengthSquare (which is equal to indiceSideLength * indiceSideLength) is used as the basic unit to calculate the attraction of a candidate,
* we compare the attraction on the same scale on different factors, such as candidate's distance to current MCV and ally construction yard & refinery within range, etc:
* we compare the attraction on the same scale on different factors, such as ally refinery within range or threats nearby.
* Note: this function requires an enabled resourceMapModule.
*/
var indiceSideLengthSquare = resourceMapModule.GetIndiceSideLength() * resourceMapModule.GetIndiceSideLength();

View File

@@ -290,7 +290,7 @@ namespace OpenRA.Mods.Common.Traits
*
* 2). the weight of friendly construction yard within range: -indiceSideLengthSquare. If it belongs to an ally, -indiceSideLengthSquare/2.
*
* 3). the weight of enemy high threat within range: -indiceSideLengthSquare*8, otherwise -indiceSideLengthSquare/64
* 3). the weight of enemy within range: -indiceSideLengthSquare*8 for base building, otherwise -indiceSideLengthSquare/64
*
* 4). the weight of friendly refinery within range (not for CheckBase mode): -indiceSideLengthSquare. If it belongs to an ally, -indiceSideLengthSquare/2.
*
@@ -312,7 +312,7 @@ namespace OpenRA.Mods.Common.Traits
{
/*
* CheckBase mode only considers the distance to current MCV, ally construction yard within range and enemy buildings within range.
* Attaction has a base value of indiceSideLengthSquare >> 3 (1/8 of the maximum distance weight, 1/(2*sqrt(2)) 1/2.8 of the maximum distance in map)
* Attaction has a base value of indiceSideLengthSquare >> 1 (1/2 of the maximum distance weight, 1/ sqrt(2) 1/1.4 of maximum euclid distance in map)
*/
case BotMcvExpansionMode.CheckBase:
var cb_conyardlocs = world.ActorsHavingTrait<Building>()
@@ -374,8 +374,8 @@ namespace OpenRA.Mods.Common.Traits
/*
* CheckResource mode considers the distance to current MCV, ally construction yard & refinery within range,
* Attaction has a base value of:
* 1. if not Mobile: indiceSideLengthSquare >> 4 (1/16 of the maximum distance weight, = 0.25 of the maximum euclid distance in map)
* 2. if Mobile: indiceSideLengthSquare >> 3 (1/8 of the maximum distance weight, 0.35 of the maximum euclid distance in map)
* 1. if not Mobile: indiceSideLengthSquare >> 2 (1/4 of the maximum distance weight, = 0.5 of the maximum euclid distance in map)
* 2. if Mobile: indiceSideLengthSquare >> 1 (1/2 of the maximum distance weight, 0.71 of the maximum euclid distance in map)
*/
case BotMcvExpansionMode.CheckResource:
@@ -389,7 +389,7 @@ namespace OpenRA.Mods.Common.Traits
.Select(a => (a.Location, a.Owner != player))
.ToArray();
// We only take indice has more than half of average indice value (in weight calculation), to skip the indice with very poor resource
// We only take indice has more than the half of average indice value (in weight calculation), to skip the indice with very poor resource
// when failedAttempts is acceptable.
var thresholdRes = 0;
for (var i = 0; i < resourceMapModule.GetIndicesLength(); i++)