Page MenuHomeWildfire Games

Fix formation-related unitAI infinite loop
Needs ReviewPublic

Authored by wraitii on Mon, Jun 24, 4:59 PM.

Details

Reviewers
None
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Trac Tickets
#5460
Summary

Formation members that attack as part of an attacking formation can run in a rare infinite loop, where they go through Idle, Find a new target, try and attack it, and MoveToTargetAttackRange returns false, triggering the whole attack.

This patch aims to correct formation members' idle behaviour, under the assumption that:

  • Formation units are never idle (they're in formation)
  • Formation units have no autonomy (they're in formation)

Thus their idle state should do nothing.

The question is:

  • should we also change the [Move/Check]TargetAttackRange functions to not handle formations members any specially?
Test Plan

Review changes. This fixes the commands.txt posted by @elexis on the trac ticket.

Diff Detail

Repository
rP 0 A.D. Public Repository
Branch
temp
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 8057
Build 13114: Vulcan BuildJenkins
Build 13113: arc lint + arc unit

Event Timeline

wraitii created this revision.Mon, Jun 24, 4:59 PM

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

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 352| 352| 		var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
| 353| 353| 		if (this.lastShorelinePosition && cmpPosition && (this.lastShorelinePosition.x == cmpPosition.GetPosition().x)
| 354| 354| 		    && (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
| 355|    |-		{
|    | 355|+		
| 356| 356| 			// we were already on the shoreline, and have not moved since
| 357| 357| 			if (DistanceBetweenEntities(this.entity, this.order.data.target) < 50)
| 358| 358| 				needToMove = false;
| 359|    |-		}
|    | 359|+		
| 360| 360| 
| 361| 361| 		if (needToMove)
| 362| 362| 			this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING");
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 350| 350| 		// Check if we need to move     TODO implement a better way to know if we are on the shoreline
| 351| 351| 		var needToMove = true;
| 352| 352| 		var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
| 353|    |-		if (this.lastShorelinePosition && cmpPosition && (this.lastShorelinePosition.x == cmpPosition.GetPosition().x)
| 354|    |-		    && (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
|    | 353|+		if (this.lastShorelinePosition && cmpPosition && (this.lastShorelinePosition.x == cmpPosition.GetPosition().x) &&
|    | 354|+		    (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
| 355| 355| 		{
| 356| 356| 			// we were already on the shoreline, and have not moved since
| 357| 357| 			if (DistanceBetweenEntities(this.entity, this.order.data.target) < 50)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 515| 515| 					this.PushOrderFront("Walk", this.order.data.lastPos);
| 516| 516| 				}
| 517| 517| 				else
| 518|    |-				{
|    | 518|+				
| 519| 519| 					// We couldn't move there, or the target moved away
| 520| 520| 					this.FinishOrder();
| 521|    |-				}
|    | 521|+				
| 522| 522| 				return;
| 523| 523| 			}
| 524| 524| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 730| 730| 			}
| 731| 731| 			// Check if we are already in range, otherwise walk there
| 732| 732| 			if (!this.CheckGarrisonRange(msg.data.target))
| 733|    |-			{
|    | 733|+			
| 734| 734| 				if (!this.CheckTargetVisible(msg.data.target))
| 735| 735| 				{
| 736| 736| 					this.FinishOrder();
| 741| 741| 					this.SetNextState("GARRISON.APPROACHING");
| 742| 742| 					return;
| 743| 743| 				}
| 744|    |-			}
|    | 744|+			
| 745| 745| 
| 746| 746| 			this.SetNextState("GARRISON.GARRISONING");
| 747| 747| 		},
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 736| 736| 					this.FinishOrder();
| 737| 737| 					return;
| 738| 738| 				}
| 739|    |-				else
| 740|    |-				{
|    | 739|+				
| 741| 740| 					this.SetNextState("GARRISON.APPROACHING");
| 742| 741| 					return;
| 743|    |-				}
|    | 742|+				
| 744| 743| 			}
| 745| 744| 
| 746| 745| 			this.SetNextState("GARRISON.GARRISONING");
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 759| 759| 						this.PushOrderFront("Walk", msg.data.lastPos);
| 760| 760| 					}
| 761| 761| 					else
| 762|    |-					{
|    | 762|+					
| 763| 763| 						// We couldn't move there, or the target moved away
| 764| 764| 						this.FinishOrder();
| 765|    |-					}
|    | 765|+					
| 766| 766| 					return;
| 767| 767| 				}
| 768| 768| 
|    | [NORMAL] ESLintBear (key-spacing):
|    | Missing space before value for key 'GARRISON'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
| 992| 992| 			},
| 993| 993| 		},
| 994| 994| 
| 995|    |-		"GARRISON":{
|    | 995|+		"GARRISON": {
| 996| 996| 			"enter": function() {
| 997| 997| 				// If the garrisonholder should pickup, warn it so it can take needed action
| 998| 998| 				var cmpGarrisonHolder = Engine.QueryInterface(this.order.data.target, IID_GarrisonHolder);
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1205|1205| 			// If the controller handled an order but some members rejected it,
|1206|1206| 			// they will have no orders and be in the FORMATIONMEMBER.IDLE state.
|1207|1207| 			if (this.orderQueue.length)
|1208|    |-			{
|    |1208|+			
|1209|1209| 				// We're leaving the formation, so stop our FormationWalk order
|1210|1210| 				if (this.FinishOrder())
|1211|1211| 					return;
|1212|    |-			}
|    |1212|+			
|1213|1213| 
|1214|1214| 			// No orders left, we're an individual now
|1215|1215| 			if (this.IsAnimal())
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1233|1233| 			// Move a tile outside the building
|1234|1234| 			let range = 4;
|1235|1235| 			if (this.CheckTargetRangeExplicit(msg.data.target, range, range))
|1236|    |-			{
|    |1236|+			
|1237|1237| 				// We are already at the target, or can't move at all
|1238|1238| 				this.FinishOrder();
|1239|    |-			}
|    |1239|+			
|1240|1240| 			else
|1241|1241| 			{
|1242|1242| 				this.order.data.min = range;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1461|1461| 
|1462|1462| 			"LosRangeUpdate": function(msg) {
|1463|1463| 				if (this.GetStance().targetVisibleEnemies)
|1464|    |-				{
|    |1464|+				
|1465|1465| 					// Start attacking one of the newly-seen enemy (if any)
|1466|1466| 					this.AttackEntitiesByPreference(msg.data.added);
|1467|    |-				}
|    |1467|+				
|1468|1468| 			},
|1469|1469| 
|1470|1470| 			"LosHealRangeUpdate": function(msg) {
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1494|1494| 				this.SelectAnimation("move");
|1495|1495| 			},
|1496|1496| 
|1497|    |-			"leave": function () {
|    |1497|+			"leave": function() {
|1498|1498| 				this.SelectAnimation("idle");
|1499|1499| 				this.StopMoving();
|1500|1500| 			},
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1674|1674| 						// if nothing better to do, check if the guarded needs to be healed or repaired
|1675|1675| 						var cmpHealth = Engine.QueryInterface(this.isGuardOf, IID_Health);
|1676|1676| 						if (cmpHealth && cmpHealth.IsInjured())
|1677|    |-						{
|    |1677|+						
|1678|1678| 							if (this.CanHeal(this.isGuardOf))
|1679|1679| 								this.PushOrderFront("Heal", { "target": this.isGuardOf, "force": false });
|1680|1680| 							else if (this.CanRepair(this.isGuardOf))
|1681|1681| 								this.PushOrderFront("Repair", { "target": this.isGuardOf, "autocontinue": false, "force": false });
|1682|    |-						}
|    |1682|+						
|1683|1683| 					}
|1684|1684| 				},
|1685|1685| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1801|1801| 					}
|1802|1802| 					// Check the target is still alive and attackable
|1803|1803| 					if (this.CanAttack(target) && !this.CheckTargetAttackRange(target, this.order.data.attackType))
|1804|    |-					{
|    |1804|+					
|1805|1805| 						// Can't reach it - try to chase after it
|1806|1806| 						if (this.ShouldChaseTargetedEntity(target, this.order.data.force))
|1807|1807| 						{
|1814|1814| 							this.SetNextState("COMBAT.CHASING");
|1815|1815| 							return true;
|1816|1816| 						}
|1817|    |-					}
|    |1817|+					
|1818|1818| 
|1819|1819| 					this.StopMoving();
|1820|1820| 
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1847|1847| 					// TODO: we should probably only bother syncing projectile attacks, not melee
|1848|1848| 
|1849|1849| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|1850|    |-					this.resyncAnimation = (prepare != this.attackTimers.prepare) ? true : false;
|    |1850|+					this.resyncAnimation = (prepare != this.attackTimers.prepare);
|1851|1851| 
|1852|1852| 					this.FaceTowardsTarget(this.order.data.target);
|1853|1853| 
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1973|1973| 
|1974|1974| 				"Attacked": function(msg) {
|1975|1975| 					// If we are capturing and are attacked by something that we would not capture, attack that entity instead
|1976|    |-					if (this.order.data.attackType == "Capture" && (this.GetStance().targetAttackersAlways || !this.order.data.force)
|1977|    |-						&& this.order.data.target != msg.data.attacker && this.GetBestAttackAgainst(msg.data.attacker, true) != "Capture")
|    |1976|+					if (this.order.data.attackType == "Capture" && (this.GetStance().targetAttackersAlways || !this.order.data.force) &&
|    |1977|+						this.order.data.target != msg.data.attacker && this.GetBestAttackAgainst(msg.data.attacker, true) != "Capture")
|1978|1978| 						this.RespondToTargetedEntities([msg.data.attacker]);
|1979|1979| 				},
|1980|1980| 			},
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|1993|1993| 					this.SelectAnimation("move");
|1994|1994| 					var cmpUnitAI = Engine.QueryInterface(this.order.data.target, IID_UnitAI);
|1995|1995| 					if (cmpUnitAI && cmpUnitAI.IsFleeing())
|1996|    |-					{
|    |1996|+					
|1997|1997| 						// Run after a fleeing target
|1998|1998| 						this.SetSpeedMultiplier(this.GetRunMultiplier());
|1999|    |-					}
|    |1999|+					
|2000|2000| 					this.StartTimer(1000, 1000);
|2001|2001| 				},
|2002|2002| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2175|2175| 
|2176|2176| 					var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
|2177|2177| 					if (cmpSupply && cmpSupply.IsAvailable(cmpOwnership.GetOwner(), this.entity))
|2178|    |-					{
|    |2178|+					
|2179|2179| 						// Check we can still reach and gather from the target
|2180|2180| 						if (this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer) && this.CanGather(this.gatheringTarget))
|2181|2181| 						{
|2226|2226| 								return;
|2227|2227| 							}
|2228|2228| 						}
|2229|    |-					}
|    |2229|+					
|2230|2230| 
|2231|2231| 					// We're already in range, can't get anywhere near it or the target is exhausted.
|2232|2232| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2218|2218| 								return;
|2219|2219| 						}
|2220|2220| 						else
|2221|    |-						{
|    |2221|+						
|2222|2222| 							// Try to follow the target
|2223|2223| 							if (this.MoveToTargetRange(this.gatheringTarget, IID_ResourceGatherer))
|2224|2224| 							{
|2225|2225| 								this.SetNextState("APPROACHING");
|2226|2226| 								return;
|2227|2227| 							}
|2228|    |-						}
|    |2228|+						
|2229|2229| 					}
|2230|2230| 
|2231|2231| 					// We're already in range, can't get anywhere near it or the target is exhausted.
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2252|2252| 					// Also don't switch to a different type of huntable animal
|2253|2253| 					var nearby = this.FindNearbyResource(function(ent, type, template) {
|2254|2254| 						return (
|2255|    |-							(type.generic == "treasure" && resourceType.generic == "treasure")
|2256|    |-							|| (type.specific == resourceType.specific
|    |2255|+							(type.generic == "treasure" && resourceType.generic == "treasure") ||
|    |2256|+							(type.specific == resourceType.specific
|2257|2257| 							&& (type.specific != "meat" || resourceTemplate == template))
|2258|2258| 						);
|2259|2259| 					});
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2253|2253| 					var nearby = this.FindNearbyResource(function(ent, type, template) {
|2254|2254| 						return (
|2255|2255| 							(type.generic == "treasure" && resourceType.generic == "treasure")
|2256|    |-							|| (type.specific == resourceType.specific
|2257|    |-							&& (type.specific != "meat" || resourceTemplate == template))
|    |2256|+							|| (type.specific == resourceType.specific &&
|    |2257|+							(type.specific != "meat" || resourceTemplate == template))
|2258|2258| 						);
|2259|2259| 					});
|2260|2260| 					if (nearby)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2318|2318| 
|2319|2319| 				"Timer": function(msg) {
|2320|2320| 					if (this.ShouldAbandonChase(this.order.data.target, this.order.data.force, IID_Heal, null))
|2321|    |-					{
|    |2321|+					
|2322|2322| 						// Return to our original position unless we have a better order.
|2323|2323| 						if (!this.FinishOrder() && this.GetStance().respondHoldGround)
|2324|2324| 							this.WalkToHeldPosition();
|2325|    |-					}
|    |2325|+					
|2326|2326| 				},
|2327|2327| 
|2328|2328| 				"MovementUpdate": function() {
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2352|2352| 					this.StartTimer(prepare, this.healTimers.repeat);
|2353|2353| 
|2354|2354| 					// If using a non-default prepare time, re-sync the animation when the timer runs.
|2355|    |-					this.resyncAnimation = (prepare != this.healTimers.prepare) ? true : false;
|    |2355|+					this.resyncAnimation = (prepare != this.healTimers.prepare);
|2356|2356| 
|2357|2357| 					this.FaceTowardsTarget(this.order.data.target);
|2358|2358| 				},
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2565|2565| 					{
|2566|2566| 						// The building was already finished/fully repaired before we arrived;
|2567|2567| 						// let the ConstructionFinished handler handle this.
|2568|    |-						this.OnGlobalConstructionFinished({"entity": this.repairTarget, "newentity": this.repairTarget});
|    |2568|+						this.OnGlobalConstructionFinished({ "entity": this.repairTarget, "newentity": this.repairTarget});
|2569|2569| 						return true;
|2570|2570| 					}
|2571|2571| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2565|2565| 					{
|2566|2566| 						// The building was already finished/fully repaired before we arrived;
|2567|2567| 						// let the ConstructionFinished handler handle this.
|2568|    |-						this.OnGlobalConstructionFinished({"entity": this.repairTarget, "newentity": this.repairTarget});
|    |2568|+						this.OnGlobalConstructionFinished({"entity": this.repairTarget, "newentity": this.repairTarget });
|2569|2569| 						return true;
|2570|2570| 					}
|2571|2571| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2692|2692| 
|2693|2693| 				// Unit was approaching and there's nothing to do now, so switch to walking
|2694|2694| 				if (oldState === "INDIVIDUAL.REPAIR.APPROACHING")
|2695|    |-				{
|    |2695|+				
|2696|2696| 					// We're already walking to the given point, so add this as a order.
|2697|2697| 					this.WalkToTarget(msg.data.newentity, true);
|2698|    |-				}
|    |2698|+				
|2699|2699| 			},
|2700|2700| 		},
|2701|2701| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2755|2755| 
|2756|2756| 					// Check that we can garrison here
|2757|2757| 					if (this.CanGarrison(target))
|2758|    |-					{
|    |2758|+					
|2759|2759| 						// Check that we're in range of the garrison target
|2760|2760| 						if (this.CheckGarrisonRange(target))
|2761|2761| 						{
|2831|2831| 								return false;
|2832|2832| 							}
|2833|2833| 						}
|2834|    |-					}
|    |2834|+					
|2835|2835| 					// Garrisoning failed for some reason, so finish the order
|2836|2836| 					this.FinishOrder();
|2837|2837| 					return true;
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2953|2953| 		"Attacked": function(msg) {
|2954|2954| 			if (this.template.NaturalBehaviour == "skittish" ||
|2955|2955| 			    this.template.NaturalBehaviour == "passive")
|2956|    |-			{
|    |2956|+			
|2957|2957| 				this.Flee(msg.data.attacker, false);
|2958|    |-			}
|    |2958|+			
|2959|2959| 			else if (this.IsDangerousAnimal() || this.template.NaturalBehaviour == "defensive")
|2960|2960| 			{
|2961|2961| 				if (this.CanAttack(msg.data.attacker))
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2962|2962| 					this.Attack(msg.data.attacker, false);
|2963|2963| 			}
|2964|2964| 			else if (this.template.NaturalBehaviour == "domestic")
|2965|    |-			{
|    |2965|+			
|2966|2966| 				// Never flee, stop what we were doing
|2967|2967| 				this.SetNextState("IDLE");
|2968|    |-			}
|    |2968|+			
|2969|2969| 		},
|2970|2970| 
|2971|2971| 		"Order.LeaveFoundation": function(msg) {
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|2976|2976| 				this.FinishOrder();
|2977|2977| 				return;
|2978|2978| 			}
|2979|    |-			else
|2980|    |-			{
|    |2979|+			
|2981|2980| 				this.order.data.min = range;
|2982|2981| 				this.SetNextState("WALKING");
|2983|    |-			}
|    |2982|+			
|2984|2983| 		},
|2985|2984| 
|2986|2985| 		"IDLE": {
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3020|3020| 				}
|3021|3021| 				// Start attacking one of the newly-seen enemy (if any)
|3022|3022| 				else if (this.IsDangerousAnimal())
|3023|    |-				{
|    |3023|+				
|3024|3024| 					this.AttackVisibleEntity(msg.data.added);
|3025|    |-				}
|    |3025|+				
|3026|3026| 
|3027|3027| 				// TODO: if two units enter our range together, we'll attack the
|3028|3028| 				// first and then the second won't trigger another LosRangeUpdate
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3063|3063| 				}
|3064|3064| 				// Start attacking one of the newly-seen enemy (if any)
|3065|3065| 				else if (this.template.NaturalBehaviour == "violent")
|3066|    |-				{
|    |3066|+				
|3067|3067| 					this.AttackVisibleEntity(msg.data.added);
|3068|    |-				}
|    |3068|+				
|3069|3069| 			},
|3070|3070| 
|3071|3071| 			"Timer": function(msg) {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 7.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3078|3078| 		"COMBAT": "INDIVIDUAL.COMBAT", // reuse the same combat behaviour for animals
|3079|3079| 
|3080|3080| 		"WALKING": "INDIVIDUAL.WALKING",	// reuse the same walking behaviour for animals
|3081|    |-							// only used for domestic animals
|    |3081|+		// only used for domestic animals
|3082|3082| 	},
|3083|3083| };
|3084|3084| 
|    | [NORMAL] ESLintBear (no-unneeded-ternary):
|    | Unnecessary use of boolean literals in conditional expression.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3135|3135| 
|3136|3136| UnitAI.prototype.IsAnimal = function()
|3137|3137| {
|3138|    |-	return (this.template.NaturalBehaviour ? true : false);
|    |3138|+	return (!!this.template.NaturalBehaviour);
|3139|3139| };
|3140|3140| 
|3141|3141| UnitAI.prototype.IsDangerousAnimal = function()
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3173|3173| UnitAI.prototype.GetGarrisonHolder = function()
|3174|3174| {
|3175|3175| 	if (this.IsGarrisoned())
|3176|    |-	{
|    |3176|+	
|3177|3177| 		for (let order of this.orderQueue)
|3178|3178| 			if (order.type == "Garrison")
|3179|3179| 				return order.data.target;
|3180|    |-	}
|    |3180|+	
|3181|3181| 	return INVALID_ENTITY;
|3182|3182| };
|3183|3183| 
|    | [NORMAL] ESLintBear (comma-spacing):
|    | A space is required after ','.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3251|3251| 		{
|3252|3252| 			let index = this.GetCurrentState().indexOf(".");
|3253|3253| 			if (index != -1)
|3254|    |-				this.UnitFsm.SwitchToNextState(this, this.GetCurrentState().slice(0,index));
|    |3254|+				this.UnitFsm.SwitchToNextState(this, this.GetCurrentState().slice(0, index));
|3255|3255| 			this.Stop(false);
|3256|3256| 		}
|3257|3257| 
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3307|3307| 		if (this.orderQueue[i].type != "PickupUnit" || this.orderQueue[i].data.target != msg.entity)
|3308|3308| 			continue;
|3309|3309| 		if (i == 0)
|3310|    |-			this.UnitFsm.ProcessMessage(this, {"type": "PickupCanceled", "data": msg});
|    |3310|+			this.UnitFsm.ProcessMessage(this, { "type": "PickupCanceled", "data": msg});
|3311|3311| 		else
|3312|3312| 			this.orderQueue.splice(i, 1);
|3313|3313| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3307|3307| 		if (this.orderQueue[i].type != "PickupUnit" || this.orderQueue[i].data.target != msg.entity)
|3308|3308| 			continue;
|3309|3309| 		if (i == 0)
|3310|    |-			this.UnitFsm.ProcessMessage(this, {"type": "PickupCanceled", "data": msg});
|    |3310|+			this.UnitFsm.ProcessMessage(this, {"type": "PickupCanceled", "data": msg });
|3311|3311| 		else
|3312|3312| 			this.orderQueue.splice(i, 1);
|3313|3313| 		Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3391|3391| };
|3392|3392| 
|3393|3393| 
|3394|    |-//// FSM linkage functions ////
|    |3394|+// // FSM linkage functions ////
|3395|3395| 
|3396|3396| // Setting the next state to the current state will leave/re-enter the top-most substate.
|3397|3397| UnitAI.prototype.SetNextState = function(state)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3563|3563| 				continue;
|3564|3564| 			if (this.orderQueue[i].type == type)
|3565|3565| 				continue;
|3566|    |-			this.orderQueue.splice(i, 0, {"type": type, "data": data});
|    |3566|+			this.orderQueue.splice(i, 0, { "type": type, "data": data});
|3567|3567| 			Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3568|3568| 			return;
|3569|3569| 		}
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3563|3563| 				continue;
|3564|3564| 			if (this.orderQueue[i].type == type)
|3565|3565| 				continue;
|3566|    |-			this.orderQueue.splice(i, 0, {"type": type, "data": data});
|    |3566|+			this.orderQueue.splice(i, 0, {"type": type, "data": data });
|3567|3567| 			Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
|3568|3568| 			return;
|3569|3569| 		}
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3577|3577| {
|3578|3578| 	// Remember the previous work orders to be able to go back to them later if required
|3579|3579| 	if (data && data.force)
|3580|    |-	{
|    |3580|+	
|3581|3581| 		if (this.IsFormationController())
|3582|3582| 			this.CallMemberFunction("UpdateWorkOrders", [type]);
|3583|3583| 		else
|3584|3584| 			this.UpdateWorkOrders(type);
|3585|    |-	}
|    |3585|+	
|3586|3586| 
|3587|3587| 	let garrisonHolder = this.IsGarrisoned() && type != "Ungarrison" ? this.GetGarrisonHolder() : null;
|3588|3588| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3654|3654| 	{
|3655|3655| 		var cmpUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI);
|3656|3656| 		if (cmpUnitAI)
|3657|    |-		{
|    |3657|+		
|3658|3658| 			for (var i = 0; i < cmpUnitAI.orderQueue.length; ++i)
|3659|3659| 			{
|3660|3660| 				if (isWorkType(cmpUnitAI.orderQueue[i].type))
|3663|3663| 					return;
|3664|3664| 				}
|3665|3665| 			}
|3666|    |-		}
|    |3666|+		
|3667|3667| 	}
|3668|3668| 
|3669|3669| 	// If nothing found, take the unit orders
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3656|3656| 		if (cmpUnitAI)
|3657|3657| 		{
|3658|3658| 			for (var i = 0; i < cmpUnitAI.orderQueue.length; ++i)
|3659|    |-			{
|    |3659|+			
|3660|3660| 				if (isWorkType(cmpUnitAI.orderQueue[i].type))
|3661|3661| 				{
|3662|3662| 					this.workOrders = cmpUnitAI.orderQueue.slice(i);
|3663|3663| 					return;
|3664|3664| 				}
|3665|    |-			}
|    |3665|+			
|3666|3666| 		}
|3667|3667| 	}
|3668|3668| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'for' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3668|3668| 
|3669|3669| 	// If nothing found, take the unit orders
|3670|3670| 	for (var i = 0; i < this.orderQueue.length; ++i)
|3671|    |-	{
|    |3671|+	
|3672|3672| 		if (isWorkType(this.orderQueue[i].type))
|3673|3673| 		{
|3674|3674| 			this.workOrders = this.orderQueue.slice(i);
|3675|3675| 			return;
|3676|3676| 		}
|3677|    |-	}
|    |3677|+	
|3678|3678| };
|3679|3679| 
|3680|3680| UnitAI.prototype.BackToWork = function()
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3734|3734| 	if (data.timerRepeat === undefined)
|3735|3735| 		this.timer = undefined;
|3736|3736| 
|3737|    |-	this.UnitFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness});
|    |3737|+	this.UnitFsm.ProcessMessage(this, { "type": "Timer", "data": data, "lateness": lateness});
|3738|3738| };
|3739|3739| 
|3740|3740| /**
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3734|3734| 	if (data.timerRepeat === undefined)
|3735|3735| 		this.timer = undefined;
|3736|3736| 
|3737|    |-	this.UnitFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness});
|    |3737|+	this.UnitFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness });
|3738|3738| };
|3739|3739| 
|3740|3740| /**
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3769|3769| 	this.timer = undefined;
|3770|3770| };
|3771|3771| 
|3772|    |-//// Message handlers /////
|    |3772|+// // Message handlers /////
|3773|3773| 
|3774|3774| UnitAI.prototype.OnMotionChanged = function(msg)
|3775|3775| {
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3781|3781| 	// TODO: This is a bit inefficient since every unit listens to every
|3782|3782| 	// construction message - ideally we could scope it to only the one we're building
|3783|3783| 
|3784|    |-	this.UnitFsm.ProcessMessage(this, {"type": "ConstructionFinished", "data": msg});
|    |3784|+	this.UnitFsm.ProcessMessage(this, { "type": "ConstructionFinished", "data": msg});
|3785|3785| };
|3786|3786| 
|3787|3787| UnitAI.prototype.OnGlobalEntityRenamed = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3781|3781| 	// TODO: This is a bit inefficient since every unit listens to every
|3782|3782| 	// construction message - ideally we could scope it to only the one we're building
|3783|3783| 
|3784|    |-	this.UnitFsm.ProcessMessage(this, {"type": "ConstructionFinished", "data": msg});
|    |3784|+	this.UnitFsm.ProcessMessage(this, {"type": "ConstructionFinished", "data": msg });
|3785|3785| };
|3786|3786| 
|3787|3787| UnitAI.prototype.OnGlobalEntityRenamed = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3806|3806| 
|3807|3807| UnitAI.prototype.OnAttacked = function(msg)
|3808|3808| {
|3809|    |-	this.UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg});
|    |3809|+	this.UnitFsm.ProcessMessage(this, { "type": "Attacked", "data": msg});
|3810|3810| };
|3811|3811| 
|3812|3812| UnitAI.prototype.OnGuardedAttacked = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3806|3806| 
|3807|3807| UnitAI.prototype.OnAttacked = function(msg)
|3808|3808| {
|3809|    |-	this.UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg});
|    |3809|+	this.UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg });
|3810|3810| };
|3811|3811| 
|3812|3812| UnitAI.prototype.OnGuardedAttacked = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3811|3811| 
|3812|3812| UnitAI.prototype.OnGuardedAttacked = function(msg)
|3813|3813| {
|3814|    |-	this.UnitFsm.ProcessMessage(this, {"type": "GuardedAttacked", "data": msg.data});
|    |3814|+	this.UnitFsm.ProcessMessage(this, { "type": "GuardedAttacked", "data": msg.data});
|3815|3815| };
|3816|3816| 
|3817|3817| UnitAI.prototype.OnHealthChanged = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3811|3811| 
|3812|3812| UnitAI.prototype.OnGuardedAttacked = function(msg)
|3813|3813| {
|3814|    |-	this.UnitFsm.ProcessMessage(this, {"type": "GuardedAttacked", "data": msg.data});
|    |3814|+	this.UnitFsm.ProcessMessage(this, {"type": "GuardedAttacked", "data": msg.data });
|3815|3815| };
|3816|3816| 
|3817|3817| UnitAI.prototype.OnHealthChanged = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3816|3816| 
|3817|3817| UnitAI.prototype.OnHealthChanged = function(msg)
|3818|3818| {
|3819|    |-	this.UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to});
|    |3819|+	this.UnitFsm.ProcessMessage(this, { "type": "HealthChanged", "from": msg.from, "to": msg.to});
|3820|3820| };
|3821|3821| 
|3822|3822| UnitAI.prototype.OnRangeUpdate = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3816|3816| 
|3817|3817| UnitAI.prototype.OnHealthChanged = function(msg)
|3818|3818| {
|3819|    |-	this.UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to});
|    |3819|+	this.UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to });
|3820|3820| };
|3821|3821| 
|3822|3822| UnitAI.prototype.OnRangeUpdate = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3822|3822| UnitAI.prototype.OnRangeUpdate = function(msg)
|3823|3823| {
|3824|3824| 	if (msg.tag == this.losRangeQuery)
|3825|    |-		this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg});
|    |3825|+		this.UnitFsm.ProcessMessage(this, { "type": "LosRangeUpdate", "data": msg});
|3826|3826| 	else if (msg.tag == this.losHealRangeQuery)
|3827|3827| 		this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg});
|3828|3828| };
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3822|3822| UnitAI.prototype.OnRangeUpdate = function(msg)
|3823|3823| {
|3824|3824| 	if (msg.tag == this.losRangeQuery)
|3825|    |-		this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg});
|    |3825|+		this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg });
|3826|3826| 	else if (msg.tag == this.losHealRangeQuery)
|3827|3827| 		this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg});
|3828|3828| };
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3824|3824| 	if (msg.tag == this.losRangeQuery)
|3825|3825| 		this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg});
|3826|3826| 	else if (msg.tag == this.losHealRangeQuery)
|3827|    |-		this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg});
|    |3827|+		this.UnitFsm.ProcessMessage(this, { "type": "LosHealRangeUpdate", "data": msg});
|3828|3828| };
|3829|3829| 
|3830|3830| UnitAI.prototype.OnPackFinished = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3824|3824| 	if (msg.tag == this.losRangeQuery)
|3825|3825| 		this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg});
|3826|3826| 	else if (msg.tag == this.losHealRangeQuery)
|3827|    |-		this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg});
|    |3827|+		this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg });
|3828|3828| };
|3829|3829| 
|3830|3830| UnitAI.prototype.OnPackFinished = function(msg)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3829|3829| 
|3830|3830| UnitAI.prototype.OnPackFinished = function(msg)
|3831|3831| {
|3832|    |-	this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed});
|    |3832|+	this.UnitFsm.ProcessMessage(this, { "type": "PackFinished", "packed": msg.packed});
|3833|3833| };
|3834|3834| 
|3835|3835| //// Helper functions to be called by the FSM ////
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3829|3829| 
|3830|3830| UnitAI.prototype.OnPackFinished = function(msg)
|3831|3831| {
|3832|    |-	this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed});
|    |3832|+	this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed });
|3833|3833| };
|3834|3834| 
|3835|3835| //// Helper functions to be called by the FSM ////
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3832|3832| 	this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed});
|3833|3833| };
|3834|3834| 
|3835|    |-//// Helper functions to be called by the FSM ////
|    |3835|+// // Helper functions to be called by the FSM ////
|3836|3836| 
|3837|3837| UnitAI.prototype.GetWalkSpeed = function()
|3838|3838| {
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|3934|3934| 	if (!cmpOwnership || cmpOwnership.GetOwner() == INVALID_PLAYER)
|3935|3935| 		return undefined;
|3936|3936| 
|3937|    |-	let cmpPosition = Engine.QueryInterface(this.entity, IID_Position)
|    |3937|+	let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
|3938|3938| 	if (!cmpPosition || !cmpPosition.IsInWorld())
|3939|3939| 		return undefined;
|3940|3940| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4019|4019| 			PlaySound(name, member);
|4020|4020| 	}
|4021|4021| 	else
|4022|    |-	{
|    |4022|+	
|4023|4023| 		// Otherwise use our own sounds
|4024|4024| 		PlaySound(name, this.entity);
|4025|    |-	}
|    |4025|+	
|4026|4026| };
|4027|4027| 
|4028|4028| /*
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4211|4211| 	else
|4212|4212| 		// return false? Or hope you come close enough?
|4213|4213| 		var parabolicMaxRange = 0;
|4214|    |-		//return false;
|    |4214|+		// return false;
|4215|4215| 
|4216|4216| 	// the parabole changes while walking, take something in the middle
|4217|4217| 	var guessedMaxRange = (range.max + parabolicMaxRange)/2;
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4298|4298| 	if (this.IsFormationMember())
|4299|4299| 	{
|4300|4300| 		var cmpFormationUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI);
|4301|    |-		if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation()
|4302|    |-			&& cmpFormationUnitAI.order.data.target == target)
|    |4301|+		if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation() &&
|    |4302|+			cmpFormationUnitAI.order.data.target == target)
|4303|4303| 			return true;
|4304|4304| 	}
|4305|4305| 
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4466|4466| UnitAI.prototype.AttackEntityInZone = function(ents)
|4467|4467| {
|4468|4468| 	var target = ents.find(target =>
|4469|    |-		this.CanAttack(target)
|4470|    |-		&& this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true))
|    |4469|+		this.CanAttack(target) &&
|    |4470|+		this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true))
|4471|4471| 		&& (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target))
|4472|4472| 	);
|4473|4473| 	if (!target)
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4467|4467| {
|4468|4468| 	var target = ents.find(target =>
|4469|4469| 		this.CanAttack(target)
|4470|    |-		&& this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true))
|4471|    |-		&& (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target))
|    |4470|+		&& this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true)) &&
|    |4471|+		(this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target))
|4472|4472| 	);
|4473|4473| 	if (!target)
|4474|4474| 		return false;
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4531|4531| 	// If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker
|4532|4532| 	if (this.isGuardOf)
|4533|4533| 	{
|4534|    |-		var cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4534|+		var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4535|4535| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4536|4536| 		if (cmpUnitAI && cmpAttack &&
|4537|4537| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4535|4535| 		var cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4536|4536| 		if (cmpUnitAI && cmpAttack &&
|4537|4537| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|4538|    |-				return false;
|    |4538|+			return false;
|4539|4539| 	}
|4540|4540| 
|4541|4541| 	// Stop if we're in hold-ground mode and it's too far from the holding point
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4540|4540| 
|4541|4541| 	// Stop if we're in hold-ground mode and it's too far from the holding point
|4542|4542| 	if (this.GetStance().respondHoldGround)
|4543|    |-	{
|    |4543|+	
|4544|4544| 		if (!this.CheckTargetDistanceFromHeldPosition(target, iid, type))
|4545|4545| 			return true;
|4546|    |-	}
|    |4546|+	
|4547|4547| 
|4548|4548| 	// Stop if it's left our vision range, unless we're especially persistent
|4549|4549| 	if (!this.GetStance().respondChaseBeyondVision)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4547|4547| 
|4548|4548| 	// Stop if it's left our vision range, unless we're especially persistent
|4549|4549| 	if (!this.GetStance().respondChaseBeyondVision)
|4550|    |-	{
|    |4550|+	
|4551|4551| 		if (!this.CheckTargetIsInVisionRange(target))
|4552|4552| 			return true;
|4553|    |-	}
|    |4553|+	
|4554|4554| 
|4555|4555| 	// (Note that CCmpUnitMotion will detect if the target is lost in FoW,
|4556|4556| 	// and will continue moving to its last seen position and then stop)
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before 'Engine'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4573|4573| 	// If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker
|4574|4574| 	if (this.isGuardOf)
|4575|4575| 	{
|4576|    |-		let cmpUnitAI =  Engine.QueryInterface(target, IID_UnitAI);
|    |4576|+		let cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
|4577|4577| 		let cmpAttack = Engine.QueryInterface(target, IID_Attack);
|4578|4578| 		if (cmpUnitAI && cmpAttack &&
|4579|4579| 		    cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type)))
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4586|4586| 	return false;
|4587|4587| };
|4588|4588| 
|4589|    |-//// External interface functions ////
|    |4589|+// // External interface functions ////
|4590|4590| 
|4591|4591| UnitAI.prototype.SetFormationController = function(ent)
|4592|4592| {
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4596|4596| 	// of our own formation (or ourself if not in formation)
|4597|4597| 	var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|4598|4598| 	if (cmpObstruction)
|4599|    |-	{
|    |4599|+	
|4600|4600| 		if (ent == INVALID_ENTITY)
|4601|4601| 			cmpObstruction.SetControlGroup(this.entity);
|4602|4602| 		else
|4603|4603| 			cmpObstruction.SetControlGroup(ent);
|4604|    |-	}
|    |4604|+	
|4605|4605| 
|4606|4606| 	// If we were removed from a formation, let the FSM switch back to INDIVIDUAL
|4607|4607| 	if (ent == INVALID_ENTITY)
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4739|4739| 	// if we already had an old guard order, do nothing if the target is the same
|4740|4740| 	// and the order is running, otherwise remove the previous order
|4741|4741| 	if (this.isGuardOf)
|4742|    |-	{
|    |4742|+	
|4743|4743| 		if (this.isGuardOf == target && this.order && this.order.type == "Guard")
|4744|4744| 			return;
|4745|4745| 		else
|4746|4746| 			this.RemoveGuard();
|4747|    |-	}
|    |4747|+	
|4748|4748| 
|4749|4749| 	this.AddOrder("Guard", { "target": target, "force": false }, queued);
|4750|4750| };
|    | [NORMAL] ESLintBear (no-else-return):
|    | Unnecessary 'else' after 'return'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4742|4742| 	{
|4743|4743| 		if (this.isGuardOf == target && this.order && this.order.type == "Guard")
|4744|4744| 			return;
|4745|    |-		else
|4746|    |-			this.RemoveGuard();
|    |4745|+		this.RemoveGuard();
|4747|4746| 	}
|4748|4747| 
|4749|4748| 	this.AddOrder("Guard", { "target": target, "force": false }, queued);
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|4913|4913| 			this.WalkToTarget(target, queued);
|4914|4914| 		return;
|4915|4915| 	}
|4916|    |-	this.AddOrder("Attack", { "target": target, "force": true, "allowCapture": allowCapture}, queued);
|    |4916|+	this.AddOrder("Attack", { "target": target, "force": true, "allowCapture": allowCapture }, queued);
|4917|4917| };
|4918|4918| 
|4919|4919| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5062|5062| 	    this.workOrders.length && this.workOrders[0].type == "Trade")
|5063|5063| 	{
|5064|5064| 		let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
|5065|    |-		if (cmpTrader.HasBothMarkets() && 
|    |5065|+		if (cmpTrader.HasBothMarkets() &&
|5066|5066| 		   (cmpTrader.GetFirstMarket() == target && cmpTrader.GetSecondMarket() == source ||
|5067|5067| 		    cmpTrader.GetFirstMarket() == source && cmpTrader.GetSecondMarket() == target))
|5068|5068| 		{
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5343|5343| 				{
|5344|5344| 					var cmpIdentity = Engine.QueryInterface(targ, IID_Identity);
|5345|5345| 					var targetClasses = this.order.data.targetClasses;
|5346|    |-					if (targetClasses.attack && cmpIdentity
|5347|    |-						&& !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|    |5346|+					if (targetClasses.attack && cmpIdentity &&
|    |5347|+						!MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|5348|5348| 						continue;
|5349|5349| 					if (targetClasses.avoid && cmpIdentity
|5350|5350| 						&& MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5346|5346| 					if (targetClasses.attack && cmpIdentity
|5347|5347| 						&& !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|5348|5348| 						continue;
|5349|    |-					if (targetClasses.avoid && cmpIdentity
|5350|    |-						&& MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|    |5349|+					if (targetClasses.avoid && cmpIdentity &&
|    |5350|+						MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|5351|5351| 						continue;
|5352|5352| 					// Only used by the AIs to prevent some choices of targets
|5353|5353| 					if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ])
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5369|5369| 		{
|5370|5370| 			var cmpIdentity = Engine.QueryInterface(targ, IID_Identity);
|5371|5371| 			var targetClasses = this.order.data.targetClasses;
|5372|    |-			if (cmpIdentity && targetClasses.attack
|5373|    |-				&& !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|    |5372|+			if (cmpIdentity && targetClasses.attack &&
|    |5373|+				!MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|5374|5374| 				continue;
|5375|5375| 			if (cmpIdentity && targetClasses.avoid
|5376|5376| 				&& MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5372|5372| 			if (cmpIdentity && targetClasses.attack
|5373|5373| 				&& !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
|5374|5374| 				continue;
|5375|    |-			if (cmpIdentity && targetClasses.avoid
|5376|    |-				&& MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|    |5375|+			if (cmpIdentity && targetClasses.avoid &&
|    |5376|+				MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
|5377|5377| 				continue;
|5378|5378| 			// Only used by the AIs to prevent some choices of targets
|5379|5379| 			if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ])
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required after '{'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5515|5515| 
|5516|5516| UnitAI.prototype.SetHeldPosition = function(x, z)
|5517|5517| {
|5518|    |-	this.heldPosition = {"x": x, "z": z};
|    |5518|+	this.heldPosition = { "x": x, "z": z};
|5519|5519| };
|5520|5520| 
|5521|5521| UnitAI.prototype.SetHeldPositionOnEntity = function(entity)
|    | [NORMAL] ESLintBear (object-curly-spacing):
|    | A space is required before '}'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5515|5515| 
|5516|5516| UnitAI.prototype.SetHeldPosition = function(x, z)
|5517|5517| {
|5518|    |-	this.heldPosition = {"x": x, "z": z};
|    |5518|+	this.heldPosition = {"x": x, "z": z };
|5519|5519| };
|5520|5520| 
|5521|5521| UnitAI.prototype.SetHeldPositionOnEntity = function(entity)
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5542|5542| 	return false;
|5543|5543| };
|5544|5544| 
|5545|    |-//// Helper functions ////
|    |5545|+// // Helper functions ////
|5546|5546| 
|5547|5547| UnitAI.prototype.CanAttack = function(target)
|5548|5548| {
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5746|5746| 	return cmpPack && cmpPack.IsPacking();
|5747|5747| };
|5748|5748| 
|5749|    |-//// Formation specific functions ////
|    |5749|+// // Formation specific functions ////
|5750|5750| 
|5751|5751| UnitAI.prototype.IsAttackingAsFormation = function()
|5752|5752| {
|    | [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/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5751|5751| UnitAI.prototype.IsAttackingAsFormation = function()
|5752|5752| {
|5753|5753| 	var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|5754|    |-	return cmpAttack && cmpAttack.CanAttackAsFormation()
|5755|    |-		&& this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING";
|    |5754|+	return cmpAttack && cmpAttack.CanAttackAsFormation() &&
|    |5755|+		this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING";
|5756|5756| };
|5757|5757| 
|5758|5758| //// Animal specific functions ////
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/UnitAI.js
|5755|5755| 		&& this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING";
|5756|5756| };
|5757|5757| 
|5758|    |-//// Animal specific functions ////
|    |5758|+// // Animal specific functions ////
|5759|5759| 
|5760|5760| UnitAI.prototype.MoveRandomly = function(distance)
|5761|5761| {

binaries/data/mods/public/simulation/components/UnitAI.js
| 327| »   »   »   return·true;
|    | [NORMAL] ESLintBear (consistent-return):
|    | Method 'Order.WalkToTarget' expected no return value.

binaries/data/mods/public/simulation/components/UnitAI.js
| 885| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
| 907| »   »   »   "enter":·function(msg)·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
| 954| »   »   »   »   »   return·true;
|    | [NORMAL] ESLintBear (consistent-return):
|    | Method 'enter' expected no return value.

binaries/data/mods/public/simulation/components/UnitAI.js
|1017| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1052| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1084| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1305| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1488| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1509| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1539| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1694| »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1745| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|1815| »   »   »   »   »   »   »   return·true;
|    | [NORMAL] ESLintBear (consistent-return):
|    | Method 'enter' expected no return value.

binaries/data/mods/public/simulation/components/UnitAI.js
|1983| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2073| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2242| »   »   »   »   »   »   let·nearby·=·this.FindNearestDropsite(resourceType.generic);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'nearby' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2297| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2415| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2480| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2520| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2724| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|2908| »   »   »   »   "enter":·function()·{
|    | [NORMAL] ESLintBear (consistent-return):
|    | Expected to return a value at the end of method 'enter'.

binaries/data/mods/public/simulation/components/UnitAI.js
|3639| »   var·isWorkType·=·type·=>·type·==·"Gather"·||·type·==·"Trade"·||·type·==·"Repair"·||·type·==·"ReturnResource";
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'type' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4453| »   var·target·=·ents.find(target·=>·this.CanAttack(target));
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'target' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4468| »   var·target·=·ents.find(target·=>
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'target' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4514| »   var·ent·=·ents.find(ent·=>·this.CanHeal(ent));
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'ent' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4537| »   »   ····cmpAttack.GetAttackTypes().some(type·=>·cmpUnitAI.CheckTargetAttackRange(this.isGuardOf,·type)))
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'type' is already declared in the upper scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4993| »   var·lastPos·=·undefined;
|    | [NORMAL] ESLintBear (no-undef-init):
|    | It's not necessary to initialize 'lastPos' to undefined.

binaries/data/mods/public/simulation/components/UnitAI.js
| 354| »   »   ····&&·(this.lastShorelinePosition.z·==·cmpPosition.GetPosition().z))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|1839| »   »   »   »   »   »   var·cmpFormation·=·Engine.QueryInterface(this.formationController,·IID_Formation);
|    | [NORMAL] JSHintBear:
|    | 'cmpFormation' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|1977| »   »   »   »   »   »   &&·this.order.data.target·!=·msg.data.attacker·&&·this.GetBestAttackAgainst(msg.data.attacker,·true)·!=·"Capture")
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|2237| »   »   »   »   »   var·cmpResourceGatherer·=·Engine.QueryInterface(this.entity,·IID_ResourceGatherer);
|    | [NORMAL] JSHintBear:
|    | 'cmpResourceGatherer' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2253| »   »   »   »   »   var·nearby·=·this.FindNearbyResource(function(ent,·type,·template)·{
|    | [NORMAL] JSHintBear:
|    | 'nearby' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2256| »   »   »   »   »   »   »   ||·(type.specific·==·resourceType.specific
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '||'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|2257| »   »   »   »   »   »   »   &&·(type.specific·!=·"meat"·||·resourceTemplate·==·template))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|2277| »   »   »   »   »   var·nearby·=·this.FindNearestDropsite(resourceType.generic);
|    | [NORMAL] JSHintBear:
|    | 'nearby' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2457| »   »   »   »   »   var·cmpResourceGatherer·=·Engine.QueryInterface(this.entity,·IID_ResourceGatherer);
|    | [NORMAL] JSHintBear:
|    | 'cmpResourceGatherer' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2671| »   »   »   »   »   var·cmpResourceDropsite·=·Engine.QueryInterface(msg.data.newentity,·IID_ResourceDropsite);
|    | [NORMAL] JSHintBear:
|    | 'cmpResourceDropsite' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|2757| »   »   »   »   »   if·(this.CanGarrison(target))
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2760| »   »   »   »   »   »   if·(this.CheckGarrisonRange(target))
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2762| »   »   »   »   »   »   »   var·cmpGarrisonHolder·=·Engine.QueryInterface(target,·IID_GarrisonHolder);
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2784| »   »   »   »   »   »   »   »   var·cmpResourceDropsite·=·Engine.QueryInterface(target,·IID_ResourceDropsite);
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2785| »   »   »   »   »   »   »   »   if·(cmpResourceDropsite·&&·this.CanReturnResource(target,·true))
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2800| »   »   »   »   »   »   »   »   »   var·cmpHolderPosition·=·Engine.QueryInterface(target,·IID_Position);
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2801| »   »   »   »   »   »   »   »   »   var·cmpHolderUnitAI·=·Engine.QueryInterface(target,·IID_UnitAI);
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2828| »   »   »   »   »   »   »   if·(!this.CheckTargetRangeExplicit(target,·0,·0)·&&·this.MoveToTarget(target))
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|2828| »   »   »   »   »   »   »   if·(!this.CheckTargetRangeExplicit(target,·0,·0)·&&·this.MoveToTarget(target))
|    | [NORMAL] JSHintBear:
|    | 'target' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|3601| »   »   var·order·=·{·"type":·type,·"data":·data·};
|    | [NORMAL] JSHintBear:
|    | 'order' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|3670| »   for·(var·i·=·0;·i·<·this.orderQueue.length;·++i)
|    | [NORMAL] JSHintBear:
|    | 'i' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|3937| »   let·cmpPosition·=·Engine.QueryInterface(this.entity,·IID_Position)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.

binaries/data/mods/public/simulation/components/UnitAI.js
|4213| »   »   var·parabolicMaxRange·=·0;
|    | [NORMAL] JSHintBear:
|    | 'parabolicMaxRange' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|4217| »   var·guessedMaxRange·=·(range.max·+·parabolicMaxRange)/2;
|    | [NORMAL] JSHintBear:
|    | 'parabolicMaxRange' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4224| »   return·cmpUnitMotion.MoveToTargetRange(target,·range.min,·Math.min(range.max,·parabolicMaxRange));
|    | [NORMAL] JSHintBear:
|    | 'parabolicMaxRange' used out of scope.

binaries/data/mods/public/simulation/components/UnitAI.js
|4302| »   »   »   &&·cmpFormationUnitAI.order.data.target·==·target)
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|4470| »   »   &&·this.CheckTargetDistanceFromHeldPosition(target,·IID_Attack,·this.GetBestAttackAgainst(target,·true))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|4471| »   »   &&·(this.GetStance().respondChaseBeyondVision·||·this.CheckTargetIsInVisionRange(target))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|4993| »   var·lastPos·=·undefined;
|    | [NORMAL] JSHintBear:
|    | It's not necessary to initialize 'lastPos' to 'undefined'.

binaries/data/mods/public/simulation/components/UnitAI.js
|5347| »   »   »   »   »   »   &&·!MatchesClassList(cmpIdentity.GetClassesList(),·targetClasses.attack))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|5350| »   »   »   »   »   »   &&·MatchesClassList(cmpIdentity.GetClassesList(),·targetClasses.avoid))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|5363| »   var·targets·=·this.GetTargetsFromUnit();
|    | [NORMAL] JSHintBear:
|    | 'targets' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5364| »   for·(var·targ·of·targets)
|    | [NORMAL] JSHintBear:
|    | 'targ' is already defined.

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

binaries/data/mods/public/simulation/components/UnitAI.js
|5371| »   »   »   var·targetClasses·=·this.order.data.targetClasses;
|    | [NORMAL] JSHintBear:
|    | 'targetClasses' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5373| »   »   »   »   &&·!MatchesClassList(cmpIdentity.GetClassesList(),·targetClasses.attack))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|5376| »   »   »   »   &&·MatchesClassList(cmpIdentity.GetClassesList(),·targetClasses.avoid))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/simulation/components/UnitAI.js
|5451| »   »   var·cmpVision·=·Engine.QueryInterface(this.entity,·IID_Vision);
|    | [NORMAL] JSHintBear:
|    | 'cmpVision' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5454| »   »   var·range·=·cmpVision.GetRange();
|    | [NORMAL] JSHintBear:
|    | 'range' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5459| »   »   var·cmpRanged·=·Engine.QueryInterface(this.entity,·iid);
|    | [NORMAL] JSHintBear:
|    | 'cmpRanged' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5462| »   »   var·range·=·iid·!==·IID_Attack·?·cmpRanged.GetRange()·:·cmpRanged.GetFullAttackRange();
|    | [NORMAL] JSHintBear:
|    | 'range' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5463| »   »   var·cmpVision·=·Engine.QueryInterface(this.entity,·IID_Vision);
|    | [NORMAL] JSHintBear:
|    | 'cmpVision' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5473| »   »   var·cmpVision·=·Engine.QueryInterface(this.entity,·IID_Vision);
|    | [NORMAL] JSHintBear:
|    | 'cmpVision' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5476| »   »   var·range·=·cmpVision.GetRange();
|    | [NORMAL] JSHintBear:
|    | 'range' is already defined.

binaries/data/mods/public/simulation/components/UnitAI.js
|5755| »   »   &&·this.GetCurrentState()·==·"FORMATIONCONTROLLER.COMBAT.ATTACKING";
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.
Executing section cli...

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