Page MenuHomeWildfire Games

Adds a "properties"-property to resources and let mods be able to prevent resources from being bartered, traded and/or tributed.
ClosedPublic

Authored by Freagarach on Apr 24 2019, 3:31 PM.

Details

Reviewers
wraitii
Silier
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Commits
rP22970: Adds a "properties"-property to resources and let mods be able to prevent…
Trac Tickets
#4370
Summary

Adds code so that mods can prevent resources from being bartered, traded and/or tributed.
Works by giving resources a "properties"-array so it is extendable (to e.g. "gatherable", "main-resource", "lootable" etcetera).
Currently supported properties are "tradable", "tributable" and "barterable".
PetraAI complies.

Test Plan

Remove a property from the array in a resource and see how it cannot be traded, tributed or bartered anymore.

Diff Detail

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

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Vulcan added a comment.Jul 9 2019, 9:31 PM

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

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/10/display/redirect

Freagarach added inline comments.Jul 9 2019, 9:38 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
294

You mean here? This should fix that, since the idea of all code below is to barter food, I can just as well check here ;)

Silier accepted this revision.Jul 9 2019, 9:44 PM

ok, I did not see that. I guess is too late for me now :) Anyway. Pointed problems have been resolved.

This revision is now accepted and ready to land.Jul 9 2019, 9:44 PM

New errors encountered:

WARNING: JavaScript warning: simulation/ai/petra/tradeManager.js line 179 reference to undefined property stocks[res]

ERROR: JavaScript error: simulation/ai/petra/tradeManager.js line 204 TypeError: mostNeeded[1] is undefined m.TradeManager.prototype.setTradingGoods@simulation/ai/petra/tradeManager.js:204:1 m.TradeManager.prototype.update@simulation/ai/petra/tradeManager.js:655:7 m.HQ.prototype.update@simulation/ai/petra/headquarters.js:2756:3 m.PetraBot.prototype.OnUpdate@simulation/ai/petra/_petrabot.js:119:3 m.BaseAI.prototype.HandleMessage@simulation/ai/common-api/baseAI.js:64:2

ERROR: JavaScript error: simulation/ai/petra/tradeManager.js line 204 TypeError: mostNeeded[1] is undefined m.TradeManager.prototype.setTradingGoods@simulation/ai/petra/tradeManager.js:204:1 m.TradeManager.prototype.update@simulation/ai/petra/tradeManager.js:655:7 m.HQ.prototype.update@simulation/ai/petra/headquarters.js:2756:3 m.PetraBot.prototype.OnUpdate@simulation/ai/petra/_petrabot.js:119:3 m.BaseAI.prototype.HandleMessage@simulation/ai/common-api/baseAI.js:64:2
Silier added inline comments.Jul 9 2019, 10:29 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
173

of

Question: Should we also try to account for the cases that no resources have a specific property?

binaries/data/mods/public/simulation/ai/petra/tradeManager.js
173

Yeah, it was too late yesterday.

Question: Should we also try to account for the cases that no resources have a specific property?

I tested these situations just now:

  • No Bartering resources reveals no errors,
  • No Trading resources gives only errors when trying to trade (obviously).
  • No Tributing resources gives an error when opening the diplomacy screen (which I think can easily be fixed by setting a default for widthOffset).

Performance-wise it would be good if PetraAI would not even try to initialise the different components when they are not possible.

Freagarach updated this revision to Diff 8807.Jul 10 2019, 8:27 AM

Even more fixes.

Freagarach marked an inline comment as done.Jul 10 2019, 8:27 AM

I would not see a problem with petra as looping through 0 resources takes 0 time

In D1846#85757, @Angen wrote:

I would not see a problem with petra as looping through 0 resources takes 0 time

Yeah, but there is happening a lot before it loops through the resources ;)

Then I would advise just early returns in that cases because disabling whole ai component could potentially cause more problems to do it and handle at all places.

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/15/display/redirect

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

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/16/display/redirect

Freagarach updated this revision to Diff 8808.Jul 10 2019, 9:45 AM

If everything went okay now, PetraAI can handle situations where there are no resources tradable, tributable and/or barterable.

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

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/17/display/redirect

GetCodes always return array, so you need to check length not existance of return

Freagarach updated this revision to Diff 8809.Jul 10 2019, 11:10 AM
  • Good check.
  • Also disables trade window when there are neither resources to trade nor to barter.

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

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/18/display/redirect

"properties": ["barterable", "tradable", "tributable"],

I was wondering whether those should be strings passed around as opposed to booleans with dedicated functions.
Having dedicated functions would mean the JS complains about it when parsing the code, whereas strings are only detected when the specific line is run.
So in the first case you get an instant test on the entire code, the latter requires testing every line manually if one doesn't rule out typos by reading well.

Having it generically means that modders can easily extend it, but is it a practical freedom?
Can we construct an exemplary use case?
It seems like the settings would mostly refer to simulation components that handle resources.
I suppose a modder has to replace the entire resource JSON file anyhow if he adds a new component, so what is the advantage of using the strings actually?

To account for pickMostNeededResources, one could pass the Resources getter function or the result of that rather than the property string to be passed to that function.
One should think about the performance impact, but I guess in both cases the function is called and the result object referenced.

Resources.GetTributableResources
Resources.GetBarterableResources
Resources.GetTradeableResources

(are those even words)

g_ResourceData.GetCodes("tributable")

Otherwise, if keeping the parameter, I would suggest to rename to GetCodesByProperty or so.

binaries/data/mods/public/globalscripts/Resources.js
39

-{}

Silier added inline comments.Jul 10 2019, 1:41 PM
binaries/data/mods/public/globalscripts/Resources.js
39

I am not sure about that. Looks like this is for line 12.

Having dedicated functions would mean the JS complains about it when parsing the code

Actually not true, only happens when the code is run, and the only code that is run when the file is loaded is the creation of the prototype and registering of global functions.
So catching typos can happen in both cases only when the affected code is run during the simulation.
Actually the generic approach prevents testing for typos by design since it is undecidable whether there is just no resource with the tag in the current set of mods or whether there is a typo.

Can we construct an exemplary use case?

Anno series was an example where there are 20+ resources but only the most relevant ones shown in the top panel.

I didn't do enough research on this to decide upon it, the generic approach just seems a bit dubious (like providing less safety checks than could be achieved without losing feature freedom).

binaries/data/mods/public/globalscripts/Resources.js
39

(cant read)

Freagarach marked 3 inline comments as done.Jul 10 2019, 2:47 PM
In D1846#85787, @elexis wrote:

Having dedicated functions would mean the JS complains about it when parsing the code

Actually not true, only happens when the code is run, and the only code that is run when the file is loaded is the creation of the prototype and registering of global functions.
So catching typos can happen in both cases only when the affected code is run during the simulation.
Actually the generic approach prevents testing for typos by design since it is undecidable whether there is just no resource with the tag in the current set of mods or whether there is a typo.

I'll wait untill you find an agreement ;)

In D1846#85787, @elexis wrote:

Can we construct an exemplary use case?

Anno series was an example where there are 20+ resources but only the most relevant ones shown in the top panel.

I didn't do enough research on this to decide upon it, the generic approach just seems a bit dubious (like providing less safety checks than could be achieved without losing feature freedom).

D1957 Is an example for something I thought was currency (but actually is not).

Still getting this:

WARNING: JavaScript warning: simulation/ai/petra/tradeManager.js line 204 reference to undefined property mostNeeded[1]

ERROR: JavaScript error: simulation/ai/petra/tradeManager.js line 204 TypeError: mostNeeded[1] is undefined m.TradeManager.prototype.setTradingGoods@simulation/ai/petra/tradeManager.js:204:1 m.TradeManager.prototype.update@simulation/ai/petra/tradeManager.js:665:7 m.HQ.prototype.update@simulation/ai/petra/headquarters.js:2760:3 m.PetraBot.prototype.OnUpdate@simulation/ai/petra/_petrabot.js:119:3 m.BaseAI.prototype.HandleMessage@simulation/ai/common-api/baseAI.js:64:2
Silier added inline comments.Jul 11 2019, 6:55 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
203

mostneeded[0/1] does not have to exists

Freagarach added inline comments.Jul 11 2019, 7:02 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
203

I'll check for more as well.

Freagarach added inline comments.Jul 11 2019, 7:18 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
203

mostNeeded[0] Has to exist because this function is not called when there are no tradable resources. Can we rely on that?

Silier added inline comments.Jul 11 2019, 7:26 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
203

technically but need to check all calls where is this function called and add comment as description of this function to not call when no tradable resources, anyway that could be early return and no one would have problems in the future calling this on 0 resources

Freagarach added inline comments.Jul 11 2019, 7:28 PM
binaries/data/mods/public/simulation/ai/petra/tradeManager.js
203

Okay, thanks! I'll add more early returns in functions then :)

Freagarach updated this revision to Diff 8833.Jul 11 2019, 7:47 PM

Some more checks in PetraAI.

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

Linter detected issues:
Executing section Source...

source/simulation2/components/tests/test_scripts.h
|   1| /*·Copyright·(C)·2017·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2017"

source/simulation2/components/tests/test_scripts.h
|  22| class·TestComponentScripts·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestComponentScripts:' is invalid C code. Use --std or --language to configure the language.
Executing section JS...

binaries/data/mods/public/simulation/components/Player.js
| 381| »   for·(var·type·in·amounts)
|    | [NORMAL] JSHintBear:
|    | 'type' is already defined.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['sell'] is better written in dot notation.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['buy'] is better written in dot notation.

binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 524| »   »   »   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
| 529| »   »   »   »   ratioMax·=·0.85·+·randFloat(0.,·0.1);
|    | [NORMAL] JSHintBear:
|    | A trailing decimal point can be confused with a dot: '0.'.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/30/display/redirect

Nescio added inline comments.Jul 11 2019, 8:16 PM
binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
72

Shouldn't there be a ! here?

Silier added inline comments.Jul 11 2019, 8:18 PM
binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
72

yes should, thanks for noticing, I did not really check last updates yet :)

Freagarach updated this revision to Diff 8834.Jul 11 2019, 8:20 PM
Freagarach marked 3 inline comments as done.

!

Freagarach requested review of this revision.Jul 11 2019, 8:23 PM

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

Linter detected issues:
Executing section Source...

source/simulation2/components/tests/test_scripts.h
|   1| /*·Copyright·(C)·2017·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2017"

source/simulation2/components/tests/test_scripts.h
|  22| class·TestComponentScripts·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestComponentScripts:' is invalid C code. Use --std or --language to configure the language.
Executing section JS...
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '='.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 438| 438| 	let candidate = { "gain": 0 };
| 439| 439| 	let potential = { "gain": 0 };
| 440| 440| 	let bestIndex = { "gain": 0 };
| 441|    |-	let bestLand  = { "gain": 0 };
|    | 441|+	let bestLand = { "gain": 0 };
| 442| 442| 
| 443| 443| 	let mapSize = gameState.sharedScript.mapSize;
| 444| 444| 	let traderTemplatesGains = gameState.getTraderTemplatesGains();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 476| 476| 			if (m1.foundationProgress() === undefined && m2.foundationProgress() === undefined)
| 477| 477| 			{
| 478| 478| 				if (accessIndex)
| 479|    |-				{
|    | 479|+				
| 480| 480| 					if (gameState.ai.accessibility.regionType[accessIndex] == "water" && sea == accessIndex)
| 481| 481| 					{
| 482| 482| 						if (gain < bestIndex.gain)
| 495| 495| 							continue;
| 496| 496| 						bestLand = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
| 497| 497| 					}
| 498|    |-				}
|    | 498|+				
| 499| 499| 				if (gain < candidate.gain)
| 500| 500| 					continue;
| 501| 501| 				candidate = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 615| 615| 		return;	// position found, but not enough gain compared to our present route
| 616| 616| 
| 617| 617| 	if (this.Config.debug > 1)
| 618|    |-	{
|    | 618|+	
| 619| 619| 		if (this.potentialTradeRoute)
| 620| 620| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a new route with gain " +
| 621| 621| 				marketPos[3] + " instead of the present " + this.potentialTradeRoute.gain);
| 622| 622| 		else
| 623| 623| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a first route with gain " +
| 624| 624| 				marketPos[3]);
| 625|    |-	}
|    | 625|+	
| 626| 626| 
| 627| 627| 	if (!this.tradeRoute)
| 628| 628| 		gameState.ai.queueManager.changePriority("economicBuilding", 2*this.Config.priorities.economicBuilding);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 680| 680| 
| 681| 681| 	let ret = {};
| 682| 682| 	for (let key in route)
| 683|    |-	{
|    | 683|+	
| 684| 684| 		if (key == "source" || key == "target")
| 685| 685| 		{
| 686| 686| 			if (!route[key])
| 689| 689| 		}
| 690| 690| 		else
| 691| 691| 			ret[key] = route[key];
| 692|    |-	}
|    | 692|+	
| 693| 693| 	return ret;
| 694| 694| };
| 695| 695| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 700| 700| 
| 701| 701| 	let ret = {};
| 702| 702| 	for (let key in route)
| 703|    |-	{
|    | 703|+	
| 704| 704| 		if (key == "source" || key == "target")
| 705| 705| 		{
| 706| 706| 			ret[key] = gameState.getEntityById(route[key]);
| 709| 709| 		}
| 710| 710| 		else
| 711| 711| 			ret[key] = route[key];
| 712|    |-	}
|    | 712|+	
| 713| 713| 	return ret;
| 714| 714| };
| 715| 715| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 727| 727| m.TradeManager.prototype.Deserialize = function(gameState, data)
| 728| 728| {
| 729| 729| 	for (let key in data)
| 730|    |-	{
|    | 730|+	
| 731| 731| 		if (key == "tradeRoute" || key == "potentialTradeRoute")
| 732| 732| 			this[key] = this.routeIdToEnt(gameState, data[key]);
| 733| 733| 		else
| 734| 734| 			this[key] = data[key];
| 735|    |-	}
|    | 735|+	
| 736| 736| };
| 737| 737| 
| 738| 738| return m;

binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 739| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 392| 392| 				// Players see colors depending on diplomacy
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395|    |-					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
|    | 395|+						g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396|    |-					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
|    | 396|+							g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397|    |-					getDiplomacyColor("enemy");
|    | 397|+								getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
| 400| 400| 	}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 644| 644| 					"civ": setStringTags(g_CivData[g_Players[g_ViewedPlayer].civ].Name, { "font": "sans-bold-stroke-14" }),
| 645| 645| 					"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
| 646| 646| 					"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
| 647|    |-			});
|    | 647|+				});
| 648| 648| 	}
| 649| 649| 
| 650| 650| 	// Following gaia can be interesting on scripted maps
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1195|1195| 
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|    |-		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|    |1198|+			"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|    |-		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|    |1199|+			"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|    |-	});
|    |1200|+		});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|1203|1203| 	for (let r = 0; r < resCodes.length; ++r)

binaries/data/mods/public/gui/session/session.js
|1056| »   let·getPanelEntNameTooltip·=·panelEntState·=>·"[font=\"sans-bold-16\"]"·+·template.name.specific·+·"[/font]";
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'panelEntState' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1131| »   »   button.onpress·=·(function(i)·{·return·function()·{·performGroup((Engine.HotkeyIsPressed("selection.add")·?·"add"·:·"select"),·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1132| »   »   button.ondoublepress·=·(function(i)·{·return·function()·{·performGroup("snap",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1133| »   »   button.onpressright·=·(function(i)·{·return·function()·{·performGroup("breakUp",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 488| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 563| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 209| 209| 	}
| 210| 210| 
| 211| 211| 	for (let evt of events.Destroy)
| 212|    |-	{
|    | 212|+	
| 213| 213| 		// Let's check we haven't lost an important building here.
| 214| 214| 		if (evt && !evt.SuccessfulFoundation && evt.entityObj && evt.metadata && evt.metadata[PlayerID] &&
| 215| 215| 			evt.metadata[PlayerID].base)
| 226| 226| 			if (evt.metadata[PlayerID].baseAnchor && evt.metadata[PlayerID].baseAnchor === true)
| 227| 227| 				base.anchorLost(gameState, ent);
| 228| 228| 		}
| 229|    |-	}
|    | 229|+	
| 230| 230| 
| 231| 231| 	for (let evt of events.EntityRenamed)
| 232| 232| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 255| 255| 			// Let's get a few units from other bases there to build this.
| 256| 256| 			let builders = this.bulkPickWorkers(gameState, newbase, 10);
| 257| 257| 			if (builders !== false)
| 258|    |-			{
|    | 258|+			
| 259| 259| 				builders.forEach(worker => {
| 260| 260| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 261| 261| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 262| 262| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 263| 263| 				});
| 264|    |-			}
|    | 264|+			
| 265| 265| 		}
| 266| 266| 		else if (ent.getMetadata(PlayerID, "base") == -2)	// anchorless base around a dock
| 267| 267| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 269| 269| 			// Let's get a few units from other bases there to build this.
| 270| 270| 			let builders = this.bulkPickWorkers(gameState, newbase, 4);
| 271| 271| 			if (builders != false)
| 272|    |-			{
|    | 272|+			
| 273| 273| 				builders.forEach(worker => {
| 274| 274| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 275| 275| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 276| 276| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 277| 277| 				});
| 278|    |-			}
|    | 278|+			
| 279| 279| 		}
| 280| 280| 	}
| 281| 281| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 395| 395| 	}
| 396| 396| 
| 397| 397| 	for (let evt of events.TrainingFinished)
| 398|    |-	{
|    | 398|+	
| 399| 399| 		for (let entId of evt.entities)
| 400| 400| 		{
| 401| 401| 			let ent = gameState.getEntityById(entId);
| 463| 463| 					ent.moveToRange(goal[0], goal[1]);
| 464| 464| 			}
| 465| 465| 		}
| 466|    |-	}
|    | 466|+	
| 467| 467| 
| 468| 468| 	for (let evt of events.TerritoryDecayChanged)
| 469| 469| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 411| 411| 					this.garrisonManager.registerHolder(gameState, holder);
| 412| 412| 			}
| 413| 413| 			else if (ent.getMetadata(PlayerID, "garrisonType"))
| 414|    |-			{
|    | 414|+			
| 415| 415| 				// we were supposed to be autogarrisoned, but this has failed (may-be full)
| 416| 416| 				ent.setMetadata(PlayerID, "garrisonType", undefined);
| 417|    |-			}
|    | 417|+			
| 418| 418| 
| 419| 419| 			// Check if this unit is no more needed in its attack plan
| 420| 420| 			// (happen when the training ends after the attack is started or aborted)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 482| 482| 	}
| 483| 483| 
| 484| 484| 	if (addBase)
| 485|    |-	{
|    | 485|+	
| 486| 486| 		if (!this.firstBaseConfig)
| 487| 487| 		{
| 488| 488| 			// This is our first base, let us configure our starting resources
| 495| 495| 			this.saveSpace = undefined;
| 496| 496| 			this.maxFields = false;
| 497| 497| 		}
| 498|    |-	}
|    | 498|+	
| 499| 499| 
| 500| 500| 	// Then deals with decaying structures: destroy them if being lost to enemy (except in easier difficulties)
| 501| 501| 	if (this.Config.difficulty < 2)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 484| 484| 	if (addBase)
| 485| 485| 	{
| 486| 486| 		if (!this.firstBaseConfig)
| 487|    |-		{
|    | 487|+		
| 488| 488| 			// This is our first base, let us configure our starting resources
| 489| 489| 			this.configFirstBase(gameState);
| 490|    |-		}
|    | 490|+		
| 491| 491| 		else
| 492| 492| 		{
| 493| 493| 			// Let us hope this new base will fix our possible resource shortage
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 773| 773| 		let aValue = 0.1;
| 774| 774| 		let bValue = 0.1;
| 775| 775| 		for (let param of parameters)
| 776|    |-		{
|    | 776|+		
| 777| 777| 			if (param[0] == "strength")
| 778| 778| 			{
| 779| 779| 				aValue += m.getMaxStrength(a[1]) * param[1];
| 807| 807| 			}
| 808| 808| 			else
| 809| 809| 				API3.warn(" trainMoreUnits avec non prevu " + uneval(param));
| 810|    |-		}
|    | 810|+		
| 811| 811| 		return -aValue/aCost + bValue/bCost;
| 812| 812| 	});
| 813| 813| 	return units[0][0];
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1053|1053| 				continue;
|1054|1054| 
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|    |-			{
|    |1056|+			
|1057|1057| 				if (!accessible)
|1058|1058| 				{
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1063|1063| 				}
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|    |-			}
|    |1066|+			
|1067|1067| 
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|1056| 			{
|1057|1057| 				if (!accessible)
|1058|    |-				{
|    |1058|+				
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1060|1060| 						norm *= 0.5;
|1061|1061| 					else
|1062|1062| 						norm *= 0.8;
|1063|    |-				}
|    |1063|+				
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|1066| 			}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|1070|1070| 			if (!oversea)
|1071|    |-			{
|    |1071|+			
|1072|1072| 				for (let dp of dpList)
|1073|1073| 				{
|1074|1074| 					let dist = API3.SquareVectorDistance(dp.pos, pos);
|1080|1080| 					else if (dist < 6400)
|1081|1081| 						norm *= 0.5;
|1082|1082| 				}
|1083|    |-			}
|    |1083|+			
|1084|1084| 			if (norm == 0)
|1085|1085| 				continue;
|1086|1086| 		}
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1094|1094| 				val += gameState.sharedScript.ccResourceMaps[res].map[j];
|1095|1095| 		val *= norm;
|1096|1096| 
|1097|    |-		// If oversea, be just above threshold to be accepted if nothing else 
|    |1097|+		// If oversea, be just above threshold to be accepted if nothing else
|1098|1098| 		if (oversea)
|1099|1099| 			val = Math.max(val, cut + 0.1);
|1100|1100| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1384|1384| 	// do not keep it if gain is too small, except if this is our first BarterMarket
|1385|1385| 	let idx;
|1386|1386| 	if (expectedGain < this.tradeManager.minimalGain)
|1387|    |-	{
|    |1387|+	
|1388|1388| 		if (template.hasClass("BarterMarket") &&
|1389|1389| 		    !gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities())
|1390|1390| 			idx = -1;	// needed by queueplanBuilding manager to keep that market
|1391|1391| 		else
|1392|1392| 			return false;
|1393|    |-	}
|    |1393|+	
|1394|1394| 	else
|1395|1395| 		idx = this.basesMap.map[bestJdx];
|1396|1396| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1571|1571| 			let cost = queues.economicBuilding.plans[0].getCost();
|1572|1572| 			queueManager.setAccounts(gameState, cost, "economicBuilding");
|1573|1573| 			if (!queueManager.canAfford("economicBuilding", cost))
|1574|    |-			{
|    |1574|+			
|1575|1575| 				for (let q in queueManager.queues)
|1576|1576| 				{
|1577|1577| 					if (q == "economicBuilding")
|1580|1580| 					if (queueManager.canAfford("economicBuilding", cost))
|1581|1581| 						break;
|1582|1582| 				}
|1583|    |-			}
|    |1583|+			
|1584|1584| 		}
|1585|1585| 		return;
|1586|1586| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1630|1630| 		let highLevel = 0;
|1631|1631| 		let lowLevel = 0;
|1632|1632| 		for (let res in cost)
|1633|    |-		{
|    |1633|+		
|1634|1634| 			if (resources[res] && resources[res] > 0.7 * cost[res])
|1635|1635| 				++highLevel;
|1636|1636| 			else if (!resources[res] || resources[res] < 0.3 * cost[res])
|1637|1637| 				++lowLevel;
|1638|    |-		}
|    |1638|+		
|1639|1639| 		if (highLevel == 0 || lowLevel > 1)
|1640|1640| 			return;
|1641|1641| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1756|1756| 	let freeSlots = gameState.getPopulationLimit() + HouseNb*popBonus - this.getAccountedPopulation(gameState);
|1757|1757| 	let priority;
|1758|1758| 	if (freeSlots < 5)
|1759|    |-	{
|    |1759|+	
|1760|1760| 		if (this.buildManager.isUnbuildable(gameState, house))
|1761|1761| 		{
|1762|1762| 			if (this.Config.debug > 1)
|1765|1765| 		}
|1766|1766| 		else
|1767|1767| 			priority = 2*this.Config.priorities.house;
|1768|    |-	}
|    |1768|+	
|1769|1769| 	else
|1770|1770| 		priority = this.Config.priorities.house;
|1771|1771| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1847|1847| 		return;
|1848|1848| 
|1849|1849| 	if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3))))
|1850|    |-	{
|    |1850|+	
|1851|1851| 		// try to build fortresses
|1852|1852| 		if (this.canBuild(gameState, "structures/{civ}_fortress"))
|1853|1853| 		{
|1866|1866| 				return;
|1867|1867| 			}
|1868|1868| 		}
|1869|    |-	}
|    |1869|+	
|1870|1870| 
|1871|1871| 	if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower"))
|1872|1872| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2010|2010| 		nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true);
|2011|2011| 
|2012|2012| 	if (!nAdvanced || nAdvanced < this.bAdvanced.length && this.getAccountedPopulation(gameState) > 110)
|2013|    |-	{
|    |2013|+	
|2014|2014| 		for (let advanced of this.bAdvanced)
|2015|2015| 		{
|2016|2016| 			if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced))
|2025|2025| 				queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced));
|2026|2026| 			return;
|2027|2027| 		}
|2028|    |-	}
|    |2028|+	
|2029|2029| };
|2030|2030| 
|2031|2031| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2113|2113| 	// in which case we prefer melee units
|2114|2114| 	let numGarrisoned = this.garrisonManager.numberOfGarrisonedUnits(nearestAnchor);
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|    |-	{
|    |2116|+	
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|2118| 		{
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|2123| 		}
|2124|    |-	}
|    |2124|+	
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|2127|2127| 	let rangedWanted = randBool() && autogarrison;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|2116| 	{
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|    |-		{
|    |2118|+		
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2120|2120| 				numGarrisoned += item.count;
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|    |-		}
|    |2123|+		
|2124|2124| 	}
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2155|2155| 	let cost = new API3.Resources(templateFound[1].cost());
|2156|2156| 	queueManager.setAccounts(gameState, cost, "emergency");
|2157|2157| 	if (!queueManager.canAfford("emergency", cost))
|2158|    |-	{
|    |2158|+	
|2159|2159| 		for (let q in queueManager.queues)
|2160|2160| 		{
|2161|2161| 			if (q == "emergency")
|2164|2164| 			if (queueManager.canAfford("emergency", cost))
|2165|2165| 				break;
|2166|2166| 		}
|2167|    |-	}
|    |2167|+	
|2168|2168| 	let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() };
|2169|2169| 	if (autogarrison)
|2170|2170| 		metadata.garrisonType = "protection";
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2445|2445| m.HQ.prototype.assignGatherers = function()
|2446|2446| {
|2447|2447| 	for (let base of this.baseManagers)
|2448|    |-	{
|    |2448|+	
|2449|2449| 		for (let worker of base.workers.values())
|2450|2450| 		{
|2451|2451| 			if (worker.unitAIState().split(".")[1] != "RETURNRESOURCE")
|2455|2455| 				continue;
|2456|2456| 			this.AddTCGatherer(orders[1].target);
|2457|2457| 		}
|2458|    |-	}
|    |2458|+	
|2459|2459| };
|2460|2460| 
|2461|2461| m.HQ.prototype.isDangerousLocation = function(gameState, pos, radius)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2627|2627| 	{
|2628|2628| 		let pop = gameState.getPopulation();
|2629|2629| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2630|    |-		{
|    |2630|+		
|2631|2631| 			for (let item of ent.trainingQueue())
|2632|2632| 			{
|2633|2633| 				if (!item.unitTemplate)
|2636|2636| 				if (unitPop)
|2637|2637| 					pop += item.count * unitPop;
|2638|2638| 			}
|2639|    |-		}
|    |2639|+		
|2640|2640| 		this.turnCache.accountedPopulation = pop;
|2641|2641| 	}
|2642|2642| 	return this.turnCache.accountedPopulation;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2651|2651| 	{
|2652|2652| 		let workers = gameState.getOwnEntitiesByRole("worker", true).length;
|2653|2653| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2654|    |-		{
|    |2654|+		
|2655|2655| 			for (let item of ent.trainingQueue())
|2656|2656| 			{
|2657|2657| 				if (!item.metadata || !item.metadata.role || item.metadata.role != "worker")
|2658|2658| 					continue;
|2659|2659| 				workers += item.count;
|2660|2660| 			}
|2661|    |-		}
|    |2661|+		
|2662|2662| 		this.turnCache.accountedWorkers = workers;
|2663|2663| 	}
|2664|2664| 	return this.turnCache.accountedWorkers;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2689|2689| 			this.phasing = 0;
|2690|2690| 	}
|2691|2691| 
|2692|    |-/*	if (this.Config.debug > 1)
|    |2692|+	/*	if (this.Config.debug > 1)
|2693|2693| 	{
|2694|2694| 		gameState.getOwnUnits().forEach (function (ent) {
|2695|2695| 			if (!ent.position())
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2764|2764| 		this.currentBase %= this.baseManagers.length;
|2765|2765| 		activeBase = this.baseManagers[this.currentBase++].update(gameState, queues, events);
|2766|2766| 		--nbBases;
|2767|    |-// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|    |2767|+		// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|2768|2768| 	}
|2769|2769| 	while (!activeBase && nbBases != 0);
|2770|2770| 

binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2902| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.

binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 524| »   »   »   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
| 529| »   »   »   »   ratioMax·=·0.85·+·randFloat(0.,·0.1);
|    | [NORMAL] JSHintBear:
|    | A trailing decimal point can be confused with a dot: '0.'.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|  82|  82| 		let tribute = {};
|  83|  83| 		let toSend = false;
|  84|  84| 		for (let res in resTribCodes)
|  85|    |-		{
|    |  85|+		
|  86|  86| 			if (donor && availableResources[res] > 200 && allyResources[res] < 0.2 * availableResources[res])
|  87|  87| 			{
|  88|  88| 				tribute[res] = Math.floor(0.3*availableResources[res] - allyResources[res]);
| 114| 114| 					}
| 115| 115| 				}
| 116| 116| 			}
| 117|    |-		}
|    | 117|+		
| 118| 118| 		if (!toSend)
| 119| 119| 			continue;
| 120| 120| 		if (this.Config.debug > 1)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 102| 102| 				if (!mostNeeded)
| 103| 103| 					mostNeeded = gameState.ai.HQ.pickMostNeededResources(gameState, resTribCodes);
| 104| 104| 				for (let k = 0; k < mostNeeded.length; ++k)
| 105|    |-				{
|    | 105|+				
| 106| 106| 					if (mostNeeded[k].type == res && mostNeeded[k].wanted > 0)
| 107| 107| 					{
| 108| 108| 						this.nextTributeRequest.set("all", gameState.ai.elapsedTime + 90);
| 112| 112| 							API3.warn("Tribute on " + res + " requested to player " + i);
| 113| 113| 						break;
| 114| 114| 					}
| 115|    |-				}
|    | 115|+				
| 116| 116| 			}
| 117| 117| 		}
| 118| 118| 		if (!toSend)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 159| 159| 			continue;
| 160| 160| 		let tributes = 0;
| 161| 161| 		for (let key in evt.amounts)
| 162|    |-		{
|    | 162|+		
| 163| 163| 			if (key === "food")
| 164| 164| 				tributes += evt.amounts[key];
| 165| 165| 			else
| 166| 166| 				tributes += 2*evt.amounts[key];
| 167|    |-		}
|    | 167|+		
| 168| 168| 		this.Config.personality.cooperative = Math.min(1, this.Config.personality.cooperative + 0.0001 * tributes);
| 169| 169| 	}
| 170| 170| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 238| 238| 
| 239| 239| 		// Our diplomacy will have changed already if the response was "accept"
| 240| 240| 		if (request.status === "waitingForTribute")
| 241|    |-		{
|    | 241|+		
| 242| 242| 			Engine.PostCommand(PlayerID, {
| 243| 243| 				"type": "tribute-request",
| 244| 244| 				"source": PlayerID,
| 246| 246| 				"resourceWanted": request.wanted,
| 247| 247| 				"resourceType": request.type
| 248| 248| 			});
| 249|    |-		}
|    | 249|+		
| 250| 250| 	}
| 251| 251| 
| 252| 252| 	// An AI player we sent a diplomacy request to demanded we send them a tribute
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 447| 447| {
| 448| 448| 	for (let [player, data] of this.receivedDiplomacyRequests)
| 449| 449| 		if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime)
| 450|    |-		{
|    | 450|+		
| 451| 451| 			if (data.sentWarning)
| 452| 452| 			{
| 453| 453| 				this.receivedDiplomacyRequests.delete(player);
| 462| 462| 					"type": data.type
| 463| 463| 				});
| 464| 464| 			}
| 465|    |-		}
|    | 465|+		
| 466| 466| };
| 467| 467| 
| 468| 468| /**

binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 574| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/Player.js
| 381| »   for·(var·type·in·amounts)
|    | [NORMAL] JSHintBear:
|    | 'type' is already defined.
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["sell"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices.sell[resourceToSell] / prices["buy"][resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["buy"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices.buy[resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['sell'] is better written in dot notation.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['buy'] is better written in dot notation.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/31/display/redirect

wraitii requested changes to this revision.Jul 14 2019, 6:55 PM

Following discussions on IRC, I think we should go back very slightly to your initial diff.
Instead of having a GetCodes take a parameter and filter on property, explicitly write GetBarterableCodes, GetTradableCodes, GetTributableCodes, and return values on that property or empty.

That way, we gain the benefit that typos would be detected when calling the functions, and we avoid passing strings. And it's only about 9 more lines of codes. And mods could still easily enough extend this for other properties.

Other than that this looks good

This revision now requires changes to proceed.Jul 14 2019, 6:55 PM
Freagarach updated this revision to Diff 8903.EditedJul 14 2019, 8:41 PM

Split function.

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

Linter detected issues:
Executing section Source...

source/simulation2/components/tests/test_scripts.h
|   1| /*·Copyright·(C)·2017·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2017"

source/simulation2/components/tests/test_scripts.h
|  22| class·TestComponentScripts·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestComponentScripts:' is invalid C code. Use --std or --language to configure the language.
Executing section JS...
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["barterable"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
|  91|  91|  */
|  92|  92| Resources.prototype.GetBarterableCodes = function()
|  93|  93| {
|  94|    |-	return this.resourceCodesByProperty["barterable"] || [];
|    |  94|+	return this.resourceCodesByProperty.barterable || [];
|  95|  95| };
|  96|  96| 
|  97|  97| /**
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["tradable"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
| 100| 100|  */
| 101| 101| Resources.prototype.GetTradableCodes = function()
| 102| 102| {
| 103|    |-	return this.resourceCodesByProperty["tradable"] || [];
|    | 103|+	return this.resourceCodesByProperty.tradable || [];
| 104| 104| };
| 105| 105| 
| 106| 106| /**
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["tributable"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/globalscripts/Resources.js
| 109| 109|  */
| 110| 110| Resources.prototype.GetTributableCodes = function()
| 111| 111| {
| 112|    |-	return this.resourceCodesByProperty["tributable"] || [];
|    | 112|+	return this.resourceCodesByProperty.tributable || [];
| 113| 113| };
| 114| 114| 
| 115| 115| /**

binaries/data/mods/public/globalscripts/Resources.js
|  94| »   return·this.resourceCodesByProperty["barterable"]·||·[];
|    | [NORMAL] JSHintBear:
|    | ['barterable'] is better written in dot notation.

binaries/data/mods/public/globalscripts/Resources.js
| 103| »   return·this.resourceCodesByProperty["tradable"]·||·[];
|    | [NORMAL] JSHintBear:
|    | ['tradable'] is better written in dot notation.

binaries/data/mods/public/globalscripts/Resources.js
| 112| »   return·this.resourceCodesByProperty["tributable"]·||·[];
|    | [NORMAL] JSHintBear:
|    | ['tributable'] is better written in dot notation.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|  82|  82| 		let tribute = {};
|  83|  83| 		let toSend = false;
|  84|  84| 		for (let res in resTribCodes)
|  85|    |-		{
|    |  85|+		
|  86|  86| 			if (donor && availableResources[res] > 200 && allyResources[res] < 0.2 * availableResources[res])
|  87|  87| 			{
|  88|  88| 				tribute[res] = Math.floor(0.3*availableResources[res] - allyResources[res]);
| 114| 114| 					}
| 115| 115| 				}
| 116| 116| 			}
| 117|    |-		}
|    | 117|+		
| 118| 118| 		if (!toSend)
| 119| 119| 			continue;
| 120| 120| 		if (this.Config.debug > 1)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 102| 102| 				if (!mostNeeded)
| 103| 103| 					mostNeeded = gameState.ai.HQ.pickMostNeededResources(gameState, resTribCodes);
| 104| 104| 				for (let k = 0; k < mostNeeded.length; ++k)
| 105|    |-				{
|    | 105|+				
| 106| 106| 					if (mostNeeded[k].type == res && mostNeeded[k].wanted > 0)
| 107| 107| 					{
| 108| 108| 						this.nextTributeRequest.set("all", gameState.ai.elapsedTime + 90);
| 112| 112| 							API3.warn("Tribute on " + res + " requested to player " + i);
| 113| 113| 						break;
| 114| 114| 					}
| 115|    |-				}
|    | 115|+				
| 116| 116| 			}
| 117| 117| 		}
| 118| 118| 		if (!toSend)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 159| 159| 			continue;
| 160| 160| 		let tributes = 0;
| 161| 161| 		for (let key in evt.amounts)
| 162|    |-		{
|    | 162|+		
| 163| 163| 			if (key === "food")
| 164| 164| 				tributes += evt.amounts[key];
| 165| 165| 			else
| 166| 166| 				tributes += 2*evt.amounts[key];
| 167|    |-		}
|    | 167|+		
| 168| 168| 		this.Config.personality.cooperative = Math.min(1, this.Config.personality.cooperative + 0.0001 * tributes);
| 169| 169| 	}
| 170| 170| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 238| 238| 
| 239| 239| 		// Our diplomacy will have changed already if the response was "accept"
| 240| 240| 		if (request.status === "waitingForTribute")
| 241|    |-		{
|    | 241|+		
| 242| 242| 			Engine.PostCommand(PlayerID, {
| 243| 243| 				"type": "tribute-request",
| 244| 244| 				"source": PlayerID,
| 246| 246| 				"resourceWanted": request.wanted,
| 247| 247| 				"resourceType": request.type
| 248| 248| 			});
| 249|    |-		}
|    | 249|+		
| 250| 250| 	}
| 251| 251| 
| 252| 252| 	// An AI player we sent a diplomacy request to demanded we send them a tribute
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 447| 447| {
| 448| 448| 	for (let [player, data] of this.receivedDiplomacyRequests)
| 449| 449| 		if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime)
| 450|    |-		{
|    | 450|+		
| 451| 451| 			if (data.sentWarning)
| 452| 452| 			{
| 453| 453| 				this.receivedDiplomacyRequests.delete(player);
| 462| 462| 					"type": data.type
| 463| 463| 				});
| 464| 464| 			}
| 465|    |-		}
|    | 465|+		
| 466| 466| };
| 467| 467| 
| 468| 468| /**

binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 574| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/Player.js
| 381| »   for·(var·type·in·amounts)
|    | [NORMAL] JSHintBear:
|    | 'type' is already defined.
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '='.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 438| 438| 	let candidate = { "gain": 0 };
| 439| 439| 	let potential = { "gain": 0 };
| 440| 440| 	let bestIndex = { "gain": 0 };
| 441|    |-	let bestLand  = { "gain": 0 };
|    | 441|+	let bestLand = { "gain": 0 };
| 442| 442| 
| 443| 443| 	let mapSize = gameState.sharedScript.mapSize;
| 444| 444| 	let traderTemplatesGains = gameState.getTraderTemplatesGains();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 476| 476| 			if (m1.foundationProgress() === undefined && m2.foundationProgress() === undefined)
| 477| 477| 			{
| 478| 478| 				if (accessIndex)
| 479|    |-				{
|    | 479|+				
| 480| 480| 					if (gameState.ai.accessibility.regionType[accessIndex] == "water" && sea == accessIndex)
| 481| 481| 					{
| 482| 482| 						if (gain < bestIndex.gain)
| 495| 495| 							continue;
| 496| 496| 						bestLand = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
| 497| 497| 					}
| 498|    |-				}
|    | 498|+				
| 499| 499| 				if (gain < candidate.gain)
| 500| 500| 					continue;
| 501| 501| 				candidate = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 615| 615| 		return;	// position found, but not enough gain compared to our present route
| 616| 616| 
| 617| 617| 	if (this.Config.debug > 1)
| 618|    |-	{
|    | 618|+	
| 619| 619| 		if (this.potentialTradeRoute)
| 620| 620| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a new route with gain " +
| 621| 621| 				marketPos[3] + " instead of the present " + this.potentialTradeRoute.gain);
| 622| 622| 		else
| 623| 623| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a first route with gain " +
| 624| 624| 				marketPos[3]);
| 625|    |-	}
|    | 625|+	
| 626| 626| 
| 627| 627| 	if (!this.tradeRoute)
| 628| 628| 		gameState.ai.queueManager.changePriority("economicBuilding", 2*this.Config.priorities.economicBuilding);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 680| 680| 
| 681| 681| 	let ret = {};
| 682| 682| 	for (let key in route)
| 683|    |-	{
|    | 683|+	
| 684| 684| 		if (key == "source" || key == "target")
| 685| 685| 		{
| 686| 686| 			if (!route[key])
| 689| 689| 		}
| 690| 690| 		else
| 691| 691| 			ret[key] = route[key];
| 692|    |-	}
|    | 692|+	
| 693| 693| 	return ret;
| 694| 694| };
| 695| 695| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 700| 700| 
| 701| 701| 	let ret = {};
| 702| 702| 	for (let key in route)
| 703|    |-	{
|    | 703|+	
| 704| 704| 		if (key == "source" || key == "target")
| 705| 705| 		{
| 706| 706| 			ret[key] = gameState.getEntityById(route[key]);
| 709| 709| 		}
| 710| 710| 		else
| 711| 711| 			ret[key] = route[key];
| 712|    |-	}
|    | 712|+	
| 713| 713| 	return ret;
| 714| 714| };
| 715| 715| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 727| 727| m.TradeManager.prototype.Deserialize = function(gameState, data)
| 728| 728| {
| 729| 729| 	for (let key in data)
| 730|    |-	{
|    | 730|+	
| 731| 731| 		if (key == "tradeRoute" || key == "potentialTradeRoute")
| 732| 732| 			this[key] = this.routeIdToEnt(gameState, data[key]);
| 733| 733| 		else
| 734| 734| 			this[key] = data[key];
| 735|    |-	}
|    | 735|+	
| 736| 736| };
| 737| 737| 
| 738| 738| return m;

binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 739| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["sell"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices.sell[resourceToSell] / prices["buy"][resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["buy"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices.buy[resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['sell'] is better written in dot notation.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['buy'] is better written in dot notation.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 209| 209| 	}
| 210| 210| 
| 211| 211| 	for (let evt of events.Destroy)
| 212|    |-	{
|    | 212|+	
| 213| 213| 		// Let's check we haven't lost an important building here.
| 214| 214| 		if (evt && !evt.SuccessfulFoundation && evt.entityObj && evt.metadata && evt.metadata[PlayerID] &&
| 215| 215| 			evt.metadata[PlayerID].base)
| 226| 226| 			if (evt.metadata[PlayerID].baseAnchor && evt.metadata[PlayerID].baseAnchor === true)
| 227| 227| 				base.anchorLost(gameState, ent);
| 228| 228| 		}
| 229|    |-	}
|    | 229|+	
| 230| 230| 
| 231| 231| 	for (let evt of events.EntityRenamed)
| 232| 232| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 255| 255| 			// Let's get a few units from other bases there to build this.
| 256| 256| 			let builders = this.bulkPickWorkers(gameState, newbase, 10);
| 257| 257| 			if (builders !== false)
| 258|    |-			{
|    | 258|+			
| 259| 259| 				builders.forEach(worker => {
| 260| 260| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 261| 261| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 262| 262| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 263| 263| 				});
| 264|    |-			}
|    | 264|+			
| 265| 265| 		}
| 266| 266| 		else if (ent.getMetadata(PlayerID, "base") == -2)	// anchorless base around a dock
| 267| 267| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 269| 269| 			// Let's get a few units from other bases there to build this.
| 270| 270| 			let builders = this.bulkPickWorkers(gameState, newbase, 4);
| 271| 271| 			if (builders != false)
| 272|    |-			{
|    | 272|+			
| 273| 273| 				builders.forEach(worker => {
| 274| 274| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 275| 275| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 276| 276| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 277| 277| 				});
| 278|    |-			}
|    | 278|+			
| 279| 279| 		}
| 280| 280| 	}
| 281| 281| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 395| 395| 	}
| 396| 396| 
| 397| 397| 	for (let evt of events.TrainingFinished)
| 398|    |-	{
|    | 398|+	
| 399| 399| 		for (let entId of evt.entities)
| 400| 400| 		{
| 401| 401| 			let ent = gameState.getEntityById(entId);
| 463| 463| 					ent.moveToRange(goal[0], goal[1]);
| 464| 464| 			}
| 465| 465| 		}
| 466|    |-	}
|    | 466|+	
| 467| 467| 
| 468| 468| 	for (let evt of events.TerritoryDecayChanged)
| 469| 469| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 411| 411| 					this.garrisonManager.registerHolder(gameState, holder);
| 412| 412| 			}
| 413| 413| 			else if (ent.getMetadata(PlayerID, "garrisonType"))
| 414|    |-			{
|    | 414|+			
| 415| 415| 				// we were supposed to be autogarrisoned, but this has failed (may-be full)
| 416| 416| 				ent.setMetadata(PlayerID, "garrisonType", undefined);
| 417|    |-			}
|    | 417|+			
| 418| 418| 
| 419| 419| 			// Check if this unit is no more needed in its attack plan
| 420| 420| 			// (happen when the training ends after the attack is started or aborted)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 482| 482| 	}
| 483| 483| 
| 484| 484| 	if (addBase)
| 485|    |-	{
|    | 485|+	
| 486| 486| 		if (!this.firstBaseConfig)
| 487| 487| 		{
| 488| 488| 			// This is our first base, let us configure our starting resources
| 495| 495| 			this.saveSpace = undefined;
| 496| 496| 			this.maxFields = false;
| 497| 497| 		}
| 498|    |-	}
|    | 498|+	
| 499| 499| 
| 500| 500| 	// Then deals with decaying structures: destroy them if being lost to enemy (except in easier difficulties)
| 501| 501| 	if (this.Config.difficulty < 2)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 484| 484| 	if (addBase)
| 485| 485| 	{
| 486| 486| 		if (!this.firstBaseConfig)
| 487|    |-		{
|    | 487|+		
| 488| 488| 			// This is our first base, let us configure our starting resources
| 489| 489| 			this.configFirstBase(gameState);
| 490|    |-		}
|    | 490|+		
| 491| 491| 		else
| 492| 492| 		{
| 493| 493| 			// Let us hope this new base will fix our possible resource shortage
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 773| 773| 		let aValue = 0.1;
| 774| 774| 		let bValue = 0.1;
| 775| 775| 		for (let param of parameters)
| 776|    |-		{
|    | 776|+		
| 777| 777| 			if (param[0] == "strength")
| 778| 778| 			{
| 779| 779| 				aValue += m.getMaxStrength(a[1]) * param[1];
| 807| 807| 			}
| 808| 808| 			else
| 809| 809| 				API3.warn(" trainMoreUnits avec non prevu " + uneval(param));
| 810|    |-		}
|    | 810|+		
| 811| 811| 		return -aValue/aCost + bValue/bCost;
| 812| 812| 	});
| 813| 813| 	return units[0][0];
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1053|1053| 				continue;
|1054|1054| 
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|    |-			{
|    |1056|+			
|1057|1057| 				if (!accessible)
|1058|1058| 				{
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1063|1063| 				}
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|    |-			}
|    |1066|+			
|1067|1067| 
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|1056| 			{
|1057|1057| 				if (!accessible)
|1058|    |-				{
|    |1058|+				
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1060|1060| 						norm *= 0.5;
|1061|1061| 					else
|1062|1062| 						norm *= 0.8;
|1063|    |-				}
|    |1063|+				
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|1066| 			}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|1070|1070| 			if (!oversea)
|1071|    |-			{
|    |1071|+			
|1072|1072| 				for (let dp of dpList)
|1073|1073| 				{
|1074|1074| 					let dist = API3.SquareVectorDistance(dp.pos, pos);
|1080|1080| 					else if (dist < 6400)
|1081|1081| 						norm *= 0.5;
|1082|1082| 				}
|1083|    |-			}
|    |1083|+			
|1084|1084| 			if (norm == 0)
|1085|1085| 				continue;
|1086|1086| 		}
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1094|1094| 				val += gameState.sharedScript.ccResourceMaps[res].map[j];
|1095|1095| 		val *= norm;
|1096|1096| 
|1097|    |-		// If oversea, be just above threshold to be accepted if nothing else 
|    |1097|+		// If oversea, be just above threshold to be accepted if nothing else
|1098|1098| 		if (oversea)
|1099|1099| 			val = Math.max(val, cut + 0.1);
|1100|1100| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1384|1384| 	// do not keep it if gain is too small, except if this is our first BarterMarket
|1385|1385| 	let idx;
|1386|1386| 	if (expectedGain < this.tradeManager.minimalGain)
|1387|    |-	{
|    |1387|+	
|1388|1388| 		if (template.hasClass("BarterMarket") &&
|1389|1389| 		    !gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities())
|1390|1390| 			idx = -1;	// needed by queueplanBuilding manager to keep that market
|1391|1391| 		else
|1392|1392| 			return false;
|1393|    |-	}
|    |1393|+	
|1394|1394| 	else
|1395|1395| 		idx = this.basesMap.map[bestJdx];
|1396|1396| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1571|1571| 			let cost = queues.economicBuilding.plans[0].getCost();
|1572|1572| 			queueManager.setAccounts(gameState, cost, "economicBuilding");
|1573|1573| 			if (!queueManager.canAfford("economicBuilding", cost))
|1574|    |-			{
|    |1574|+			
|1575|1575| 				for (let q in queueManager.queues)
|1576|1576| 				{
|1577|1577| 					if (q == "economicBuilding")
|1580|1580| 					if (queueManager.canAfford("economicBuilding", cost))
|1581|1581| 						break;
|1582|1582| 				}
|1583|    |-			}
|    |1583|+			
|1584|1584| 		}
|1585|1585| 		return;
|1586|1586| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1630|1630| 		let highLevel = 0;
|1631|1631| 		let lowLevel = 0;
|1632|1632| 		for (let res in cost)
|1633|    |-		{
|    |1633|+		
|1634|1634| 			if (resources[res] && resources[res] > 0.7 * cost[res])
|1635|1635| 				++highLevel;
|1636|1636| 			else if (!resources[res] || resources[res] < 0.3 * cost[res])
|1637|1637| 				++lowLevel;
|1638|    |-		}
|    |1638|+		
|1639|1639| 		if (highLevel == 0 || lowLevel > 1)
|1640|1640| 			return;
|1641|1641| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1756|1756| 	let freeSlots = gameState.getPopulationLimit() + HouseNb*popBonus - this.getAccountedPopulation(gameState);
|1757|1757| 	let priority;
|1758|1758| 	if (freeSlots < 5)
|1759|    |-	{
|    |1759|+	
|1760|1760| 		if (this.buildManager.isUnbuildable(gameState, house))
|1761|1761| 		{
|1762|1762| 			if (this.Config.debug > 1)
|1765|1765| 		}
|1766|1766| 		else
|1767|1767| 			priority = 2*this.Config.priorities.house;
|1768|    |-	}
|    |1768|+	
|1769|1769| 	else
|1770|1770| 		priority = this.Config.priorities.house;
|1771|1771| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1847|1847| 		return;
|1848|1848| 
|1849|1849| 	if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3))))
|1850|    |-	{
|    |1850|+	
|1851|1851| 		// try to build fortresses
|1852|1852| 		if (this.canBuild(gameState, "structures/{civ}_fortress"))
|1853|1853| 		{
|1866|1866| 				return;
|1867|1867| 			}
|1868|1868| 		}
|1869|    |-	}
|    |1869|+	
|1870|1870| 
|1871|1871| 	if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower"))
|1872|1872| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2010|2010| 		nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true);
|2011|2011| 
|2012|2012| 	if (!nAdvanced || nAdvanced < this.bAdvanced.length && this.getAccountedPopulation(gameState) > 110)
|2013|    |-	{
|    |2013|+	
|2014|2014| 		for (let advanced of this.bAdvanced)
|2015|2015| 		{
|2016|2016| 			if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced))
|2025|2025| 				queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced));
|2026|2026| 			return;
|2027|2027| 		}
|2028|    |-	}
|    |2028|+	
|2029|2029| };
|2030|2030| 
|2031|2031| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2113|2113| 	// in which case we prefer melee units
|2114|2114| 	let numGarrisoned = this.garrisonManager.numberOfGarrisonedUnits(nearestAnchor);
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|    |-	{
|    |2116|+	
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|2118| 		{
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|2123| 		}
|2124|    |-	}
|    |2124|+	
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|2127|2127| 	let rangedWanted = randBool() && autogarrison;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|2116| 	{
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|    |-		{
|    |2118|+		
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2120|2120| 				numGarrisoned += item.count;
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|    |-		}
|    |2123|+		
|2124|2124| 	}
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2155|2155| 	let cost = new API3.Resources(templateFound[1].cost());
|2156|2156| 	queueManager.setAccounts(gameState, cost, "emergency");
|2157|2157| 	if (!queueManager.canAfford("emergency", cost))
|2158|    |-	{
|    |2158|+	
|2159|2159| 		for (let q in queueManager.queues)
|2160|2160| 		{
|2161|2161| 			if (q == "emergency")
|2164|2164| 			if (queueManager.canAfford("emergency", cost))
|2165|2165| 				break;
|2166|2166| 		}
|2167|    |-	}
|    |2167|+	
|2168|2168| 	let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() };
|2169|2169| 	if (autogarrison)
|2170|2170| 		metadata.garrisonType = "protection";
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2445|2445| m.HQ.prototype.assignGatherers = function()
|2446|2446| {
|2447|2447| 	for (let base of this.baseManagers)
|2448|    |-	{
|    |2448|+	
|2449|2449| 		for (let worker of base.workers.values())
|2450|2450| 		{
|2451|2451| 			if (worker.unitAIState().split(".")[1] != "RETURNRESOURCE")
|2455|2455| 				continue;
|2456|2456| 			this.AddTCGatherer(orders[1].target);
|2457|2457| 		}
|2458|    |-	}
|    |2458|+	
|2459|2459| };
|2460|2460| 
|2461|2461| m.HQ.prototype.isDangerousLocation = function(gameState, pos, radius)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2627|2627| 	{
|2628|2628| 		let pop = gameState.getPopulation();
|2629|2629| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2630|    |-		{
|    |2630|+		
|2631|2631| 			for (let item of ent.trainingQueue())
|2632|2632| 			{
|2633|2633| 				if (!item.unitTemplate)
|2636|2636| 				if (unitPop)
|2637|2637| 					pop += item.count * unitPop;
|2638|2638| 			}
|2639|    |-		}
|    |2639|+		
|2640|2640| 		this.turnCache.accountedPopulation = pop;
|2641|2641| 	}
|2642|2642| 	return this.turnCache.accountedPopulation;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2651|2651| 	{
|2652|2652| 		let workers = gameState.getOwnEntitiesByRole("worker", true).length;
|2653|2653| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2654|    |-		{
|    |2654|+		
|2655|2655| 			for (let item of ent.trainingQueue())
|2656|2656| 			{
|2657|2657| 				if (!item.metadata || !item.metadata.role || item.metadata.role != "worker")
|2658|2658| 					continue;
|2659|2659| 				workers += item.count;
|2660|2660| 			}
|2661|    |-		}
|    |2661|+		
|2662|2662| 		this.turnCache.accountedWorkers = workers;
|2663|2663| 	}
|2664|2664| 	return this.turnCache.accountedWorkers;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2689|2689| 			this.phasing = 0;
|2690|2690| 	}
|2691|2691| 
|2692|    |-/*	if (this.Config.debug > 1)
|    |2692|+	/*	if (this.Config.debug > 1)
|2693|2693| 	{
|2694|2694| 		gameState.getOwnUnits().forEach (function (ent) {
|2695|2695| 			if (!ent.position())
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2764|2764| 		this.currentBase %= this.baseManagers.length;
|2765|2765| 		activeBase = this.baseManagers[this.currentBase++].update(gameState, queues, events);
|2766|2766| 		--nbBases;
|2767|    |-// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|    |2767|+		// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|2768|2768| 	}
|2769|2769| 	while (!activeBase && nbBases != 0);
|2770|2770| 

binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2902| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.

binaries/data/mods/public/gui/session/menu.js
| 488| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 563| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 392| 392| 				// Players see colors depending on diplomacy
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395|    |-					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
|    | 395|+						g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396|    |-					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
|    | 396|+							g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397|    |-					getDiplomacyColor("enemy");
|    | 397|+								getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
| 400| 400| 	}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 644| 644| 					"civ": setStringTags(g_CivData[g_Players[g_ViewedPlayer].civ].Name, { "font": "sans-bold-stroke-14" }),
| 645| 645| 					"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
| 646| 646| 					"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
| 647|    |-			});
|    | 647|+				});
| 648| 648| 	}
| 649| 649| 
| 650| 650| 	// Following gaia can be interesting on scripted maps
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1195|1195| 
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|    |-		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|    |1198|+			"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|    |-		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|    |1199|+			"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|    |-	});
|    |1200|+		});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|1203|1203| 	for (let r = 0; r < resCodes.length; ++r)

binaries/data/mods/public/gui/session/session.js
|1056| »   let·getPanelEntNameTooltip·=·panelEntState·=>·"[font=\"sans-bold-16\"]"·+·template.name.specific·+·"[/font]";
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'panelEntState' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1131| »   »   button.onpress·=·(function(i)·{·return·function()·{·performGroup((Engine.HotkeyIsPressed("selection.add")·?·"add"·:·"select"),·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1132| »   »   button.ondoublepress·=·(function(i)·{·return·function()·{·performGroup("snap",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1133| »   »   button.onpressright·=·(function(i)·{·return·function()·{·performGroup("breakUp",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/78/display/redirect

Freagarach updated this revision to Diff 8933.Jul 16 2019, 7:13 PM

Make Jenkins/Vulcan a tad happier.

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

Linter detected issues:
Executing section Source...

source/simulation2/components/tests/test_scripts.h
|  22| class·TestComponentScripts·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestComponentScripts:' is invalid C code. Use --std or --language to configure the language.
Executing section JS...
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 392| 392| 				// Players see colors depending on diplomacy
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395|    |-					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
|    | 395|+						g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396|    |-					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
|    | 396|+							g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397|    |-					getDiplomacyColor("enemy");
|    | 397|+								getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
| 400| 400| 	}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 644| 644| 					"civ": setStringTags(g_CivData[g_Players[g_ViewedPlayer].civ].Name, { "font": "sans-bold-stroke-14" }),
| 645| 645| 					"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
| 646| 646| 					"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
| 647|    |-			});
|    | 647|+				});
| 648| 648| 	}
| 649| 649| 
| 650| 650| 	// Following gaia can be interesting on scripted maps
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1195|1195| 
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|    |-		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|    |1198|+			"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1196|1196| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|    |-		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|    |1199|+			"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|1200| 	});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1197|1197| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1198|1198| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1199|1199| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1200|    |-	});
|    |1200|+		});
|1201|1201| 
|1202|1202| 	let resCodes = g_ResourceData.GetCodes();
|1203|1203| 	for (let r = 0; r < resCodes.length; ++r)

binaries/data/mods/public/gui/session/session.js
|1056| »   let·getPanelEntNameTooltip·=·panelEntState·=>·"[font=\"sans-bold-16\"]"·+·template.name.specific·+·"[/font]";
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'panelEntState' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1131| »   »   button.onpress·=·(function(i)·{·return·function()·{·performGroup((Engine.HotkeyIsPressed("selection.add")·?·"add"·:·"select"),·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1132| »   »   button.ondoublepress·=·(function(i)·{·return·function()·{·performGroup("snap",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1133| »   »   button.onpressright·=·(function(i)·{·return·function()·{·performGroup("breakUp",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["sell"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices.sell[resourceToSell] / prices["buy"][resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["buy"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices.buy[resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['sell'] is better written in dot notation.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['buy'] is better written in dot notation.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|  82|  82| 		let tribute = {};
|  83|  83| 		let toSend = false;
|  84|  84| 		for (let res in resTribCodes)
|  85|    |-		{
|    |  85|+		
|  86|  86| 			if (donor && availableResources[res] > 200 && allyResources[res] < 0.2 * availableResources[res])
|  87|  87| 			{
|  88|  88| 				tribute[res] = Math.floor(0.3*availableResources[res] - allyResources[res]);
| 114| 114| 					}
| 115| 115| 				}
| 116| 116| 			}
| 117|    |-		}
|    | 117|+		
| 118| 118| 		if (!toSend)
| 119| 119| 			continue;
| 120| 120| 		if (this.Config.debug > 1)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 102| 102| 				if (!mostNeeded)
| 103| 103| 					mostNeeded = gameState.ai.HQ.pickMostNeededResources(gameState, resTribCodes);
| 104| 104| 				for (let k = 0; k < mostNeeded.length; ++k)
| 105|    |-				{
|    | 105|+				
| 106| 106| 					if (mostNeeded[k].type == res && mostNeeded[k].wanted > 0)
| 107| 107| 					{
| 108| 108| 						this.nextTributeRequest.set("all", gameState.ai.elapsedTime + 90);
| 112| 112| 							API3.warn("Tribute on " + res + " requested to player " + i);
| 113| 113| 						break;
| 114| 114| 					}
| 115|    |-				}
|    | 115|+				
| 116| 116| 			}
| 117| 117| 		}
| 118| 118| 		if (!toSend)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 159| 159| 			continue;
| 160| 160| 		let tributes = 0;
| 161| 161| 		for (let key in evt.amounts)
| 162|    |-		{
|    | 162|+		
| 163| 163| 			if (key === "food")
| 164| 164| 				tributes += evt.amounts[key];
| 165| 165| 			else
| 166| 166| 				tributes += 2*evt.amounts[key];
| 167|    |-		}
|    | 167|+		
| 168| 168| 		this.Config.personality.cooperative = Math.min(1, this.Config.personality.cooperative + 0.0001 * tributes);
| 169| 169| 	}
| 170| 170| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 238| 238| 
| 239| 239| 		// Our diplomacy will have changed already if the response was "accept"
| 240| 240| 		if (request.status === "waitingForTribute")
| 241|    |-		{
|    | 241|+		
| 242| 242| 			Engine.PostCommand(PlayerID, {
| 243| 243| 				"type": "tribute-request",
| 244| 244| 				"source": PlayerID,
| 246| 246| 				"resourceWanted": request.wanted,
| 247| 247| 				"resourceType": request.type
| 248| 248| 			});
| 249|    |-		}
|    | 249|+		
| 250| 250| 	}
| 251| 251| 
| 252| 252| 	// An AI player we sent a diplomacy request to demanded we send them a tribute
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 447| 447| {
| 448| 448| 	for (let [player, data] of this.receivedDiplomacyRequests)
| 449| 449| 		if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime)
| 450|    |-		{
|    | 450|+		
| 451| 451| 			if (data.sentWarning)
| 452| 452| 			{
| 453| 453| 				this.receivedDiplomacyRequests.delete(player);
| 462| 462| 					"type": data.type
| 463| 463| 				});
| 464| 464| 			}
| 465|    |-		}
|    | 465|+		
| 466| 466| };
| 467| 467| 
| 468| 468| /**

binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
| 574| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.

binaries/data/mods/public/gui/session/menu.js
| 488| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 520| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 563| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 629| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 209| 209| 	}
| 210| 210| 
| 211| 211| 	for (let evt of events.Destroy)
| 212|    |-	{
|    | 212|+	
| 213| 213| 		// Let's check we haven't lost an important building here.
| 214| 214| 		if (evt && !evt.SuccessfulFoundation && evt.entityObj && evt.metadata && evt.metadata[PlayerID] &&
| 215| 215| 			evt.metadata[PlayerID].base)
| 226| 226| 			if (evt.metadata[PlayerID].baseAnchor && evt.metadata[PlayerID].baseAnchor === true)
| 227| 227| 				base.anchorLost(gameState, ent);
| 228| 228| 		}
| 229|    |-	}
|    | 229|+	
| 230| 230| 
| 231| 231| 	for (let evt of events.EntityRenamed)
| 232| 232| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 255| 255| 			// Let's get a few units from other bases there to build this.
| 256| 256| 			let builders = this.bulkPickWorkers(gameState, newbase, 10);
| 257| 257| 			if (builders !== false)
| 258|    |-			{
|    | 258|+			
| 259| 259| 				builders.forEach(worker => {
| 260| 260| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 261| 261| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 262| 262| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 263| 263| 				});
| 264|    |-			}
|    | 264|+			
| 265| 265| 		}
| 266| 266| 		else if (ent.getMetadata(PlayerID, "base") == -2)	// anchorless base around a dock
| 267| 267| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 269| 269| 			// Let's get a few units from other bases there to build this.
| 270| 270| 			let builders = this.bulkPickWorkers(gameState, newbase, 4);
| 271| 271| 			if (builders != false)
| 272|    |-			{
|    | 272|+			
| 273| 273| 				builders.forEach(worker => {
| 274| 274| 					worker.setMetadata(PlayerID, "base", newbase.ID);
| 275| 275| 					worker.setMetadata(PlayerID, "subrole", "builder");
| 276| 276| 					worker.setMetadata(PlayerID, "target-foundation", ent.id());
| 277| 277| 				});
| 278|    |-			}
|    | 278|+			
| 279| 279| 		}
| 280| 280| 	}
| 281| 281| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 395| 395| 	}
| 396| 396| 
| 397| 397| 	for (let evt of events.TrainingFinished)
| 398|    |-	{
|    | 398|+	
| 399| 399| 		for (let entId of evt.entities)
| 400| 400| 		{
| 401| 401| 			let ent = gameState.getEntityById(entId);
| 463| 463| 					ent.moveToRange(goal[0], goal[1]);
| 464| 464| 			}
| 465| 465| 		}
| 466|    |-	}
|    | 466|+	
| 467| 467| 
| 468| 468| 	for (let evt of events.TerritoryDecayChanged)
| 469| 469| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 411| 411| 					this.garrisonManager.registerHolder(gameState, holder);
| 412| 412| 			}
| 413| 413| 			else if (ent.getMetadata(PlayerID, "garrisonType"))
| 414|    |-			{
|    | 414|+			
| 415| 415| 				// we were supposed to be autogarrisoned, but this has failed (may-be full)
| 416| 416| 				ent.setMetadata(PlayerID, "garrisonType", undefined);
| 417|    |-			}
|    | 417|+			
| 418| 418| 
| 419| 419| 			// Check if this unit is no more needed in its attack plan
| 420| 420| 			// (happen when the training ends after the attack is started or aborted)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 482| 482| 	}
| 483| 483| 
| 484| 484| 	if (addBase)
| 485|    |-	{
|    | 485|+	
| 486| 486| 		if (!this.firstBaseConfig)
| 487| 487| 		{
| 488| 488| 			// This is our first base, let us configure our starting resources
| 495| 495| 			this.saveSpace = undefined;
| 496| 496| 			this.maxFields = false;
| 497| 497| 		}
| 498|    |-	}
|    | 498|+	
| 499| 499| 
| 500| 500| 	// Then deals with decaying structures: destroy them if being lost to enemy (except in easier difficulties)
| 501| 501| 	if (this.Config.difficulty < 2)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 484| 484| 	if (addBase)
| 485| 485| 	{
| 486| 486| 		if (!this.firstBaseConfig)
| 487|    |-		{
|    | 487|+		
| 488| 488| 			// This is our first base, let us configure our starting resources
| 489| 489| 			this.configFirstBase(gameState);
| 490|    |-		}
|    | 490|+		
| 491| 491| 		else
| 492| 492| 		{
| 493| 493| 			// Let us hope this new base will fix our possible resource shortage
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
| 773| 773| 		let aValue = 0.1;
| 774| 774| 		let bValue = 0.1;
| 775| 775| 		for (let param of parameters)
| 776|    |-		{
|    | 776|+		
| 777| 777| 			if (param[0] == "strength")
| 778| 778| 			{
| 779| 779| 				aValue += m.getMaxStrength(a[1]) * param[1];
| 807| 807| 			}
| 808| 808| 			else
| 809| 809| 				API3.warn(" trainMoreUnits avec non prevu " + uneval(param));
| 810|    |-		}
|    | 810|+		
| 811| 811| 		return -aValue/aCost + bValue/bCost;
| 812| 812| 	});
| 813| 813| 	return units[0][0];
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1053|1053| 				continue;
|1054|1054| 
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|    |-			{
|    |1056|+			
|1057|1057| 				if (!accessible)
|1058|1058| 				{
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1063|1063| 				}
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|    |-			}
|    |1066|+			
|1067|1067| 
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1055|1055| 			if (minDist > maxAccessDisfavored)     // Disfavor if quite far from any allied cc
|1056|1056| 			{
|1057|1057| 				if (!accessible)
|1058|    |-				{
|    |1058|+				
|1059|1059| 					if (minDist > maxNoAccessDisfavored)
|1060|1060| 						norm *= 0.5;
|1061|1061| 					else
|1062|1062| 						norm *= 0.8;
|1063|    |-				}
|    |1063|+				
|1064|1064| 				else
|1065|1065| 					norm *= 0.5;
|1066|1066| 			}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1068|1068| 			// Not near any of our dropsite, except for oversea docks
|1069|1069| 			oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index);
|1070|1070| 			if (!oversea)
|1071|    |-			{
|    |1071|+			
|1072|1072| 				for (let dp of dpList)
|1073|1073| 				{
|1074|1074| 					let dist = API3.SquareVectorDistance(dp.pos, pos);
|1080|1080| 					else if (dist < 6400)
|1081|1081| 						norm *= 0.5;
|1082|1082| 				}
|1083|    |-			}
|    |1083|+			
|1084|1084| 			if (norm == 0)
|1085|1085| 				continue;
|1086|1086| 		}
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1094|1094| 				val += gameState.sharedScript.ccResourceMaps[res].map[j];
|1095|1095| 		val *= norm;
|1096|1096| 
|1097|    |-		// If oversea, be just above threshold to be accepted if nothing else 
|    |1097|+		// If oversea, be just above threshold to be accepted if nothing else
|1098|1098| 		if (oversea)
|1099|1099| 			val = Math.max(val, cut + 0.1);
|1100|1100| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1384|1384| 	// do not keep it if gain is too small, except if this is our first BarterMarket
|1385|1385| 	let idx;
|1386|1386| 	if (expectedGain < this.tradeManager.minimalGain)
|1387|    |-	{
|    |1387|+	
|1388|1388| 		if (template.hasClass("BarterMarket") &&
|1389|1389| 		    !gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities())
|1390|1390| 			idx = -1;	// needed by queueplanBuilding manager to keep that market
|1391|1391| 		else
|1392|1392| 			return false;
|1393|    |-	}
|    |1393|+	
|1394|1394| 	else
|1395|1395| 		idx = this.basesMap.map[bestJdx];
|1396|1396| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1571|1571| 			let cost = queues.economicBuilding.plans[0].getCost();
|1572|1572| 			queueManager.setAccounts(gameState, cost, "economicBuilding");
|1573|1573| 			if (!queueManager.canAfford("economicBuilding", cost))
|1574|    |-			{
|    |1574|+			
|1575|1575| 				for (let q in queueManager.queues)
|1576|1576| 				{
|1577|1577| 					if (q == "economicBuilding")
|1580|1580| 					if (queueManager.canAfford("economicBuilding", cost))
|1581|1581| 						break;
|1582|1582| 				}
|1583|    |-			}
|    |1583|+			
|1584|1584| 		}
|1585|1585| 		return;
|1586|1586| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1630|1630| 		let highLevel = 0;
|1631|1631| 		let lowLevel = 0;
|1632|1632| 		for (let res in cost)
|1633|    |-		{
|    |1633|+		
|1634|1634| 			if (resources[res] && resources[res] > 0.7 * cost[res])
|1635|1635| 				++highLevel;
|1636|1636| 			else if (!resources[res] || resources[res] < 0.3 * cost[res])
|1637|1637| 				++lowLevel;
|1638|    |-		}
|    |1638|+		
|1639|1639| 		if (highLevel == 0 || lowLevel > 1)
|1640|1640| 			return;
|1641|1641| 	}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1756|1756| 	let freeSlots = gameState.getPopulationLimit() + HouseNb*popBonus - this.getAccountedPopulation(gameState);
|1757|1757| 	let priority;
|1758|1758| 	if (freeSlots < 5)
|1759|    |-	{
|    |1759|+	
|1760|1760| 		if (this.buildManager.isUnbuildable(gameState, house))
|1761|1761| 		{
|1762|1762| 			if (this.Config.debug > 1)
|1765|1765| 		}
|1766|1766| 		else
|1767|1767| 			priority = 2*this.Config.priorities.house;
|1768|    |-	}
|    |1768|+	
|1769|1769| 	else
|1770|1770| 		priority = this.Config.priorities.house;
|1771|1771| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|1847|1847| 		return;
|1848|1848| 
|1849|1849| 	if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3))))
|1850|    |-	{
|    |1850|+	
|1851|1851| 		// try to build fortresses
|1852|1852| 		if (this.canBuild(gameState, "structures/{civ}_fortress"))
|1853|1853| 		{
|1866|1866| 				return;
|1867|1867| 			}
|1868|1868| 		}
|1869|    |-	}
|    |1869|+	
|1870|1870| 
|1871|1871| 	if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower"))
|1872|1872| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2010|2010| 		nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true);
|2011|2011| 
|2012|2012| 	if (!nAdvanced || nAdvanced < this.bAdvanced.length && this.getAccountedPopulation(gameState) > 110)
|2013|    |-	{
|    |2013|+	
|2014|2014| 		for (let advanced of this.bAdvanced)
|2015|2015| 		{
|2016|2016| 			if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced))
|2025|2025| 				queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced));
|2026|2026| 			return;
|2027|2027| 		}
|2028|    |-	}
|    |2028|+	
|2029|2029| };
|2030|2030| 
|2031|2031| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2113|2113| 	// in which case we prefer melee units
|2114|2114| 	let numGarrisoned = this.garrisonManager.numberOfGarrisonedUnits(nearestAnchor);
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|    |-	{
|    |2116|+	
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|2118| 		{
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|2123| 		}
|2124|    |-	}
|    |2124|+	
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|2127|2127| 	let rangedWanted = randBool() && autogarrison;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2115|2115| 	if (nearestAnchor._entity.trainingQueue)
|2116|2116| 	{
|2117|2117| 		for (let item of nearestAnchor._entity.trainingQueue)
|2118|    |-		{
|    |2118|+		
|2119|2119| 			if (item.metadata && item.metadata.garrisonType)
|2120|2120| 				numGarrisoned += item.count;
|2121|2121| 			else if (!item.progress && (!item.metadata || !item.metadata.trainer))
|2122|2122| 				nearestAnchor.stopProduction(item.id);
|2123|    |-		}
|    |2123|+		
|2124|2124| 	}
|2125|2125| 	let autogarrison = numGarrisoned < nearestAnchor.garrisonMax() &&
|2126|2126| 	                   nearestAnchor.hitpoints() > nearestAnchor.garrisonEjectHealth() * nearestAnchor.maxHitpoints();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2155|2155| 	let cost = new API3.Resources(templateFound[1].cost());
|2156|2156| 	queueManager.setAccounts(gameState, cost, "emergency");
|2157|2157| 	if (!queueManager.canAfford("emergency", cost))
|2158|    |-	{
|    |2158|+	
|2159|2159| 		for (let q in queueManager.queues)
|2160|2160| 		{
|2161|2161| 			if (q == "emergency")
|2164|2164| 			if (queueManager.canAfford("emergency", cost))
|2165|2165| 				break;
|2166|2166| 		}
|2167|    |-	}
|    |2167|+	
|2168|2168| 	let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() };
|2169|2169| 	if (autogarrison)
|2170|2170| 		metadata.garrisonType = "protection";
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2445|2445| m.HQ.prototype.assignGatherers = function()
|2446|2446| {
|2447|2447| 	for (let base of this.baseManagers)
|2448|    |-	{
|    |2448|+	
|2449|2449| 		for (let worker of base.workers.values())
|2450|2450| 		{
|2451|2451| 			if (worker.unitAIState().split(".")[1] != "RETURNRESOURCE")
|2455|2455| 				continue;
|2456|2456| 			this.AddTCGatherer(orders[1].target);
|2457|2457| 		}
|2458|    |-	}
|    |2458|+	
|2459|2459| };
|2460|2460| 
|2461|2461| m.HQ.prototype.isDangerousLocation = function(gameState, pos, radius)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2627|2627| 	{
|2628|2628| 		let pop = gameState.getPopulation();
|2629|2629| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2630|    |-		{
|    |2630|+		
|2631|2631| 			for (let item of ent.trainingQueue())
|2632|2632| 			{
|2633|2633| 				if (!item.unitTemplate)
|2636|2636| 				if (unitPop)
|2637|2637| 					pop += item.count * unitPop;
|2638|2638| 			}
|2639|    |-		}
|    |2639|+		
|2640|2640| 		this.turnCache.accountedPopulation = pop;
|2641|2641| 	}
|2642|2642| 	return this.turnCache.accountedPopulation;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2651|2651| 	{
|2652|2652| 		let workers = gameState.getOwnEntitiesByRole("worker", true).length;
|2653|2653| 		for (let ent of gameState.getOwnTrainingFacilities().values())
|2654|    |-		{
|    |2654|+		
|2655|2655| 			for (let item of ent.trainingQueue())
|2656|2656| 			{
|2657|2657| 				if (!item.metadata || !item.metadata.role || item.metadata.role != "worker")
|2658|2658| 					continue;
|2659|2659| 				workers += item.count;
|2660|2660| 			}
|2661|    |-		}
|    |2661|+		
|2662|2662| 		this.turnCache.accountedWorkers = workers;
|2663|2663| 	}
|2664|2664| 	return this.turnCache.accountedWorkers;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2689|2689| 			this.phasing = 0;
|2690|2690| 	}
|2691|2691| 
|2692|    |-/*	if (this.Config.debug > 1)
|    |2692|+	/*	if (this.Config.debug > 1)
|2693|2693| 	{
|2694|2694| 		gameState.getOwnUnits().forEach (function (ent) {
|2695|2695| 			if (!ent.position())
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 0.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2764|2764| 		this.currentBase %= this.baseManagers.length;
|2765|2765| 		activeBase = this.baseManagers[this.currentBase++].update(gameState, queues, events);
|2766|2766| 		--nbBases;
|2767|    |-// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|    |2767|+		// TODO what to do with this.reassignTerritories(this.baseManagers[this.currentBase]);
|2768|2768| 	}
|2769|2769| 	while (!activeBase && nbBases != 0);
|2770|2770| 

binaries/data/mods/public/simulation/ai/petra/headquarters.js
|2902| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.

binaries/data/mods/public/simulation/components/Player.js
| 381| »   for·(var·type·in·amounts)
|    | [NORMAL] JSHintBear:
|    | 'type' is already defined.
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '='.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 438| 438| 	let candidate = { "gain": 0 };
| 439| 439| 	let potential = { "gain": 0 };
| 440| 440| 	let bestIndex = { "gain": 0 };
| 441|    |-	let bestLand  = { "gain": 0 };
|    | 441|+	let bestLand = { "gain": 0 };
| 442| 442| 
| 443| 443| 	let mapSize = gameState.sharedScript.mapSize;
| 444| 444| 	let traderTemplatesGains = gameState.getTraderTemplatesGains();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 476| 476| 			if (m1.foundationProgress() === undefined && m2.foundationProgress() === undefined)
| 477| 477| 			{
| 478| 478| 				if (accessIndex)
| 479|    |-				{
|    | 479|+				
| 480| 480| 					if (gameState.ai.accessibility.regionType[accessIndex] == "water" && sea == accessIndex)
| 481| 481| 					{
| 482| 482| 						if (gain < bestIndex.gain)
| 495| 495| 							continue;
| 496| 496| 						bestLand = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
| 497| 497| 					}
| 498|    |-				}
|    | 498|+				
| 499| 499| 				if (gain < candidate.gain)
| 500| 500| 					continue;
| 501| 501| 				candidate = { "source": m1, "target": m2, "gain": gain, "land": land, "sea": sea };
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 615| 615| 		return;	// position found, but not enough gain compared to our present route
| 616| 616| 
| 617| 617| 	if (this.Config.debug > 1)
| 618|    |-	{
|    | 618|+	
| 619| 619| 		if (this.potentialTradeRoute)
| 620| 620| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a new route with gain " +
| 621| 621| 				marketPos[3] + " instead of the present " + this.potentialTradeRoute.gain);
| 622| 622| 		else
| 623| 623| 			API3.warn("turn " + gameState.ai.playedTurn + "we could have a first route with gain " +
| 624| 624| 				marketPos[3]);
| 625|    |-	}
|    | 625|+	
| 626| 626| 
| 627| 627| 	if (!this.tradeRoute)
| 628| 628| 		gameState.ai.queueManager.changePriority("economicBuilding", 2*this.Config.priorities.economicBuilding);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 680| 680| 
| 681| 681| 	let ret = {};
| 682| 682| 	for (let key in route)
| 683|    |-	{
|    | 683|+	
| 684| 684| 		if (key == "source" || key == "target")
| 685| 685| 		{
| 686| 686| 			if (!route[key])
| 689| 689| 		}
| 690| 690| 		else
| 691| 691| 			ret[key] = route[key];
| 692|    |-	}
|    | 692|+	
| 693| 693| 	return ret;
| 694| 694| };
| 695| 695| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 700| 700| 
| 701| 701| 	let ret = {};
| 702| 702| 	for (let key in route)
| 703|    |-	{
|    | 703|+	
| 704| 704| 		if (key == "source" || key == "target")
| 705| 705| 		{
| 706| 706| 			ret[key] = gameState.getEntityById(route[key]);
| 709| 709| 		}
| 710| 710| 		else
| 711| 711| 			ret[key] = route[key];
| 712|    |-	}
|    | 712|+	
| 713| 713| 	return ret;
| 714| 714| };
| 715| 715| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 727| 727| m.TradeManager.prototype.Deserialize = function(gameState, data)
| 728| 728| {
| 729| 729| 	for (let key in data)
| 730|    |-	{
|    | 730|+	
| 731| 731| 		if (key == "tradeRoute" || key == "potentialTradeRoute")
| 732| 732| 			this[key] = this.routeIdToEnt(gameState, data[key]);
| 733| 733| 		else
| 734| 734| 			this[key] = data[key];
| 735|    |-	}
|    | 735|+	
| 736| 736| };
| 737| 737| 
| 738| 738| return m;

binaries/data/mods/public/simulation/ai/petra/tradeManager.js
| 739| }(PETRA);
|    | [MAJOR] ESLintBear (no-use-before-define):
|    | 'PETRA' was used before it was defined.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/98/display/redirect

Silier added inline comments.Jul 22 2019, 1:15 PM
binaries/data/mods/public/gui/session/menu.js
773

!!! Bartable Codes empty -> out of bounds

binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
69

could you move this after resTribCodes.length check ?

70

same

412

will pickMostNeededResources return non empty array always? else I see out of bounds

Freagarach updated this revision to Diff 9062.Jul 22 2019, 6:31 PM
Freagarach marked 5 inline comments as done.

Prevent out of bounds.

binaries/data/mods/public/gui/session/menu.js
773

Hmm, no error is shown. But I'll fix it anyways.
That might be why @Stan suggested find.

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/192/display/redirect

Builds and tests are green on windows.

Globalscript test: refs. D151.

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

Link to build: https://jenkins.wildfiregames.com/job/vs2015-differential/241/display/redirect

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

Linter detected issues:
Executing section Source...

source/simulation2/components/tests/test_scripts.h
|  22| class·TestComponentScripts·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestComponentScripts:' is invalid C code. Use --std or --language to configure the language.
Executing section JS...

binaries/data/mods/public/gui/session/menu.js
| 475| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 507| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 507| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 507| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 550| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 616| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 616| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 392| 392| 				// Players see colors depending on diplomacy
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395|    |-					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
|    | 395|+						g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 393| 393| 				g_DisplayedPlayerColors[i] =
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396|    |-					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
|    | 396|+							g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397| 397| 					getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 394| 394| 					g_ViewedPlayer == i ? getDiplomacyColor("self") :
| 395| 395| 					g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
| 396| 396| 					g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
| 397|    |-					getDiplomacyColor("enemy");
|    | 397|+								getDiplomacyColor("enemy");
| 398| 398| 
| 399| 399| 		g_DisplayedPlayerColors[0] = g_Players[0].color;
| 400| 400| 	}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
| 656| 656| 					"civ": setStringTags(g_CivData[g_Players[g_ViewedPlayer].civ].Name, { "font": "sans-bold-stroke-14" }),
| 657| 657| 					"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
| 658| 658| 					"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
| 659|    |-			});
|    | 659|+				});
| 660| 660| 	}
| 661| 661| 
| 662| 662| 	// Following gaia can be interesting on scripted maps
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1212|1212| 
|1213|1213| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1214|1214| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1215|    |-		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|    |1215|+			"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1216|1216| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1217|1217| 	});
|1218|1218| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1213|1213| 	let orderHotkeyTooltip = Object.keys(viewablePlayerStates).length <= 1 ? "" :
|1214|1214| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1215|1215| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1216|    |-		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|    |1216|+			"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1217|1217| 	});
|1218|1218| 
|1219|1219| 	let resCodes = g_ResourceData.GetCodes();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/session.js
|1214|1214| 		"\n" + sprintf(translate("%(order)s: %(hotkey)s to change order."), {
|1215|1215| 		"hotkey": setStringTags("\\[Click]", g_HotkeyTags),
|1216|1216| 		"order": tooltipSort == 0 ? translate("Unordered") : tooltipSort == 1 ? translate("Descending") : translate("Ascending")
|1217|    |-	});
|    |1217|+		});
|1218|1218| 
|1219|1219| 	let resCodes = g_ResourceData.GetCodes();
|1220|1220| 	for (let r = 0; r < resCodes.length; ++r)

binaries/data/mods/public/gui/session/session.js
|1073| »   let·getPanelEntNameTooltip·=·panelEntState·=>·"[font=\"sans-bold-16\"]"·+·template.name.specific·+·"[/font]";
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'panelEntState' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1148| »   »   button.onpress·=·(function(i)·{·return·function()·{·performGroup((Engine.HotkeyIsPressed("selection.add")·?·"add"·:·"select"),·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1149| »   »   button.ondoublepress·=·(function(i)·{·return·function()·{·performGroup("snap",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/session.js
|1150| »   »   button.onpressright·=·(function(i)·{·return·function()·{·performGroup("breakUp",·i);·};·})(i);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["sell"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices.sell[resourceToSell] / prices["buy"][resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers
|    | [NORMAL] ESLintBear (dot-notation):
|    | ["buy"] is better written in dot notation.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/Barter.js
|  95|  95| 	amountsToSubtract[resourceToSell] = amount;
|  96|  96| 	if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|  97|  97| 	{
|  98|    |-		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|    |  98|+		var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices.buy[resourceToBuy] * amount);
|  99|  99| 		cmpPlayer.AddResource(resourceToBuy, amountToAdd);
| 100| 100| 
| 101| 101| 		// Display chat message to observers

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['sell'] is better written in dot notation.

binaries/data/mods/public/simulation/components/Barter.js
|  98| »   »   var·amountToAdd·=·Math.round(prices["sell"][resourceToSell]·/·prices["buy"][resourceToBuy]·*·amount);
|    | [NORMAL] JSHintBear:
|    | ['buy'] is better written in dot notation.
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/Player.js
| 381| »   for·(var·type·in·amounts)
|    | [NORMAL] JSHintBear:
|    | 'type' is already defined.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/753/display/redirect

Silier accepted this revision.Sep 19 2019, 5:06 PM

Builds, tests passed, jenkins tests are ok, feature looks good, I do not see more problems in code

wraitii accepted this revision.Sep 22 2019, 9:44 AM

Works fine and I think this is nice enough right now, making the game more moddable with little added complexity. The question of extending JSON files will have to be tackled some day but so far I don't have a good answer.

This revision is now accepted and ready to land.Sep 22 2019, 9:44 AM

Following discussions on IRC, I think we should go back very slightly to your initial diff.
Instead of having a GetCodes take a parameter and filter on property, explicitly write GetBarterableCodes, GetTradableCodes, GetTributableCodes, and return values on that property or empty.

But then 0ad code isn't an example of how mods should do it. Modders who take 0ad code as an example will then introduce getters as well, in which case one could have used properties directly.

Thanks for the review all and for commiting this @wraitii!