Page MenuHomeWildfire Games

match unit classes with templates
ClosedPublic

Authored by Nescio on Apr 4 2019, 2:39 PM.

Details

Summary

Currently we have Archer and Maceman classes on the one hand, but Javelin and Spear. For consistency and to make things more straightforward for future additions, it would be good if classes match their templates, e.g. template_unit_infantry_ranged_slinger.xml has Slinger (and not Sling) class.

This patch:

  • removes Spear class from pikemen templates
  • renames:
    • Axe → Axeman
    • Javelin → Javelinist
    • Pike → Pikeman
    • Sling → Slinger
    • Spear → Spearman
    • Sword → Swordsman
  • corrects other simulation files accordingly
  • updates the components/Identity.js file

[EDIT]:

  • gave the gastraphetes a Crossbowman class
  • gave the clubman a Clubman class
  • Catapult → StoneThrower
  • made FishingBoat a visible class
  • introduced Bireme, Trireme, and Quinquereme visible classes
  • removed incorrect Melee class from maur_trireme.xml
  • moved Organic class to template_unit.xml, because most of its children have it; cf. ConquestCritical class
  • list <VisibleClasses> directly after <Classes>
Test Plan

Check nothing is overlooked and everything still works.

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Nescio updated this revision to Diff 7665.Apr 4 2019, 2:59 PM
Nescio edited the summary of this revision. (Show Details)
Vulcan added a comment.Apr 4 2019, 3:01 PM

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|  97|  97| 	this.visibleClassesList = GetVisibleIdentityClasses(this.template);
|  98|  98| };
|  99|  99| 
| 100|    |-Identity.prototype.Deserialize = function ()
|    | 100|+Identity.prototype.Deserialize = function()
| 101| 101| {
| 102| 102| 	this.Init();
| 103| 103| };
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A" }, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B" }, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C" }] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A" }, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B" }, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C" }] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  10|  10| 
|  11|  11| 	var ret = {};
|  12|  12| 	for (var i in this)
|  13|    |-	{
|    |  13|+	
|  14|  14| 		if (this.hasOwnProperty(i))
|  15|  15| 			ret[i] = this[i];
|  16|    |-	}
|    |  16|+	
|  17|  17| 	ret.modificationCache = {};
|  18|  18| 	return ret;
|  19|  19| };
|    | [NORMAL] ESLintBear (operator-linebreak):
|    | '||' should be placed at the end of the line.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  64|  64| 	for (let key of this.unresearchedAutoResearchTechs)
|  65|  65| 	{
|  66|  66| 		let tech = TechnologyTemplates.Get(key);
|  67|    |-		if ((tech.autoResearch && this.CanResearch(key))
|  68|    |-			|| (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|    |  67|+		if ((tech.autoResearch && this.CanResearch(key)) ||
|    |  68|+			(tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|  69|  69| 		{
|  70|  70| 			this.unresearchedAutoResearchTechs.delete(key);
|  71|  71| 			this.ResearchTechnology(key);
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  75|  75| };
|  76|  76| 
|  77|  77| // Checks an entity template to see if its technology requirements have been met
|  78|    |-TechnologyManager.prototype.CanProduce = function (templateName)
|    |  78|+TechnologyManager.prototype.CanProduce = function(templateName)
|  79|  79| {
|  80|  80| 	var cmpTempManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
|  81|  81| 	var template = cmpTempManager.GetTemplate(templateName);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 193| 193| 		var classes = cmpIdentity.GetClassesList();
| 194| 194| 		// don't use foundations for the class counts but check if techs apply (e.g. health increase)
| 195| 195| 		if (!Engine.QueryInterface(msg.entity, IID_Foundation))
| 196|    |-		{
|    | 196|+		
| 197| 197| 			for (let cls of classes)
| 198| 198| 			{
| 199| 199| 				this.classCounts[cls] = this.classCounts[cls] || 0;
| 203| 203| 				this.typeCountsByClass[cls][template] = this.typeCountsByClass[cls][template] || 0;
| 204| 204| 				this.typeCountsByClass[cls][template] += 1;
| 205| 205| 			}
| 206|    |-		}
|    | 206|+		
| 207| 207| 
| 208| 208| 		// Newly created entity, check if any researched techs might apply
| 209| 209| 		// (only do this for new entities because even if an entity is converted or captured,
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 286| 286| 	}
| 287| 287| 
| 288| 288| 	if (template.replaces && template.replaces.length > 0)
| 289|    |-	{
|    | 289|+	
| 290| 290| 		for (var i of template.replaces)
| 291| 291| 		{
| 292| 292| 			if (!i || this.IsTechnologyResearched(i))
| 304| 304| 					cmpPlayerEntityLimits.UpdateLimitsFromTech(i);
| 305| 305| 			}
| 306| 306| 		}
| 307|    |-	}
|    | 307|+	
| 308| 308| 
| 309| 309| 	this.UpdateAutoResearch();
| 310| 310| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, { "player": playerID, "tech": tech});
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech });
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329|    |-		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
|    | 329|+		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component] });
| 330| 330| 		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
| 331| 331| 	}
| 332| 332| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329| 329| 		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
| 330|    |-		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
|    | 330|+		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component] });
| 331| 331| 	}
| 332| 332| 
| 333| 333| 	if (tech.startsWith("phase") && !template.autoResearch)
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 449| 449|  */
| 450| 450| TechnologyManager.prototype.GetResearcher = function(tech)
| 451| 451| {
| 452|    |-	return this.researchQueued.get(tech)
|    | 452|+	return this.researchQueued.get(tech);
| 453| 453| };
| 454| 454| 
| 455| 455| /**

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 150| »   »   »   switch·(type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 165| »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 220| ·»   »   »   »   »   if·(DoesModificationApply(modif,·classes))
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/simulation/components/TechnologyManager.js
|  68| »   »   »   ||·(tech.top·&&·(this.IsTechnologyResearched(tech.top)·||·this.IsTechnologyResearched(tech.bottom))))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '||'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 229| »   »   »   for·(var·component·in·modifiedComponents)
|    | [NORMAL] JSHintBear:
|    | 'component' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 235| »   »   var·cmpTemplateManager·=·Engine.QueryInterface(SYSTEM_ENTITY,·IID_TemplateManager);
|    | [NORMAL] JSHintBear:
|    | 'cmpTemplateManager' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 236| »   »   var·template·=·cmpTemplateManager.GetCurrentTemplateName(msg.entity);
|    | [NORMAL] JSHintBear:
|    | 'template' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 241| »   »   »   var·cmpIdentity·=·Engine.QueryInterface(msg.entity,·IID_Identity);
|    | [NORMAL] JSHintBear:
|    | 'cmpIdentity' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 244| »   »   »   »   var·classes·=·cmpIdentity.GetClassesList();
|    | [NORMAL] JSHintBear:
|    | 'classes' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 452| »   return·this.researchQueued.get(tech)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
Executing section cli...

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

bb added a comment.Apr 15 2019, 8:57 PM

Renamings of spear => spearman and co is good imo (wasn't there some earlier revision where it was discussed?)

didn't check for completeness (yet)

binaries/data/mods/public/simulation/data/auras/units/heroes/spart_hero_brasidas.json
4–5

removing it from females and slaves, according to the description

binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_pikeman.xml
29

Removing Spear(man) means that the techs won't apply anymore, don't think you wanted to do that. One could either leave the spear class, or add pikes in all relevant techs

binaries/data/mods/public/simulation/templates/units/athen_champion_ranged_gastraphetes.xml
23 ↗(On Diff #7665)

Don't know how it is in english, but in dutch an "crossbowman" (kruisboogschutter) would also be an "archer" (boogschutter), so shouldn't both classes be present?

binaries/data/mods/public/simulation/templates/units/kush_champion_infantry_apedemak.xml
26

Same comment as for spears vs pikes holds here too

binaries/data/mods/public/simulation/templates/units/kush_infantry_clubman_b.xml
36

same

(wasn't there some earlier revision where it was discussed?)

Yes, D1036.

binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_pikeman.xml
29

Actually it's intentional. There are a number of technologies affecting spearmen, but most are unused (see D1775), only spartans_agoge.json matters, but Sparta can't train any pikemen, therefore I think it's proper to remove the Spear class from pikemen.

binaries/data/mods/public/simulation/templates/units/athen_champion_ranged_gastraphetes.xml
23 ↗(On Diff #7665)

In many languages, including English, a javelin is a spear, yet we don't add the Spearman class to Javelin templates.
Similarily, it's better to separate crossbowmen from archers; having only one weapon-class per template simplifies things (e.g. technologies: ["Archer !Crossbowman"] is ugly).

binaries/data/mods/public/simulation/templates/units/kush_champion_infantry_apedemak.xml
26

Again, intentional. Civs that have sword-technologies (iber, maur attack_steel_working.js) don't have axemen, and factions with axemen don't have sword technologies.

binaries/data/mods/public/simulation/templates/units/kush_infantry_clubman_b.xml
36

A club is not a sword.

wraitii requested changes to this revision.EditedApr 22 2019, 9:24 AM
wraitii added a subscriber: wraitii.

Care to do the siege units as well? If not, I'll un-request changes.

This revision now requires changes to proceed.Apr 22 2019, 9:24 AM
Nescio updated this revision to Diff 7801.Apr 22 2019, 12:51 PM
Nescio edited the summary of this revision. (Show Details)

Also updated siege and ship classes.

Owners added a subscriber: Restricted Owners Package.Apr 22 2019, 12:51 PM

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|  97|  97| 	this.visibleClassesList = GetVisibleIdentityClasses(this.template);
|  98|  98| };
|  99|  99| 
| 100|    |-Identity.prototype.Deserialize = function ()
|    | 100|+Identity.prototype.Deserialize = function()
| 101| 101| {
| 102| 102| 	this.Init();
| 103| 103| };
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  10|  10| 
|  11|  11| 	var ret = {};
|  12|  12| 	for (var i in this)
|  13|    |-	{
|    |  13|+	
|  14|  14| 		if (this.hasOwnProperty(i))
|  15|  15| 			ret[i] = this[i];
|  16|    |-	}
|    |  16|+	
|  17|  17| 	ret.modificationCache = {};
|  18|  18| 	return ret;
|  19|  19| };
|    | [NORMAL] ESLintBear (operator-linebreak):
|    | '||' should be placed at the end of the line.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  64|  64| 	for (let key of this.unresearchedAutoResearchTechs)
|  65|  65| 	{
|  66|  66| 		let tech = TechnologyTemplates.Get(key);
|  67|    |-		if ((tech.autoResearch && this.CanResearch(key))
|  68|    |-			|| (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|    |  67|+		if ((tech.autoResearch && this.CanResearch(key)) ||
|    |  68|+			(tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|  69|  69| 		{
|  70|  70| 			this.unresearchedAutoResearchTechs.delete(key);
|  71|  71| 			this.ResearchTechnology(key);
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  75|  75| };
|  76|  76| 
|  77|  77| // Checks an entity template to see if its technology requirements have been met
|  78|    |-TechnologyManager.prototype.CanProduce = function (templateName)
|    |  78|+TechnologyManager.prototype.CanProduce = function(templateName)
|  79|  79| {
|  80|  80| 	var cmpTempManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
|  81|  81| 	var template = cmpTempManager.GetTemplate(templateName);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 193| 193| 		var classes = cmpIdentity.GetClassesList();
| 194| 194| 		// don't use foundations for the class counts but check if techs apply (e.g. health increase)
| 195| 195| 		if (!Engine.QueryInterface(msg.entity, IID_Foundation))
| 196|    |-		{
|    | 196|+		
| 197| 197| 			for (let cls of classes)
| 198| 198| 			{
| 199| 199| 				this.classCounts[cls] = this.classCounts[cls] || 0;
| 203| 203| 				this.typeCountsByClass[cls][template] = this.typeCountsByClass[cls][template] || 0;
| 204| 204| 				this.typeCountsByClass[cls][template] += 1;
| 205| 205| 			}
| 206|    |-		}
|    | 206|+		
| 207| 207| 
| 208| 208| 		// Newly created entity, check if any researched techs might apply
| 209| 209| 		// (only do this for new entities because even if an entity is converted or captured,
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 286| 286| 	}
| 287| 287| 
| 288| 288| 	if (template.replaces && template.replaces.length > 0)
| 289|    |-	{
|    | 289|+	
| 290| 290| 		for (var i of template.replaces)
| 291| 291| 		{
| 292| 292| 			if (!i || this.IsTechnologyResearched(i))
| 304| 304| 					cmpPlayerEntityLimits.UpdateLimitsFromTech(i);
| 305| 305| 			}
| 306| 306| 		}
| 307|    |-	}
|    | 307|+	
| 308| 308| 
| 309| 309| 	this.UpdateAutoResearch();
| 310| 310| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, { "player": playerID, "tech": tech});
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech });
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329|    |-		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
|    | 329|+		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component] });
| 330| 330| 		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
| 331| 331| 	}
| 332| 332| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329| 329| 		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
| 330|    |-		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
|    | 330|+		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component] });
| 331| 331| 	}
| 332| 332| 
| 333| 333| 	if (tech.startsWith("phase") && !template.autoResearch)
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 449| 449|  */
| 450| 450| TechnologyManager.prototype.GetResearcher = function(tech)
| 451| 451| {
| 452|    |-	return this.researchQueued.get(tech)
|    | 452|+	return this.researchQueued.get(tech);
| 453| 453| };
| 454| 454| 
| 455| 455| /**

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 150| »   »   »   switch·(type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 165| »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 220| ·»   »   »   »   »   if·(DoesModificationApply(modif,·classes))
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/simulation/components/TechnologyManager.js
|  68| »   »   »   ||·(tech.top·&&·(this.IsTechnologyResearched(tech.top)·||·this.IsTechnologyResearched(tech.bottom))))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '||'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 229| »   »   »   for·(var·component·in·modifiedComponents)
|    | [NORMAL] JSHintBear:
|    | 'component' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 235| »   »   var·cmpTemplateManager·=·Engine.QueryInterface(SYSTEM_ENTITY,·IID_TemplateManager);
|    | [NORMAL] JSHintBear:
|    | 'cmpTemplateManager' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 236| »   »   var·template·=·cmpTemplateManager.GetCurrentTemplateName(msg.entity);
|    | [NORMAL] JSHintBear:
|    | 'template' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 241| »   »   »   var·cmpIdentity·=·Engine.QueryInterface(msg.entity,·IID_Identity);
|    | [NORMAL] JSHintBear:
|    | 'cmpIdentity' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 244| »   »   »   »   var·classes·=·cmpIdentity.GetClassesList();
|    | [NORMAL] JSHintBear:
|    | 'classes' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 452| »   return·this.researchQueued.get(tech)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A" }, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B" }, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C" }] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A" }, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B" }, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C" }] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|  52|  52| 		}
|  53|  53| 	}
|  54|  54| 	for (let enemy in attackingArmies)
|  55|    |-	{
|    |  55|+	
|  56|  56| 		for (let ally in attackingArmies[enemy])
|  57|  57| 		{
|  58|  58| 			if (this.attackedAllies[ally] === undefined)
|  59|  59| 				this.attackedAllies[ally] = 0;
|  60|  60| 			this.attackedAllies[ally] += 1;
|  61|  61| 		}
|  62|    |-	}
|    |  62|+	
|  63|  63| 	this.checkEnemyArmies(gameState);
|  64|  64| 	this.checkEnemyUnits(gameState);
|  65|  65| 	this.assignDefenders(gameState);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|  70|  70| m.DefenseManager.prototype.makeIntoArmy = function(gameState, entityID, type = "default")
|  71|  71| {
|  72|  72| 	if (type == "default")
|  73|    |-	{
|    |  73|+	
|  74|  74| 		// Try to add it to an existing army.
|  75|  75| 		for (let army of this.armies)
|  76|  76| 			if (army.getType() == type && army.addFoe(gameState, entityID))
|  77|  77| 				return;	// over
|  78|    |-	}
|    |  78|+	
|  79|  79| 
|  80|  80| 	// Create a new army for it.
|  81|  81| 	let army = new m.DefenseArmy(gameState, [entityID], type);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 179| 179| 		if (territoryOwner != PlayerID && this.attackedAllies[territoryOwner] &&
| 180| 180| 		                                  this.attackedAllies[territoryOwner] > 1 &&
| 181| 181| 		                                  this.GetCooperationLevel(territoryOwner) > 0.7)
| 182|    |-		{
|    | 182|+		
| 183| 183| 			for (let building of gameState.getAllyStructures(territoryOwner).values())
| 184| 184| 			{
| 185| 185| 				if (building.foundationProgress() == 0 ||
| 188| 188| 				if (!this.territoryMap.isBlinking(building.position()))
| 189| 189| 					return true;
| 190| 190| 			}
| 191|    |-		}
|    | 191|+		
| 192| 192| 
| 193| 193| 		// Update the number of enemies attacking this ally
| 194| 194| 		let enemy = entity.owner();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 211| 211| 	if (i == PlayerID)
| 212| 212| 	{
| 213| 213| 		if (!this.armies.length)
| 214|    |-		{
|    | 214|+		
| 215| 215| 			// check if we can recover capture points from any of our notdecaying structures
| 216| 216| 			for (let ent of gameState.getOwnStructures().values())
| 217| 217| 			{
| 229| 229| 				this.makeIntoArmy(gameState, ent.id(), "capturing");
| 230| 230| 				break;
| 231| 231| 			}
| 232|    |-		}
|    | 232|+		
| 233| 233| 		return;
| 234| 234| 	}
| 235| 235| 	else if (!gameState.isPlayerEnemy(i))
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 328| 328| 		if (!gameState.isPlayerEnemy(owner))
| 329| 329| 		{
| 330| 330| 			if (gameState.isPlayerMutualAlly(owner))
| 331|    |-			{
|    | 331|+			
| 332| 332| 				// update the number of enemies attacking this ally
| 333| 333| 				for (let id of army.foeEntities)
| 334| 334| 				{
| 343| 343| 					this.attackingArmies[enemy][owner] += 1;
| 344| 344| 					break;
| 345| 345| 				}
| 346|    |-			}
|    | 346|+			
| 347| 347| 			continue;
| 348| 348| 		}
| 349| 349| 		else if (owner != 0)   // enemy army back in its territory
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 530| 530| 		army.checkEvents(gameState, events);
| 531| 531| 
| 532| 532| 	for (let evt of events.OwnershipChanged)   // capture events
| 533|    |-	{
|    | 533|+	
| 534| 534| 		if (gameState.isPlayerMutualAlly(evt.from) && evt.to > 0)
| 535| 535| 		{
| 536| 536| 			let ent = gameState.getEntityById(evt.entity);
| 537| 537| 			if (ent && ent.hasClass("CivCentre")) // one of our cc has been captured
| 538| 538| 				gameState.ai.HQ.attackManager.switchDefenseToAttack(gameState, ent, { "range": 150 });
| 539| 539| 		}
| 540|    |-	}
|    | 540|+	
| 541| 541| 
| 542| 542| 	let allAttacked = {};
| 543| 543| 	for (let evt of events.Attacked)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 552| 552| 		let attacker = gameState.getEntityById(evt.attacker);
| 553| 553| 		if (attacker && gameState.isEntityOwn(attacker) && gameState.isEntityEnemy(target) && !attacker.hasClass("Ship") &&
| 554| 554| 		   (!target.hasClass("Structure") || target.attackRange("Ranged")))
| 555|    |-		{
|    | 555|+		
| 556| 556| 			// If enemies are in range of one of our defensive structures, garrison it for arrow multiplier
| 557| 557| 			// (enemy non-defensive structure are not considered to stay in sync with garrisonManager)
| 558| 558| 			if (attacker.position() && attacker.isGarrisonHolder() && attacker.getArrowMultiplier() &&
| 559| 559| 			    (target.owner() != 0 || !target.hasClass("Unit") ||
| 560| 560| 			     target.unitAIState() && target.unitAIState().split(".")[1] == "COMBAT"))
| 561| 561| 				this.garrisonUnitsInside(gameState, attacker, { "attacker": target });
| 562|    |-		}
|    | 562|+		
| 563| 563| 
| 564| 564| 		if (!gameState.isEntityOwn(target))
| 565| 565| 			continue;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 756| 756| 	let typeGarrison = data.type || "protection";
| 757| 757| 	let allowMelee = gameState.ai.HQ.garrisonManager.allowMelee(target);
| 758| 758| 	if (allowMelee === undefined)
| 759|    |-	{
|    | 759|+	
| 760| 760| 		// Should be kept in sync with garrisonManager to avoid garrisoning-ungarrisoning some units
| 761| 761| 		if (data.attacker)
| 762| 762| 			allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !m.isSiegeUnit(data.attacker);
| 763| 763| 		else
| 764| 764| 			allowMelee = true;
| 765|    |-	}
|    | 765|+	
| 766| 766| 	let units = gameState.getOwnUnits().filter(ent => {
| 767| 767| 		if (!ent.position())
| 768| 768| 			return false;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|  62|  62| 		targetPlayer = evt.player;
|  63|  63| 		let available = 0;
|  64|  64| 		for (let attackType in this.upcomingAttacks)
|  65|    |-		{
|    |  65|+		
|  66|  66| 			for (let attack of this.upcomingAttacks[attackType])
|  67|  67| 			{
|  68|  68| 				if (attack.state === "completing")
|  79|  79| 				if (attack.unitCollection.length > 2)
|  80|  80| 					available += attack.unitCollection.length;
|  81|  81| 			}
|  82|    |-		}
|    |  82|+		
|  83|  83| 
|  84|  84| 		if (available > 12)	// launch the attack immediately
|  85|  85| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|  84|  84| 		if (available > 12)	// launch the attack immediately
|  85|  85| 		{
|  86|  86| 			for (let attackType in this.upcomingAttacks)
|  87|    |-			{
|    |  87|+			
|  88|  88| 				for (let attack of this.upcomingAttacks[attackType])
|  89|  89| 				{
|  90|  90| 					if (attack.state === "completing" ||
|  94|  94| 					attack.forceStart();
|  95|  95| 					attack.requested = true;
|  96|  96| 				}
|  97|    |-			}
|    |  97|+			
|  98|  98| 			answer = "join";
|  99|  99| 		}
| 100| 100| 		else if (other !== undefined)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 105| 105| 		m.chatAnswerRequestAttack(gameState, targetPlayer, answer, other);
| 106| 106| 
| 107| 107| 	for (let evt of events.EntityRenamed)	// take care of packing units in bombing attacks
| 108|    |-	{
|    | 108|+	
| 109| 109| 		for (let [targetId, unitIds] of this.bombingAttacks)
| 110| 110| 		{
| 111| 111| 			if (targetId == evt.entity)
| 119| 119| 				unitIds.delete(evt.entity);
| 120| 120| 			}
| 121| 121| 		}
| 122|    |-	}
|    | 122|+	
| 123| 123| };
| 124| 124| 
| 125| 125| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 107| 107| 	for (let evt of events.EntityRenamed)	// take care of packing units in bombing attacks
| 108| 108| 	{
| 109| 109| 		for (let [targetId, unitIds] of this.bombingAttacks)
| 110|    |-		{
|    | 110|+		
| 111| 111| 			if (targetId == evt.entity)
| 112| 112| 			{
| 113| 113| 				this.bombingAttacks.set(evt.newentity, unitIds);
| 118| 118| 				unitIds.add(evt.newentity);
| 119| 119| 				unitIds.delete(evt.entity);
| 120| 120| 			}
| 121|    |-		}
|    | 121|+		
| 122| 122| 	}
| 123| 123| };
| 124| 124| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 186| 186| 			let x;
| 187| 187| 			let z;
| 188| 188| 			if (struct.hasClass("Field"))
| 189|    |-			{
|    | 189|+			
| 190| 190| 				if (!struct.resourceSupplyNumGatherers() ||
| 191| 191| 				    !gameState.isPlayerEnemy(gameState.ai.HQ.territoryMap.getOwner(structPos)))
| 192| 192| 					continue;
| 193|    |-			}
|    | 193|+			
| 194| 194| 			let dist = API3.VectorDistance(entPos, structPos);
| 195| 195| 			if (dist > range)
| 196| 196| 			{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 254| 254| 
| 255| 255| 	let unexecutedAttacks = { "Rush": 0, "Raid": 0, "Attack": 0, "HugeAttack": 0 };
| 256| 256| 	for (let attackType in this.upcomingAttacks)
| 257|    |-	{
|    | 257|+	
| 258| 258| 		for (let i = 0; i < this.upcomingAttacks[attackType].length; ++i)
| 259| 259| 		{
| 260| 260| 			let attack = this.upcomingAttacks[attackType][i];
| 293| 293| 				this.upcomingAttacks[attackType].splice(i--, 1);
| 294| 294| 			}
| 295| 295| 		}
| 296|    |-	}
|    | 296|+	
| 297| 297| 
| 298| 298| 	for (let attackType in this.startedAttacks)
| 299| 299| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 296| 296| 	}
| 297| 297| 
| 298| 298| 	for (let attackType in this.startedAttacks)
| 299|    |-	{
|    | 299|+	
| 300| 300| 		for (let i = 0; i < this.startedAttacks[attackType].length; ++i)
| 301| 301| 		{
| 302| 302| 			let attack = this.startedAttacks[attackType][i];
| 313| 313| 				this.startedAttacks[attackType].splice(i--, 1);
| 314| 314| 			}
| 315| 315| 		}
| 316|    |-	}
|    | 316|+	
| 317| 317| 
| 318| 318| 	// creating plans after updating because an aborted plan might be reused in that case.
| 319| 319| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 339| 339| 	else if (unexecutedAttacks.Attack == 0 && unexecutedAttacks.HugeAttack == 0 &&
| 340| 340| 		this.startedAttacks.Attack.length + this.startedAttacks.HugeAttack.length < Math.min(2, 1 + Math.round(gameState.getPopulationMax()/100)) &&
| 341| 341| 		(this.startedAttacks.Attack.length + this.startedAttacks.HugeAttack.length == 0 || gameState.getPopulationMax() - gameState.getPopulation() > 12))
| 342|    |-	{
|    | 342|+	
| 343| 343| 		if (barracksNb >= 1 && (gameState.currentPhase() > 1 || gameState.isResearching(gameState.getPhaseName(2))) ||
| 344| 344| 			!gameState.ai.HQ.baseManagers[1])	// if we have no base ... nothing else to do than attack
| 345| 345| 		{
| 357| 357| 			}
| 358| 358| 			this.attackNumber++;
| 359| 359| 		}
| 360|    |-	}
|    | 360|+	
| 361| 361| 
| 362| 362| 	if (unexecutedAttacks.Raid === 0 && gameState.ai.HQ.defenseManager.targetList.length)
| 363| 363| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 383| 383| m.AttackManager.prototype.getPlan = function(planName)
| 384| 384| {
| 385| 385| 	for (let attackType in this.upcomingAttacks)
| 386|    |-	{
|    | 386|+	
| 387| 387| 		for (let attack of this.upcomingAttacks[attackType])
| 388| 388| 			if (attack.getName() == planName)
| 389| 389| 				return attack;
| 390|    |-	}
|    | 390|+	
| 391| 391| 	for (let attackType in this.startedAttacks)
| 392| 392| 	{
| 393| 393| 		for (let attack of this.startedAttacks[attackType])
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 389| 389| 				return attack;
| 390| 390| 	}
| 391| 391| 	for (let attackType in this.startedAttacks)
| 392|    |-	{
|    | 392|+	
| 393| 393| 		for (let attack of this.startedAttacks[attackType])
| 394| 394| 			if (attack.getName() == planName)
| 395| 395| 				return attack;
| 396|    |-	}
|    | 396|+	
| 397| 397| 	return undefined;
| 398| 398| };
| 399| 399| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 465| 465| 		veto[i] = true;
| 466| 466| 	// No rush if enemy too well defended (i.e. iberians)
| 467| 467| 	if (attack.type == "Rush")
| 468|    |-	{
|    | 468|+	
| 469| 469| 		for (let i = 1; i < gameState.sharedScript.playersData.length; ++i)
| 470| 470| 		{
| 471| 471| 			if (!gameState.isPlayerEnemy(i) || veto[i])
| 479| 479| 			if (enemyDefense > 6)
| 480| 480| 				veto[i] = true;
| 481| 481| 		}
| 482|    |-	}
|    | 482|+	
| 483| 483| 
| 484| 484| 	// then if not a huge attack, continue attacking our previous target as long as it has some entities,
| 485| 485| 	// otherwise target the most accessible one
Executing section cli...

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

elexis added inline comments.Apr 25 2019, 12:41 PM
binaries/data/mods/public/simulation/components/tests/test_Technologies.js
523 ↗(On Diff #7801)

Changing the Female identity class rings a bell, that broke the lobby bot once who records the number of trained women in rated games. rP19457 (But it looks like this diff doesn't break the bot, would have to look more closely)

Nescio added inline comments.Apr 28 2019, 8:29 PM
binaries/data/mods/public/simulation/components/tests/test_Technologies.js
523 ↗(On Diff #7801)

template_unit_support_female_citizen.xml has a FemaleCitizen class, not Female.

Nescio updated this revision to Diff 8268.Jun 1 2019, 10:03 AM
Nescio edited the test plan for this revision. (Show Details)

Updated because of rP22328.

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A" }, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B" }, { "civ": "civ_C"}] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  55|  55| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]);
|  56|  56| 
|  57|  57| // Multiple `civ`s
|  58|    |-template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C"}] };
|    |  58|+template.requirements = { "all": [{ "civ": "civ_A"}, { "civ": "civ_B"}, { "civ": "civ_C" }] };
|  59|  59| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []);
|  60|  60| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []);
|  61|  61| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A" }, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B" }, { "notciv": "civ_C"}] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/tests/test_Technologies.js
|  62|  62| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false);
|  63|  63| 
|  64|  64| // Multiple `notciv`s
|  65|    |-template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C"}] };
|    |  65|+template.requirements = { "all": [{ "notciv": "civ_A"}, { "notciv": "civ_B"}, { "notciv": "civ_C" }] };
|  66|  66| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false);
|  67|  67| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false);
|  68|  68| TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  10|  10| 
|  11|  11| 	var ret = {};
|  12|  12| 	for (var i in this)
|  13|    |-	{
|    |  13|+	
|  14|  14| 		if (this.hasOwnProperty(i))
|  15|  15| 			ret[i] = this[i];
|  16|    |-	}
|    |  16|+	
|  17|  17| 	ret.modificationCache = {};
|  18|  18| 	return ret;
|  19|  19| };
|    | [NORMAL] ESLintBear (operator-linebreak):
|    | '||' should be placed at the end of the line.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  64|  64| 	for (let key of this.unresearchedAutoResearchTechs)
|  65|  65| 	{
|  66|  66| 		let tech = TechnologyTemplates.Get(key);
|  67|    |-		if ((tech.autoResearch && this.CanResearch(key))
|  68|    |-			|| (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|    |  67|+		if ((tech.autoResearch && this.CanResearch(key)) ||
|    |  68|+			(tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
|  69|  69| 		{
|  70|  70| 			this.unresearchedAutoResearchTechs.delete(key);
|  71|  71| 			this.ResearchTechnology(key);
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|  75|  75| };
|  76|  76| 
|  77|  77| // Checks an entity template to see if its technology requirements have been met
|  78|    |-TechnologyManager.prototype.CanProduce = function (templateName)
|    |  78|+TechnologyManager.prototype.CanProduce = function(templateName)
|  79|  79| {
|  80|  80| 	var cmpTempManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
|  81|  81| 	var template = cmpTempManager.GetTemplate(templateName);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 193| 193| 		var classes = cmpIdentity.GetClassesList();
| 194| 194| 		// don't use foundations for the class counts but check if techs apply (e.g. health increase)
| 195| 195| 		if (!Engine.QueryInterface(msg.entity, IID_Foundation))
| 196|    |-		{
|    | 196|+		
| 197| 197| 			for (let cls of classes)
| 198| 198| 			{
| 199| 199| 				this.classCounts[cls] = this.classCounts[cls] || 0;
| 203| 203| 				this.typeCountsByClass[cls][template] = this.typeCountsByClass[cls][template] || 0;
| 204| 204| 				this.typeCountsByClass[cls][template] += 1;
| 205| 205| 			}
| 206|    |-		}
|    | 206|+		
| 207| 207| 
| 208| 208| 		// Newly created entity, check if any researched techs might apply
| 209| 209| 		// (only do this for new entities because even if an entity is converted or captured,
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 286| 286| 	}
| 287| 287| 
| 288| 288| 	if (template.replaces && template.replaces.length > 0)
| 289|    |-	{
|    | 289|+	
| 290| 290| 		for (var i of template.replaces)
| 291| 291| 		{
| 292| 292| 			if (!i || this.IsTechnologyResearched(i))
| 304| 304| 					cmpPlayerEntityLimits.UpdateLimitsFromTech(i);
| 305| 305| 			}
| 306| 306| 		}
| 307|    |-	}
|    | 307|+	
| 308| 308| 
| 309| 309| 	this.UpdateAutoResearch();
| 310| 310| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, { "player": playerID, "tech": tech});
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 322| 322| 		cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
| 323| 323| 
| 324| 324| 	// always send research finished message
| 325|    |-	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
|    | 325|+	Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech });
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 326| 326| 
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329|    |-		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
|    | 329|+		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component] });
| 330| 330| 		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
| 331| 331| 	}
| 332| 332| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 327| 327| 	for (var component in modifiedComponents)
| 328| 328| 	{
| 329| 329| 		Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
| 330|    |-		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
|    | 330|+		Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component] });
| 331| 331| 	}
| 332| 332| 
| 333| 333| 	if (tech.startsWith("phase") && !template.autoResearch)
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/TechnologyManager.js
| 449| 449|  */
| 450| 450| TechnologyManager.prototype.GetResearcher = function(tech)
| 451| 451| {
| 452|    |-	return this.researchQueued.get(tech)
|    | 452|+	return this.researchQueued.get(tech);
| 453| 453| };
| 454| 454| 
| 455| 455| /**

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 150| »   »   »   switch·(type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 165| »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 220| ·»   »   »   »   »   if·(DoesModificationApply(modif,·classes))
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/simulation/components/TechnologyManager.js
|  68| »   »   »   ||·(tech.top·&&·(this.IsTechnologyResearched(tech.top)·||·this.IsTechnologyResearched(tech.bottom))))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '||'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 229| »   »   »   for·(var·component·in·modifiedComponents)
|    | [NORMAL] JSHintBear:
|    | 'component' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 235| »   »   var·cmpTemplateManager·=·Engine.QueryInterface(SYSTEM_ENTITY,·IID_TemplateManager);
|    | [NORMAL] JSHintBear:
|    | 'cmpTemplateManager' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 236| »   »   var·template·=·cmpTemplateManager.GetCurrentTemplateName(msg.entity);
|    | [NORMAL] JSHintBear:
|    | 'template' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 241| »   »   »   var·cmpIdentity·=·Engine.QueryInterface(msg.entity,·IID_Identity);
|    | [NORMAL] JSHintBear:
|    | 'cmpIdentity' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 244| »   »   »   »   var·classes·=·cmpIdentity.GetClassesList();
|    | [NORMAL] JSHintBear:
|    | 'classes' is already defined.

binaries/data/mods/public/simulation/components/TechnologyManager.js
| 452| »   return·this.researchQueued.get(tech)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|  62|  62| 		targetPlayer = evt.player;
|  63|  63| 		let available = 0;
|  64|  64| 		for (let attackType in this.upcomingAttacks)
|  65|    |-		{
|    |  65|+		
|  66|  66| 			for (let attack of this.upcomingAttacks[attackType])
|  67|  67| 			{
|  68|  68| 				if (attack.state === "completing")
|  79|  79| 				if (attack.unitCollection.length > 2)
|  80|  80| 					available += attack.unitCollection.length;
|  81|  81| 			}
|  82|    |-		}
|    |  82|+		
|  83|  83| 
|  84|  84| 		if (available > 12)	// launch the attack immediately
|  85|  85| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|  84|  84| 		if (available > 12)	// launch the attack immediately
|  85|  85| 		{
|  86|  86| 			for (let attackType in this.upcomingAttacks)
|  87|    |-			{
|    |  87|+			
|  88|  88| 				for (let attack of this.upcomingAttacks[attackType])
|  89|  89| 				{
|  90|  90| 					if (attack.state === "completing" ||
|  94|  94| 					attack.forceStart();
|  95|  95| 					attack.requested = true;
|  96|  96| 				}
|  97|    |-			}
|    |  97|+			
|  98|  98| 			answer = "join";
|  99|  99| 		}
| 100| 100| 		else if (other !== undefined)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 105| 105| 		m.chatAnswerRequestAttack(gameState, targetPlayer, answer, other);
| 106| 106| 
| 107| 107| 	for (let evt of events.EntityRenamed)	// take care of packing units in bombing attacks
| 108|    |-	{
|    | 108|+	
| 109| 109| 		for (let [targetId, unitIds] of this.bombingAttacks)
| 110| 110| 		{
| 111| 111| 			if (targetId == evt.entity)
| 119| 119| 				unitIds.delete(evt.entity);
| 120| 120| 			}
| 121| 121| 		}
| 122|    |-	}
|    | 122|+	
| 123| 123| };
| 124| 124| 
| 125| 125| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 107| 107| 	for (let evt of events.EntityRenamed)	// take care of packing units in bombing attacks
| 108| 108| 	{
| 109| 109| 		for (let [targetId, unitIds] of this.bombingAttacks)
| 110|    |-		{
|    | 110|+		
| 111| 111| 			if (targetId == evt.entity)
| 112| 112| 			{
| 113| 113| 				this.bombingAttacks.set(evt.newentity, unitIds);
| 118| 118| 				unitIds.add(evt.newentity);
| 119| 119| 				unitIds.delete(evt.entity);
| 120| 120| 			}
| 121|    |-		}
|    | 121|+		
| 122| 122| 	}
| 123| 123| };
| 124| 124| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 186| 186| 			let x;
| 187| 187| 			let z;
| 188| 188| 			if (struct.hasClass("Field"))
| 189|    |-			{
|    | 189|+			
| 190| 190| 				if (!struct.resourceSupplyNumGatherers() ||
| 191| 191| 				    !gameState.isPlayerEnemy(gameState.ai.HQ.territoryMap.getOwner(structPos)))
| 192| 192| 					continue;
| 193|    |-			}
|    | 193|+			
| 194| 194| 			let dist = API3.VectorDistance(entPos, structPos);
| 195| 195| 			if (dist > range)
| 196| 196| 			{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 254| 254| 
| 255| 255| 	let unexecutedAttacks = { "Rush": 0, "Raid": 0, "Attack": 0, "HugeAttack": 0 };
| 256| 256| 	for (let attackType in this.upcomingAttacks)
| 257|    |-	{
|    | 257|+	
| 258| 258| 		for (let i = 0; i < this.upcomingAttacks[attackType].length; ++i)
| 259| 259| 		{
| 260| 260| 			let attack = this.upcomingAttacks[attackType][i];
| 293| 293| 				this.upcomingAttacks[attackType].splice(i--, 1);
| 294| 294| 			}
| 295| 295| 		}
| 296|    |-	}
|    | 296|+	
| 297| 297| 
| 298| 298| 	for (let attackType in this.startedAttacks)
| 299| 299| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 296| 296| 	}
| 297| 297| 
| 298| 298| 	for (let attackType in this.startedAttacks)
| 299|    |-	{
|    | 299|+	
| 300| 300| 		for (let i = 0; i < this.startedAttacks[attackType].length; ++i)
| 301| 301| 		{
| 302| 302| 			let attack = this.startedAttacks[attackType][i];
| 313| 313| 				this.startedAttacks[attackType].splice(i--, 1);
| 314| 314| 			}
| 315| 315| 		}
| 316|    |-	}
|    | 316|+	
| 317| 317| 
| 318| 318| 	// creating plans after updating because an aborted plan might be reused in that case.
| 319| 319| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 339| 339| 	else if (unexecutedAttacks.Attack == 0 && unexecutedAttacks.HugeAttack == 0 &&
| 340| 340| 		this.startedAttacks.Attack.length + this.startedAttacks.HugeAttack.length < Math.min(2, 1 + Math.round(gameState.getPopulationMax()/100)) &&
| 341| 341| 		(this.startedAttacks.Attack.length + this.startedAttacks.HugeAttack.length == 0 || gameState.getPopulationMax() - gameState.getPopulation() > 12))
| 342|    |-	{
|    | 342|+	
| 343| 343| 		if (barracksNb >= 1 && (gameState.currentPhase() > 1 || gameState.isResearching(gameState.getPhaseName(2))) ||
| 344| 344| 			!gameState.ai.HQ.baseManagers[1])	// if we have no base ... nothing else to do than attack
| 345| 345| 		{
| 357| 357| 			}
| 358| 358| 			this.attackNumber++;
| 359| 359| 		}
| 360|    |-	}
|    | 360|+	
| 361| 361| 
| 362| 362| 	if (unexecutedAttacks.Raid === 0 && gameState.ai.HQ.defenseManager.targetList.length)
| 363| 363| 	{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 383| 383| m.AttackManager.prototype.getPlan = function(planName)
| 384| 384| {
| 385| 385| 	for (let attackType in this.upcomingAttacks)
| 386|    |-	{
|    | 386|+	
| 387| 387| 		for (let attack of this.upcomingAttacks[attackType])
| 388| 388| 			if (attack.getName() == planName)
| 389| 389| 				return attack;
| 390|    |-	}
|    | 390|+	
| 391| 391| 	for (let attackType in this.startedAttacks)
| 392| 392| 	{
| 393| 393| 		for (let attack of this.startedAttacks[attackType])
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 389| 389| 				return attack;
| 390| 390| 	}
| 391| 391| 	for (let attackType in this.startedAttacks)
| 392|    |-	{
|    | 392|+	
| 393| 393| 		for (let attack of this.startedAttacks[attackType])
| 394| 394| 			if (attack.getName() == planName)
| 395| 395| 				return attack;
| 396|    |-	}
|    | 396|+	
| 397| 397| 	return undefined;
| 398| 398| };
| 399| 399| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/attackManager.js
| 465| 465| 		veto[i] = true;
| 466| 466| 	// No rush if enemy too well defended (i.e. iberians)
| 467| 467| 	if (attack.type == "Rush")
| 468|    |-	{
|    | 468|+	
| 469| 469| 		for (let i = 1; i < gameState.sharedScript.playersData.length; ++i)
| 470| 470| 		{
| 471| 471| 			if (!gameState.isPlayerEnemy(i) || veto[i])
| 479| 479| 			if (enemyDefense > 6)
| 480| 480| 				veto[i] = true;
| 481| 481| 		}
| 482|    |-	}
|    | 482|+	
| 483| 483| 
| 484| 484| 	// then if not a huge attack, continue attacking our previous target as long as it has some entities,
| 485| 485| 	// otherwise target the most accessible one
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-in'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|  52|  52| 		}
|  53|  53| 	}
|  54|  54| 	for (let enemy in attackingArmies)
|  55|    |-	{
|    |  55|+	
|  56|  56| 		for (let ally in attackingArmies[enemy])
|  57|  57| 		{
|  58|  58| 			if (this.attackedAllies[ally] === undefined)
|  59|  59| 				this.attackedAllies[ally] = 0;
|  60|  60| 			this.attackedAllies[ally] += 1;
|  61|  61| 		}
|  62|    |-	}
|    |  62|+	
|  63|  63| 	this.checkEnemyArmies(gameState);
|  64|  64| 	this.checkEnemyUnits(gameState);
|  65|  65| 	this.assignDefenders(gameState);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|  70|  70| m.DefenseManager.prototype.makeIntoArmy = function(gameState, entityID, type = "default")
|  71|  71| {
|  72|  72| 	if (type == "default")
|  73|    |-	{
|    |  73|+	
|  74|  74| 		// Try to add it to an existing army.
|  75|  75| 		for (let army of this.armies)
|  76|  76| 			if (army.getType() == type && army.addFoe(gameState, entityID))
|  77|  77| 				return;	// over
|  78|    |-	}
|    |  78|+	
|  79|  79| 
|  80|  80| 	// Create a new army for it.
|  81|  81| 	let army = new m.DefenseArmy(gameState, [entityID], type);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 179| 179| 		if (territoryOwner != PlayerID && this.attackedAllies[territoryOwner] &&
| 180| 180| 		                                  this.attackedAllies[territoryOwner] > 1 &&
| 181| 181| 		                                  this.GetCooperationLevel(territoryOwner) > 0.7)
| 182|    |-		{
|    | 182|+		
| 183| 183| 			for (let building of gameState.getAllyStructures(territoryOwner).values())
| 184| 184| 			{
| 185| 185| 				if (building.foundationProgress() == 0 ||
| 188| 188| 				if (!this.territoryMap.isBlinking(building.position()))
| 189| 189| 					return true;
| 190| 190| 			}
| 191|    |-		}
|    | 191|+		
| 192| 192| 
| 193| 193| 		// Update the number of enemies attacking this ally
| 194| 194| 		let enemy = entity.owner();
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 211| 211| 	if (i == PlayerID)
| 212| 212| 	{
| 213| 213| 		if (!this.armies.length)
| 214|    |-		{
|    | 214|+		
| 215| 215| 			// check if we can recover capture points from any of our notdecaying structures
| 216| 216| 			for (let ent of gameState.getOwnStructures().values())
| 217| 217| 			{
| 229| 229| 				this.makeIntoArmy(gameState, ent.id(), "capturing");
| 230| 230| 				break;
| 231| 231| 			}
| 232|    |-		}
|    | 232|+		
| 233| 233| 		return;
| 234| 234| 	}
| 235| 235| 	else if (!gameState.isPlayerEnemy(i))
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 328| 328| 		if (!gameState.isPlayerEnemy(owner))
| 329| 329| 		{
| 330| 330| 			if (gameState.isPlayerMutualAlly(owner))
| 331|    |-			{
|    | 331|+			
| 332| 332| 				// update the number of enemies attacking this ally
| 333| 333| 				for (let id of army.foeEntities)
| 334| 334| 				{
| 343| 343| 					this.attackingArmies[enemy][owner] += 1;
| 344| 344| 					break;
| 345| 345| 				}
| 346|    |-			}
|    | 346|+			
| 347| 347| 			continue;
| 348| 348| 		}
| 349| 349| 		else if (owner != 0)   // enemy army back in its territory
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for-of'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 530| 530| 		army.checkEvents(gameState, events);
| 531| 531| 
| 532| 532| 	for (let evt of events.OwnershipChanged)   // capture events
| 533|    |-	{
|    | 533|+	
| 534| 534| 		if (gameState.isPlayerMutualAlly(evt.from) && evt.to > 0)
| 535| 535| 		{
| 536| 536| 			let ent = gameState.getEntityById(evt.entity);
| 537| 537| 			if (ent && ent.hasClass("CivCentre")) // one of our cc has been captured
| 538| 538| 				gameState.ai.HQ.attackManager.switchDefenseToAttack(gameState, ent, { "range": 150 });
| 539| 539| 		}
| 540|    |-	}
|    | 540|+	
| 541| 541| 
| 542| 542| 	let allAttacked = {};
| 543| 543| 	for (let evt of events.Attacked)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 552| 552| 		let attacker = gameState.getEntityById(evt.attacker);
| 553| 553| 		if (attacker && gameState.isEntityOwn(attacker) && gameState.isEntityEnemy(target) && !attacker.hasClass("Ship") &&
| 554| 554| 		   (!target.hasClass("Structure") || target.attackRange("Ranged")))
| 555|    |-		{
|    | 555|+		
| 556| 556| 			// If enemies are in range of one of our defensive structures, garrison it for arrow multiplier
| 557| 557| 			// (enemy non-defensive structure are not considered to stay in sync with garrisonManager)
| 558| 558| 			if (attacker.position() && attacker.isGarrisonHolder() && attacker.getArrowMultiplier() &&
| 559| 559| 			    (target.owner() != 0 || !target.hasClass("Unit") ||
| 560| 560| 			     target.unitAIState() && target.unitAIState().split(".")[1] == "COMBAT"))
| 561| 561| 				this.garrisonUnitsInside(gameState, attacker, { "attacker": target });
| 562|    |-		}
|    | 562|+		
| 563| 563| 
| 564| 564| 		if (!gameState.isEntityOwn(target))
| 565| 565| 			continue;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
| 756| 756| 	let typeGarrison = data.type || "protection";
| 757| 757| 	let allowMelee = gameState.ai.HQ.garrisonManager.allowMelee(target);
| 758| 758| 	if (allowMelee === undefined)
| 759|    |-	{
|    | 759|+	
| 760| 760| 		// Should be kept in sync with garrisonManager to avoid garrisoning-ungarrisoning some units
| 761| 761| 		if (data.attacker)
| 762| 762| 			allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !m.isSiegeUnit(data.attacker);
| 763| 763| 		else
| 764| 764| 			allowMelee = true;
| 765|    |-	}
|    | 765|+	
| 766| 766| 	let units = gameState.getOwnUnits().filter(ent => {
| 767| 767| 		if (!ent.position())
| 768| 768| 			return false;
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Identity.js
|  97|  97| 	this.visibleClassesList = GetVisibleIdentityClasses(this.template);
|  98|  98| };
|  99|  99| 
| 100|    |-Identity.prototype.Deserialize = function ()
|    | 100|+Identity.prototype.Deserialize = function()
| 101| 101| {
| 102| 102| 	this.Init();
| 103| 103| };
Executing section cli...

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

Nescio updated this revision to Diff 9546.Aug 31 2019, 4:56 PM
Nescio edited the summary of this revision. (Show Details)

Updated because of rP22809 and rP22810.

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

Nescio added inline comments.Aug 31 2019, 5:19 PM
binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js
517

No such unit exist.

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

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

Freagarach added inline comments.
binaries/data/mods/public/simulation/ai/petra/defenseManager.js
660–661

Captial + period?

binaries/data/mods/public/simulation/components/tests/test_Identity.js
35

You don't *have* to change tests, since the classes in here may be bogus.

binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js
517

Doesn't matter for tests :)

binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_pikeman.xml
29

Not even via mercenaries/captured CCs?

Nescio added inline comments.Sep 1 2019, 9:44 AM
binaries/data/mods/public/simulation/ai/petra/defenseManager.js
660–661

Thanks, will do!

binaries/data/mods/public/simulation/components/tests/test_Identity.js
35

Well, I just did a grep and corrected all occurences; better be safe than sorry.

binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js
517

Good to know!

binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_pikeman.xml
29

Nope; cart_champion_pikeman.xml (without infantry) and spart_champion_infantry_pike.xml (without man) aren't trainable; ptol and sele fortresses train {civ}_champion_infantry_pikeman.xml.

Nescio updated this revision to Diff 9563.Sep 1 2019, 9:47 AM
Vulcan added a comment.Sep 1 2019, 9:50 AM

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

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

Nescio updated this revision to Diff 9565.Sep 1 2019, 10:01 AM

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

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

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

Nescio updated this revision to Diff 9567.Sep 1 2019, 10:26 AM
Nescio edited the summary of this revision. (Show Details)

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

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

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

wraitii added inline comments.Sep 1 2019, 10:40 AM
binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js
517

In fact arguably tests should use completely irrelevant classes such as "TestA TestB", but out of scope for sure.

wraitii requested changes to this revision.Sep 1 2019, 10:56 AM

One change needed for Quiquereme, otherwise this seems complete (tested with [^a-zA-Z/]Slinger[^a-zA-Z.] and such regex).

I'm not sure about Gastrophetes... I'd keep it an archer for now given that it actually _is_ an archer, gameplay-wise.

binaries/data/mods/public/simulation/templates/template_unit_ship_quinquereme.xml
38

StoneThrower ;)

binaries/data/mods/public/simulation/templates/units/kush_champion_infantry_apedemak.xml
26

Seems OK, special unit.

binaries/data/mods/public/simulation/templates/units/kush_infantry_clubman_b.xml
36

This seems OK, it's a special unit.

binaries/data/mods/public/simulation/templates/units/mace_champion_infantry_crossbowman.xml
26

Mh, to be honest this sounds dangerous. It's the only instance of 'Crossbowman' in the game, but it very much acts like a champion archer. So that's counter-intuitive and likely means we'll forget to pull CrossBowMan when pulling Archer (as opposed to e.g. Slingers which are somewhat different units)

E.g. 'Archery Tradition' refers to Archer specifically... But it doesn't apply to Macedonians.

This revision now requires changes to proceed.Sep 1 2019, 10:56 AM
Nescio updated this revision to Diff 9569.Sep 1 2019, 10:57 AM
Nescio edited the summary of this revision. (Show Details)

List <VisibleClasses> directly after <Classes>.

Nescio added inline comments.Sep 1 2019, 11:00 AM
binaries/data/mods/public/simulation/templates/template_unit_ship_quinquereme.xml
38

Oops, will correct.

binaries/data/mods/public/simulation/templates/units/mace_champion_infantry_crossbowman.xml
26

Keep in mind this unit is not trainable, nor used in any maps at the moment. Its attack is also quite different from other archers.

Nescio updated this revision to Diff 9571.Sep 1 2019, 11:01 AM

Catapult→StoneThrower in ;uinquereme template

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

wraitii accepted this revision.Sep 1 2019, 11:07 AM
wraitii added inline comments.
binaries/data/mods/public/simulation/templates/units/mace_champion_infantry_crossbowman.xml
26

Mh, OK, in that case, it actually seems like a fair move to make it have a different class.

This revision is now accepted and ready to land.Sep 1 2019, 11:07 AM

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'Phenotype'.
|----|    | /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/simulation/components/tests/test_Identity.js
|  21|  21| cmpIdentity = ConstructComponent(6, "Identity", {
|  22|  22| 	"Civ": "iber",
|  23|  23| 	"Lang": "iberian",
|  24|    |-	"Phenotype":  { "_string": "female" },
|    |  24|+	"Phenotype": { "_string": "female" },
|  25|  25| 	"GenericName": "Iberian Skirmisher",
|  26|  26| 	"SpecificName": "Lusitano Ezpatari",
|  27|  27| 	"SelectionGroupName": "units/iber_infantry_javelinist_b",
Executing section cli...

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

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

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

This revision was automatically updated to reflect the committed changes.
Stan added a comment.Sep 1 2019, 4:14 PM

This will break a few mods. They should be notified.