Page MenuHomeWildfire Games

Petra: add a function to test AI chats
Needs ReviewPublic

Authored by mimo on Mar 12 2018, 7:08 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

for D1265 (and future), it would be useful to have a way to test easily the AI chats messages.
This patch adds a function which displays all AI messages, with a new variation every about 15s.

The function itself is not used in game, so can be commited if it solves Gallaceo needs.
The way to call it (i.e. call the function from headquarters::update) will still have to be done manually when needed.

As the numbers of messages is important, they are separated in 2 parts, given by the second argument of the function.

PS the "about 15s" delay could be added as a third argument of the function if that's too short.

Test Plan

Check that it works for D1265

Diff Detail

Repository
rP 0 A.D. Public Repository
Branch
/ps/trunk
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 5522
Build 9319: Vulcan BuildJenkins
Build 9318: arc lint + arc unit

Event Timeline

Vulcan added a subscriber: Vulcan.Mar 12 2018, 10:45 PM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 218| 218| 	}
| 219| 219| 
| 220| 220| 	for (let evt of events.Destroy)
| 221|    |-	{
|    | 221|+	
| 222| 222| 		// Let's check we haven't lost an important building here.
| 223| 223| 		if (evt && !evt.SuccessfulFoundation && evt.entityObj && evt.metadata && evt.metadata[PlayerID] &&
| 224| 224| 			evt.metadata[PlayerID].base)
| 235| 235| 			if (evt.metadata[PlayerID].baseAnchor && evt.metadata[PlayerID].baseAnchor === true)
| 236| 236| 				base.anchorLost(gameState, ent);
| 237| 237| 		}
| 238|    |-	}
|    | 238|+	
| 239| 239| 
| 240| 240| 	for (let evt of events.EntityRenamed)
| 241| 241| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 264| 264| 			// Let's get a few units from other bases there to build this.
| 265| 265| 			let builders = this.bulkPickWorkers(gameState, newbase, 10);
| 266| 266| 			if (builders !== false)
| 267|    |-			{
|    | 267|+			
| 268| 268| 				builders.forEach(worker => {
| 269| 269| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 270| 270| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 271| 271| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 272| 272| 				});
| 273|    |-			}
|    | 273|+			
| 274| 274| 		}
| 275| 275| 		else if (ent.getMetadata(PlayerID, "base") == -2)	// anchorless base around a dock
| 276| 276| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 278| 278| 			// Let's get a few units from other bases there to build this.
| 279| 279| 			let builders = this.bulkPickWorkers(gameState, newbase, 4);
| 280| 280| 			if (builders != false)
| 281|    |-			{
|    | 281|+			
| 282| 282| 				builders.forEach(worker => {
| 283| 283| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 284| 284| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 285| 285| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 286| 286| 				});
| 287|    |-			}
|    | 287|+			
| 288| 288| 		}
| 289| 289| 	}
| 290| 290| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 404| 404| 	}
| 405| 405| 
| 406| 406| 	for (let evt of events.TrainingFinished)
| 407|    |-	{
|    | 407|+	
| 408| 408| 		for (let entId of evt.entities)
| 409| 409| 		{
| 410| 410| 			let ent = gameState.getEntityById(entId);
| 472| 472| 					ent.moveToRange(goal[0], goal[1]);
| 473| 473| 			}
| 474| 474| 		}
| 475|    |-	}
|    | 475|+	
| 476| 476| 
| 477| 477| 	for (let evt of events.TerritoryDecayChanged)
| 478| 478| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 420| 420| 					this.garrisonManager.registerHolder(gameState, holder);
| 421| 421| 			}
| 422| 422| 			else if (ent.getMetadata(PlayerID, "garrisonType"))
| 423|    |-			{
|    | 423|+			
| 424| 424| 				// we were supposed to be autogarrisoned, but this has failed (may-be full)
| 425| 425| 				ent.setMetadata(PlayerID, "garrisonType", undefined);
| 426|    |-			}
|    | 426|+			
| 427| 427| 
| 428| 428| 			// Check if this unit is no more needed in its attack plan
| 429| 429| 			// (happen when the training ends after the attack is started or aborted)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 491| 491| 	}
| 492| 492| 
| 493| 493| 	if (addBase)
| 494|    |-	{
|    | 494|+	
| 495| 495| 		if (!this.firstBaseConfig)
| 496| 496| 		{
| 497| 497| 			// This is our first base, let us configure our starting resources
| 504| 504| 			this.saveSpace = undefined;
| 505| 505| 			this.maxFields = false;
| 506| 506| 		}
| 507|    |-	}
|    | 507|+	
| 508| 508| 
| 509| 509| 	// Then deals with decaying structures: destroy them if being lost to enemy (except in easier difficulties)
| 510| 510| 	if (this.Config.difficulty < 2)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 493| 493| 	if (addBase)
| 494| 494| 	{
| 495| 495| 		if (!this.firstBaseConfig)
| 496|    |-		{
|    | 496|+		
| 497| 497| 			// This is our first base, let us configure our starting resources
| 498| 498| 			this.configFirstBase(gameState);
| 499|    |-		}
|    | 499|+		
| 500| 500| 		else
| 501| 501| 		{
| 502| 502| 			// Let us hope this new base will fix our possible resource shortage
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 781| 781| 		let aValue = 0.1;
| 782| 782| 		let bValue = 0.1;
| 783| 783| 		for (let param of parameters)
| 784|    |-		{
|    | 784|+		
| 785| 785| 			if (param[0] == "strength")
| 786| 786| 			{
| 787| 787| 				aValue += m.getMaxStrength(a[1]) * param[1];
| 815| 815| 			}
| 816| 816| 			else
| 817| 817| 				API3.warn(" trainMoreUnits avec non prevu " + uneval(param));
| 818|    |-		}
|    | 818|+		
| 819| 819| 		return -aValue/aCost + bValue/bCost;
| 820| 820| 	});
| 821| 821| 	return units[0][0];
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 883| 883| 			base.getGatherRates(gameState, this.currentRates);
| 884| 884| 
| 885| 885| 		for (let res in this.currentRates)
| 886|    |-		{
|    | 886|+		
| 887| 887| 			if (this.currentRates[res] < 0)
| 888| 888| 			{
| 889| 889| 				if (this.Config.debug > 0)
| 890| 890| 					API3.warn("Petra: current rate for " + res + " < 0 with " + this.GetTCResGatherer(res) + " moved gatherers");
| 891| 891| 				this.currentRates[res] = 0;
| 892| 892| 			}
| 893|    |-		}
|    | 893|+		
| 894| 894| 		this.turnCache.gatherRates = true;
| 895| 895| 	}
| 896| 896| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1045|1045| 				continue;
|1046|1046| 
|1047|1047| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1048|    |-			{
|    |1048|+			
|1049|1049| 				if (!accessible)
|1050|1050| 				{
|1051|1051| 					if (minDist > maxNoAccessDisfavored)
|1055|1055| 				}
|1056|1056| 				else
|1057|1057| 					norm *= 0.5;
|1058|    |-			}
|    |1058|+			
|1059|1059| 
|1060|1060| 			// Not near any of our dropsite, except for oversea docks
|1061|1061| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1047|1047| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1048|1048| 			{
|1049|1049| 				if (!accessible)
|1050|    |-				{
|    |1050|+				
|1051|1051| 					if (minDist > maxNoAccessDisfavored)
|1052|1052| 						norm *= 0.5;
|1053|1053| 					else
|1054|1054| 						norm *= 0.8;
|1055|    |-				}
|    |1055|+				
|1056|1056| 				else
|1057|1057| 					norm *= 0.5;
|1058|1058| 			}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1060|1060| 			// Not near any of our dropsite, except for oversea docks
|1061|1061| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|1062|1062| 			if (!oversea)
|1063|    |-			{
|    |1063|+			
|1064|1064| 				for (let dp of dpList)
|1065|1065| 				{
|1066|1066| 					let dist = API3.SquareVectorDistance(dp.pos, pos);
|1072|1072| 					else if (dist < 6400)
|1073|1073| 						norm *= 0.5;
|1074|1074| 				}
|1075|    |-			}
|    |1075|+			
|1076|1076| 			if (norm == 0)
|1077|1077| 				continue;
|1078|1078| 		}
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1086|1086| 				val += gameState.sharedScript.ccResourceMaps[res].map[j];
|1087|1087| 		val *= norm;
|1088|1088| 
|1089|    |-		// If oversea, be just above threshold to be accepted if nothing else 
|    |1089|+		// If oversea, be just above threshold to be accepted if nothing else
|1090|1090| 		if (oversea)
|1091|1091| 			val = Math.max(val, cut + 0.1);
|1092|1092| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1372|1372| 	// do not keep it if gain is too small, except if this is our first BarterMarket
|1373|1373| 	let idx;
|1374|1374| 	if (expectedGain < this.tradeManager.minimalGain)
|1375|    |-	{
|    |1375|+	
|1376|1376| 		if (template.hasClass("BarterMarket") &&
|1377|1377| 		    !gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities())
|1378|1378| 			idx = -1;	// needed by queueplanBuilding manager to keep that market
|1379|1379| 		else
|1380|1380| 			return false;
|1381|    |-	}
|    |1381|+	
|1382|1382| 	else
|1383|1383| 		idx = this.basesMap.map[bestJdx];
|1384|1384| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1559|1559| 			let cost = queues.economicBuilding.plans[0].getCost();
|1560|1560| 			queueManager.setAccounts(gameState, cost, "economicBuilding");
|1561|1561| 			if (!queueManager.canAfford("economicBuilding", cost))
|1562|    |-			{
|    |1562|+			
|1563|1563| 				for (let q in queueManager.queues)
|1564|1564| 				{
|1565|1565| 					if (q == "economicBuilding")
|1568|1568| 					if (queueManager.canAfford("economicBuilding", cost))
|1569|1569| 						break;
|1570|1570| 				}
|1571|    |-			}
|    |1571|+			
|1572|1572| 		}
|1573|1573| 		return;
|1574|1574| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1618|1618| 		let highLevel = 0;
|1619|1619| 		let lowLevel = 0;
|1620|1620| 		for (let res in cost)
|1621|    |-		{
|    |1621|+		
|1622|1622| 			if (resources[res] && resources[res] > 0.7 * cost[res])
|1623|1623| 				++highLevel;
|1624|1624| 			else if (!resources[res] || resources[res] < 0.3 * cost[res])
|1625|1625| 				++lowLevel;
|1626|    |-		}
|    |1626|+		
|1627|1627| 		if (highLevel == 0 || lowLevel > 1)
|1628|1628| 			return;
|1629|1629| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1744|1744| 	let freeSlots = gameState.getPopulationLimit() + HouseNb*popBonus - this.getAccountedPopulation(gameState);
|1745|1745| 	let priority;
|1746|1746| 	if (freeSlots < 5)
|1747|    |-	{
|    |1747|+	
|1748|1748| 		if (this.buildManager.isUnbuildable(gameState, house))
|1749|1749| 		{
|1750|1750| 			if (this.Config.debug > 1)
|1753|1753| 		}
|1754|1754| 		else
|1755|1755| 			priority = 2*this.Config.priorities.house;
|1756|    |-	}
|    |1756|+	
|1757|1757| 	else
|1758|1758| 		priority = this.Config.priorities.house;
|1759|1759| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1835|1835| 		return;
|1836|1836| 
|1837|1837| 	if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3))))
|1838|    |-	{
|    |1838|+	
|1839|1839| 		// try to build fortresses
|1840|1840| 		if (this.canBuild(gameState, "structures/{civ}_fortress"))
|1841|1841| 		{
|1854|1854| 				return;
|1855|1855| 			}
|1856|1856| 		}
|1857|    |-	}
|    |1857|+	
|1858|1858| 
|1859|1859| 	if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower"))
|1860|1860| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1984|1984| 		nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true);
|1985|1985| 
|1986|1986| 	if (!nAdvanced || nAdvanced < this.bAdvanced.length && this.getAccountedPopulation(gameState) > 110)
|1987|    |-	{
|    |1987|+	
|1988|1988| 		for (let advanced of this.bAdvanced)
|1989|1989| 		{
|1990|1990| 			if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced))
|1999|1999| 				queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced));
|2000|2000| 			return;
|2001|2001| 		}
|2002|    |-	}
|    |2002|+	
|2003|2003| };
|2004|2004| 
|2005|2005| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2087|2087| 	// in which case we prefer melee units
|2088|2088| 	let numGarrisoned = this.garrisonManager.numberOfGarrisonedUnits(nearestAnchor);
|2089|2089| 	if (nearestAnchor._entity.trainingQueue)
|2090|    |-	{
|    |2090|+	
|2091|2091| 		for (let item of nearestAnchor._entity.trainingQueue)
|2092|2092| 		{
|2093|2093| 			if (item.metadata && item.metadata.garrisonType)
|2095|2095| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2096|2096| 				nearestAnchor.stopProduction(item.id);
|2097|2097| 		}
|2098|    |-	}
|    |2098|+	
|2099|2099| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2100|2100| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|2101|2101| 	let rangedWanted = randBool() && autogarrison;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2089|2089| 	if (nearestAnchor._entity.trainingQueue)
|2090|2090| 	{
|2091|2091| 		for (let item of nearestAnchor._entity.trainingQueue)
|2092|    |-		{
|    |2092|+		
|2093|2093| 			if (item.metadata && item.metadata.garrisonType)
|2094|2094| 				numGarrisoned += item.count;
|2095|2095| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2096|2096| 				nearestAnchor.stopProduction(item.id);
|2097|    |-		}
|    |2097|+		
|2098|2098| 	}
|2099|2099| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2100|2100| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2129|2129| 	let cost = new API3.Resources(templateFound[1].cost());
|2130|2130| 	queueManager.setAccounts(gameState, cost, "emergency");
|2131|2131| 	if (!queueManager.canAfford("emergency", cost))
|2132|    |-	{
|    |2132|+	
|2133|2133| 		for (let q in queueManager.queues)
|2134|2134| 		{
|2135|2135| 			if (q === "emergency")
|2138|2138| 			if (queueManager.canAfford("emergency", cost))
|2139|2139| 				break;
|2140|2140| 		}
|2141|    |-	}
|    |2141|+	
|2142|2142| 	let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() };
|2143|2143| 	if (autogarrison)
|2144|2144| 		metadata.garrisonType = "protection";
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2419|2419| m.HQ.prototype.assignGatherers = function()
|2420|2420| {
|2421|2421| 	for (let base of this.baseManagers)
|2422|    |-	{
|    |2422|+	
|2423|2423| 		for (let worker of base.workers.values())
|2424|2424| 		{
|2425|2425| 			if (worker.unitAIState().split(".")[1] !== "RETURNRESOURCE")
|2429|2429| 				continue;
|2430|2430| 			this.AddTCGatherer(orders[1].target);
|2431|2431| 		}
|2432|    |-	}
|    |2432|+	
|2433|2433| };
|2434|2434| 
|2435|2435| m.HQ.prototype.isDangerousLocation = function(gameState, pos, radius)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2599|2599| 	{
|2600|2600| 		let pop = gameState.getPopulation();
|2601|2601| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2602|    |-		{
|    |2602|+		
|2603|2603| 			for (let item of ent.trainingQueue())
|2604|2604| 			{
|2605|2605| 				if (!item.unitTemplate)
|2608|2608| 				if (unitPop)
|2609|2609| 					pop += item.count * unitPop;
|2610|2610| 			}
|2611|    |-		}
|    |2611|+		
|2612|2612| 		this.turnCache.accountedPopulation = pop;
|2613|2613| 	}
|2614|2614| 	return this.turnCache.accountedPopulation;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2623|2623| 	{
|2624|2624| 		let workers = gameState.getOwnEntitiesByRole("worker", true).length;
|2625|2625| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2626|    |-		{
|    |2626|+		
|2627|2627| 			for (let item of ent.trainingQueue())
|2628|2628| 			{
|2629|2629| 				if (!item.metadata || !item.metadata.role || item.metadata.role != "worker")
|2630|2630| 					continue;
|2631|2631| 				workers += item.count;
|2632|2632| 			}
|2633|    |-		}
|    |2633|+		
|2634|2634| 		this.turnCache.accountedWorkers = workers;
|2635|2635| 	}
|2636|2636| 	return this.turnCache.accountedWorkers;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 0.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2663|2663| 			this.phasing = 0;
|2664|2664| 	}
|2665|2665| 
|2666|    |-/*	if (this.Config.debug > 1)
|    |2666|+	/*	if (this.Config.debug > 1)
|2667|2667| 	{
|2668|2668| 		gameState.getOwnUnits().forEach (function (ent) {
|2669|2669| 			if (!ent.position())
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 0.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2737|2737| 		this.currentBase %= this.baseManagers.length;
|2738|2738| 		activeBase = this.baseManagers[this.currentBase++].update(gameState, queues, events);
|2739|2739| 		--nbBases;
|2740|    |-// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|    |2740|+		// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|2741|2741| 	}
|2742|2742| 	while (!activeBase && nbBases != 0);
|2743|2743| 

binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 533| »   »   »   let·ratioMax·=·0.70·+·randFloat(0.,·0.1);
|    | [NORMAL] JSHintBear:
|    | A trailing decimal point can be confused with a dot: '0.'.

binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 538| »   »   »   »   ratioMax·=·0.85·+·randFloat(0.,·0.1);
|    | [NORMAL] JSHintBear:
|    | A trailing decimal point can be confused with a dot: '0.'.

Link to build: https://jenkins.wildfiregames.com/job/differential/238/display/redirect